|
@@ -217,20 +217,6 @@ void DecodeVedio::wakeUpCondQueueNoEmpty()
|
|
*/
|
|
*/
|
|
QImage* DecodeVedio::getOneImage()
|
|
QImage* DecodeVedio::getOneImage()
|
|
{
|
|
{
|
|
- // if(m_queueImage.count() == 0)
|
|
|
|
- // {
|
|
|
|
- // // SPDLOG_TRACE("队列为空...");
|
|
|
|
- // return nullptr;
|
|
|
|
- // }
|
|
|
|
- // // SPDLOG_TRACE("******************************** 队列中图片个数:{} ",m_queueImage.count());
|
|
|
|
- // m_mutexQueue.lock();
|
|
|
|
- // auto image = m_queueImage.dequeue();
|
|
|
|
- // m_mutexQueue.unlock();
|
|
|
|
- // /* 唤醒可能阻塞住的解码线程,队列中的图片低于20之后再唤醒 */
|
|
|
|
- // if(m_queueImage.count() < 20)
|
|
|
|
- // {
|
|
|
|
- // m_condQueueNoFull.wakeAll();
|
|
|
|
- // }
|
|
|
|
QImage* image = m_ringQueue.deQueueBlock();
|
|
QImage* image = m_ringQueue.deQueueBlock();
|
|
return image;
|
|
return image;
|
|
}
|
|
}
|
|
@@ -479,7 +465,7 @@ void DecodeVedio::openVedio(const QString& fileName)
|
|
|
|
|
|
/************ 初始化数据包 ************/
|
|
/************ 初始化数据包 ************/
|
|
m_packet = av_packet_alloc();
|
|
m_packet = av_packet_alloc();
|
|
- // av_new_packet(m_packet, m_pCodecContext->width * m_pCodecContext->height);
|
|
|
|
|
|
+ av_new_packet(m_packet, m_pCodecContext->width * m_pCodecContext->height);
|
|
|
|
|
|
/* 创建两个pFrame,一个存放原始数据,一个存放转换后的RGB数据 */
|
|
/* 创建两个pFrame,一个存放原始数据,一个存放转换后的RGB数据 */
|
|
m_pFrameSRC = av_frame_alloc();
|
|
m_pFrameSRC = av_frame_alloc();
|
|
@@ -514,9 +500,6 @@ void DecodeVedio::openVedio(const QString& fileName)
|
|
int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGBA, m_pCodecContext->width, m_pCodecContext->height, 1);
|
|
int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGBA, m_pCodecContext->width, m_pCodecContext->height, 1);
|
|
/* 这里多分配了一些空间,防止某些视频图像在使用sws_scale()拷贝后超出数组长度 */
|
|
/* 这里多分配了一些空间,防止某些视频图像在使用sws_scale()拷贝后超出数组长度 */
|
|
m_buffer = (uint8_t *)av_malloc(numBytes + 1000);
|
|
m_buffer = (uint8_t *)av_malloc(numBytes + 1000);
|
|
-
|
|
|
|
- /* 这个函数的实际作用是将buffer设置给pFrameRGB作为原始数据的内存区域 */
|
|
|
|
- av_image_fill_arrays(m_pFrameRGB->data, m_pFrameRGB->linesize, m_buffer, AV_PIX_FMT_RGBA, m_pCodecContext->width, m_pCodecContext->height, 1);
|
|
|
|
|
|
|
|
m_initFFmpeg = true;
|
|
m_initFFmpeg = true;
|
|
SPDLOG_INFO("FFMPEG初始化完成!");
|
|
SPDLOG_INFO("FFMPEG初始化完成!");
|
|
@@ -587,7 +570,7 @@ void DecodeVedio::decodeUsingCPU()
|
|
}
|
|
}
|
|
|
|
|
|
SPDLOG_DEBUG("读取到数据包packet,pts:{}",m_packet->pts);
|
|
SPDLOG_DEBUG("读取到数据包packet,pts:{}",m_packet->pts);
|
|
- /* 解码packet包的内容 */
|
|
|
|
|
|
+ /* 解码packet包的内容,一个packet包内可能包含好多帧视频 */
|
|
while(m_isRunning)
|
|
while(m_isRunning)
|
|
{
|
|
{
|
|
/* 读取出解码器返回的帧 avcodec_receive_frame */
|
|
/* 读取出解码器返回的帧 avcodec_receive_frame */
|
|
@@ -600,8 +583,10 @@ void DecodeVedio::decodeUsingCPU()
|
|
}
|
|
}
|
|
else if (ret == AVERROR(EAGAIN))
|
|
else if (ret == AVERROR(EAGAIN))
|
|
{
|
|
{
|
|
- /* packet无法解码成一帧,需要更多的输入包 */
|
|
|
|
|
|
+ /* packet中的内容无法解码成一帧,需要更多的输入包,可能已经取出了几帧,也肯能就不够一帧
|
|
|
|
+ * 这时候就需要往解码器送数据包了 */
|
|
SPDLOG_WARN("packet无法解码成一帧,需要更多的输入包");
|
|
SPDLOG_WARN("packet无法解码成一帧,需要更多的输入包");
|
|
|
|
+ av_frame_unref(m_pFrameSRC);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
else if(ret < 0)
|
|
else if(ret < 0)
|
|
@@ -639,19 +624,25 @@ void DecodeVedio::decodeUsingCPU()
|
|
SPDLOG_INFO("创建SwsContext成功...");
|
|
SPDLOG_INFO("创建SwsContext成功...");
|
|
}
|
|
}
|
|
/* 转换成RGBA格式 */
|
|
/* 转换成RGBA格式 */
|
|
|
|
+ uint8_t* data[1] = { m_buffer };
|
|
|
|
+ int lines[4];
|
|
|
|
+ /* 使用像素格式pix_fmt和宽度填充图像的平面线条的大小(一行大小?) */
|
|
|
|
+ av_image_fill_linesizes(lines, AV_PIX_FMT_RGBA, m_pFrameSRC->width);
|
|
|
|
+
|
|
sws_scale( m_sws_ctx, /* 缩放的上下文 */
|
|
sws_scale( m_sws_ctx, /* 缩放的上下文 */
|
|
- m_pFrameSRC->data, /* 源图像数组 */
|
|
|
|
- m_pFrameSRC->linesize, /* 包含源图像每个平面步幅的数组 */
|
|
|
|
|
|
+ m_pFrameSRC->data, /* 源图像数组 */
|
|
|
|
+ m_pFrameSRC->linesize, /* 包含源图像每个平面步幅的数组 */
|
|
0, /* 开始位置 */
|
|
0, /* 开始位置 */
|
|
- m_pFrameSRC->height, /* 行数 */
|
|
|
|
- m_pFrameRGB->data, /* 目标图像数组 */
|
|
|
|
- m_pFrameRGB->linesize); /* 目标图像行数 */
|
|
|
|
- if(m_pFrameRGB->data[0] != nullptr)
|
|
|
|
|
|
+ m_pFrameSRC->height, /* 行数 */
|
|
|
|
+ data, /* 目标图像数组 */
|
|
|
|
+ lines); /* 目标图像行数 */
|
|
|
|
+ if(m_buffer != nullptr)
|
|
{
|
|
{
|
|
/* 将数据拷贝到QImage中 */
|
|
/* 将数据拷贝到QImage中 */
|
|
auto image = new QImage(m_pFrameRGB->data[0], m_width, m_height, QImage::Format_RGBA8888);
|
|
auto image = new QImage(m_pFrameRGB->data[0], m_width, m_height, QImage::Format_RGBA8888);
|
|
m_ringQueue.enQueueBlock(image);
|
|
m_ringQueue.enQueueBlock(image);
|
|
av_frame_unref(m_pFrameRGB);
|
|
av_frame_unref(m_pFrameRGB);
|
|
|
|
+ SPDLOG_DEBUG("一帧视频入队");
|
|
}
|
|
}
|
|
av_frame_unref(m_pFrameSRC);
|
|
av_frame_unref(m_pFrameSRC);
|
|
}
|
|
}
|