Слияние кода завершено, страница обновится автоматически
#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;
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )