代码拉取完成,页面将自动刷新
#include "zffvideo.h"
#include "zffmpeg.h"
#include "zffaudio.h"
#include <QDebug>
QAtomicPointer<ZFFvideo> ZFFvideo::_instance = 0;
QMutex ZFFvideo::_mutex;
ZFFvideo::ZFFvideo()
{}
ZFFvideo * ZFFvideo::getInstance()
{
// 使用双重检测。
/*! testAndSetOrders操作保证在原子操作前和后的的内存访问
* 不会被重新排序。
*/
if (_instance.testAndSetOrdered(0, 0)) // 第一次检测
{
QMutexLocker locker(&_mutex); // 加互斥锁。
_instance.testAndSetOrdered(0, new ZFFvideo); // 第二次检测。
}
return _instance;
}
int ZFFvideo::ToRGB(const AVFrame *yuv, char *out, int outwidth, int outheight)
{
AVFormatContext *ic = ZFFmpeg::getInstance()->GetFormatCtx();
int videoStream = ZFFmpeg::getInstance()->GetVideoStream();
// QMutexLocker locker(&_mutex);//加互斥锁
if (!ic) // 未打开视频文件
{
return -1;
}
AVCodecContext *videoCtx = ic->streams[videoStream]->codec;
SwsContext *cCtx = NULL;
cCtx = sws_getCachedContext(cCtx, videoCtx->width, // 初始化一个SwsContext
videoCtx->height,
videoCtx->pix_fmt, // 输入像素格式
outwidth, outheight,
AV_PIX_FMT_BGRA, // 输出像素格式
SWS_BICUBIC, // 转码的算法
NULL, NULL, NULL);
if (!cCtx)
{
qDebug("sws_getCachedContext failed!");
return -1;
}
uint8_t *data[AV_NUM_DATA_POINTERS] = { 0 };
data[0] = (uint8_t *)out;
int linesize[AV_NUM_DATA_POINTERS] = { 0 };
linesize[0] = outwidth * 4; // 一行的宽度,32位4个字节
int h = sws_scale(cCtx, yuv->data, // 当前处理区域的每个通道数据指针
yuv->linesize, // 每个通道行字节数
0, videoCtx->height, // 原视频帧的高度
data, // 输出的每个通道数据指针
linesize // 每个通道行字节数
); // 开始转码
return 0;
}
void ZFFvideo::terminate() {
_canBeRun = false;
}
void ZFFvideo::start(Priority pro) {
_canBeRun = true;
QThread::start(pro);
qDebug("ZFFvideo::start");
}
void ZFFvideo::run() {
while (_canBeRun) {
// qDebug("%d",ZFFmpeg::getInstance()->videoList.size());
if (ZFFmpeg::getInstance()->videoList.list.size() > 0) {
AVPacket pkt;
{
QMutexLocker locker(&ZFFmpeg::getInstance()->videoList._mutex);
pkt = ZFFmpeg::getInstance()->videoList.list.takeFirst();
curTimestampSec = ZFFmpeg::getInstance()->GetPts(&pkt);
// qDebug("ZFFvideo::run play %f ms", curTimestampSec);
}
while (_canBeRun &&
curTimestampSec > ZFFaudio::getInstance()->GetCurTimeSec()) {
msleep(1);
}
AVFrame *videoFrame = ZFFmpeg::getInstance()->Decode(&pkt); // 解码
av_packet_unref(&pkt); // 释放pkt包
RGBList.append(videoFrame);
} else {
msleep(1);
}
}
}
void ZFFvideo::stop() {
_canBeRun = false;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。