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:
parent
904495d2bf
commit
8bfbae1b47
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue
Block a user