1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

refactor(video): use a new ToxAVFrame structure instead of vpx_image

Instead of misusing an existing structure from another library, defines
a new simpler structure that reflects the capabilities of the ToxAV
transport mechanism.
This commit is contained in:
initramfs 2016-04-25 11:16:04 -04:00 committed by initramfs
parent 904495d2bf
commit 8bfbae1b47
No known key found for this signature in database
GPG Key ID: 78B8BDF87E9EF0AF
3 changed files with 29 additions and 51 deletions

View File

@ -361,26 +361,20 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe)
}
// This frame shares vframe's buffers, we don't call vpx_img_free but just delete it
vpx_image* frame = vframe->toVpxImage();
ToxAVFrame frame = vframe->toToxAVFrame();
if(!frame)
if(frame.width == 0 || frame.height == 0)
{
return;
}
if(frame->fmt == VPX_IMG_FMT_NONE)
{
qWarning() << "Invalid frame";
vpx_img_free(frame);
return;
}
// TOXAV_ERR_SEND_FRAME_SYNC means toxav failed to lock, retry 5 times in this case
// We don't want to be dropping iframes because of some lock held by toxav_iterate
TOXAV_ERR_SEND_FRAME err;
int retries = 0;
do {
if (!toxav_video_send_frame(toxav, callId, frame->d_w, frame->d_h,
frame->planes[0], frame->planes[1], frame->planes[2], &err))
if (!toxav_video_send_frame(toxav, callId, frame.width, frame.height,
frame.y, frame.u, frame.v, &err))
{
if (err == TOXAV_ERR_SEND_FRAME_SYNC)
{
@ -395,8 +389,6 @@ void CoreAV::sendCallVideo(uint32_t callId, std::shared_ptr<VideoFrame> vframe)
} while (err == TOXAV_ERR_SEND_FRAME_SYNC && retries < 5);
if (err == TOXAV_ERR_SEND_FRAME_SYNC)
qDebug() << "toxav_video_send_frame error: Lock busy, dropping frame";
vpx_img_free(frame);
}
void CoreAV::micMuteToggle(uint32_t callId)

View File

@ -162,7 +162,7 @@ QImage VideoFrame::toQImage(QSize frameSize)
return ret;
}
vpx_image* VideoFrame::toVpxImage(QSize frameSize)
ToxAVFrame VideoFrame::toToxAVFrame(QSize frameSize)
{
frameLock.lockForRead();
@ -170,7 +170,7 @@ vpx_image* VideoFrame::toVpxImage(QSize frameSize)
if(frameBuffer.size() == 0)
{
frameLock.unlock();
return nullptr;
return {0, 0, nullptr, nullptr, nullptr};
}
if(frameSize.width() == 0 && frameSize.height() == 0)
@ -182,20 +182,7 @@ vpx_image* VideoFrame::toVpxImage(QSize frameSize)
if(frame)
{
vpx_image* ret = new vpx_image {};
memset(ret, 0, sizeof(vpx_image));
ret->w = ret->d_w = frameSize.width();
ret->h = ret->d_h = frameSize.height();
ret->fmt = VPX_IMG_FMT_I420;
ret->planes[0] = frame->data[0];
ret->planes[1] = frame->data[1];
ret->planes[2] = frame->data[2];
ret->planes[3] = nullptr;
ret->stride[0] = frame->linesize[0];
ret->stride[1] = frame->linesize[1];
ret->stride[2] = frame->linesize[2];
ret->stride[3] = frame->linesize[3];
ToxAVFrame ret {frameSize.width(), frameSize.height(), frame->data[0], frame->data[1], frame->data[2]};
frameLock.unlock();
return ret;
@ -216,20 +203,7 @@ vpx_image* VideoFrame::toVpxImage(QSize frameSize)
storeAVFrame(frame, frameSize, static_cast<int>(AV_PIX_FMT_YUV420P));
vpx_image* ret = new vpx_image {};
memset(ret, 0, sizeof(vpx_image));
ret->w = ret->d_w = frameSize.width();
ret->h = ret->d_h = frameSize.height();
ret->fmt = VPX_IMG_FMT_I420;
ret->planes[0] = frame->data[0];
ret->planes[1] = frame->data[1];
ret->planes[2] = frame->data[2];
ret->planes[3] = nullptr;
ret->stride[0] = frame->linesize[0];
ret->stride[1] = frame->linesize[1];
ret->stride[2] = frame->linesize[2];
ret->stride[3] = frame->linesize[3];
ToxAVFrame ret {frameSize.width(), frameSize.height(), frame->data[0], frame->data[1], frame->data[2]};
frameLock.unlock();
return ret;

View File

@ -29,11 +29,24 @@ extern "C"{
#include <libavcodec/avcodec.h>
}
#include <vpx/vpx_image.h>
#include <functional>
#include <memory>
#include <unordered_map>
/**
* @brief A simple structure to represent a ToxAV frame.
*/
struct ToxAVFrame
{
public:
const std::uint16_t width;
const std::uint16_t height;
const uint8_t* y;
const uint8_t* u;
const uint8_t* v;
};
/**
* @brief An ownernship and management class for AVFrames.
*
@ -145,18 +158,17 @@ public:
QImage toQImage(QSize frameSize = {0, 0});
/**
* @brief Converts this VideoFrame to a vpx_image that shares this VideoFrame's buffer.
* @brief Converts this VideoFrame to a ToxAVFrame that shares this VideoFrame's buffer.
*
* Given that libvpx does not provide a way to create vpx_images that uses external buffers,
* the vpx_image constructed by this function is done in a non-compliant way, requiring the
* use of the C++ delete keyword to properly deallocate memory associated with this image.
* The given ToxAVFrame will be frame aligned under a pixel format of planar YUV with a chroma
* subsampling format of 4:2:0 (i.e. AV_PIX_FMT_YUV420P).
*
* @param frameSize the given frame size of vpx_image to generate. If frame size is 0, defaults
* @param frameSize the given frame size of ToxAVFrame to generate. If frame size is 0, defaults
* to source frame size.
* @return a vpx_image that represents this VideoFrame, sharing it's buffers or nullptr if this
* VideoFrame is no longer valid.
* @return a ToxAVFrame structure that represents this VideoFrame, sharing it's buffers or an
* empty structure if this VideoFrame is no longer valid.
*/
vpx_image* toVpxImage(QSize frameSize = {0, 0});
ToxAVFrame toToxAVFrame(QSize frameSize = {0, 0});
/**
* @brief Data alignment parameter used to populate AVFrame buffers.