|
- #include "FfmpegDecodeOld.h"
-
- ConstBuffer* FfmpegDecodeOld::m_pConstBuffer =
- new ConstBuffer(VideoBufferLength, false, false, VideoPacketLength);
-
- FfmpegDecodeOld::FfmpegDecodeOld(QObject* parent)
- : QThread(parent)
- , m_bNeedWork(false)
- , m_sBufferSize(VideoPacketLength)
- , m_pBuffer(nullptr)
- , m_pAVIOContext(nullptr)
- , m_pAVInputFormat(nullptr)
- , m_pAVFormatContext(nullptr)
- , m_iId(-1)
- , m_pAVPacket(nullptr)
- , m_pAVCodec(nullptr)
- , m_pAVCodecContext(nullptr)
- , m_pAVFrameSrc(nullptr)
- , m_pAVFrameDes(nullptr)
- , m_pAVCodecParameters(nullptr)
- , m_pSwsContext(nullptr)
- {}
-
- FfmpegDecodeOld::~FfmpegDecodeOld()
- {}
-
- int FfmpegDecodeOld::read_data(void* opaque, uint8_t* buf, int buf_size)
- {
- FfmpegDecodeOld* pFfmpegDecodeOld = (FfmpegDecodeOld*)opaque;
- unsigned short usRecvSize = pFfmpegDecodeOld->getConstBuffer()->read(buf, buf_size);
- return usRecvSize;
- }
-
- void FfmpegDecodeOld::init()
- {
- // (1)注册所有编解码器(codecs)、解析器(parsers)以及码流过滤器(bitstream filters)
- avcodec_register_all();
- // (2)申请内存
- m_pBuffer = (uint8_t*)av_malloc(sizeof(uint8_t) * m_sBufferSize);
- // (3)申请一个AVIOContext
- m_pAVIOContext = avio_alloc_context(m_pBuffer, m_sBufferSize, 0, NULL, read_data, NULL, NULL);
- // (4)探测网络流格式
- if (av_probe_input_buffer(m_pAVIOContext, &m_pAVInputFormat, "", NULL, 0, 0) < 0) {
- return;
- }
- // (5)申请一个AVFormatContext
- m_pAVFormatContext = avformat_alloc_context();
- // (6)将申请到的AVIOContext句柄挂载至之前申请的m_pAVFormatContext中
- m_pAVFormatContext->pb = m_pAVIOContext;
- // (7)打开输入的AVFormatContext
- if (avformat_open_input(&m_pAVFormatContext, "", m_pAVInputFormat, NULL) < 0) {
- return;
- }
- // (8)检索流信息
- if (avformat_find_stream_info(m_pAVFormatContext, NULL) < 0) {
- return;
- }
- // (9)打印格式信息
- av_dump_format(m_pAVFormatContext, 0, "", 0);
- // (10)判断是否有视频编码解码器
- for (int i = 0; i < m_pAVFormatContext->nb_streams; ++i) {
- if (m_pAVFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
- m_iId = i;
- break;
- }
- }
- if (m_iId == -1) {
- avformat_close_input(&m_pAVFormatContext); // 关闭流信息
- return;
- }
- // (11)找到流的解码器
- m_pAVCodec = avcodec_find_decoder(m_pAVFormatContext->streams[m_iId]->codecpar->codec_id);
- if (!m_pAVCodec) {
- return; // 未找到解码器
- }
- // (12)分配视频编解码器上下文
- m_pAVCodecContext = avcodec_alloc_context3(m_pAVCodec);
- if (!m_pAVCodecContext) { // 无法分配视频编解码器上下文
- return;
- }
- // (13)将编解码器参数从输入流复制到输出编解码器上下文
- m_pAVCodecParameters = m_pAVFormatContext->streams[m_iId]->codecpar;
- if (avcodec_parameters_to_context(m_pAVCodecContext,
- m_pAVFormatContext->streams[m_iId]->codecpar)
- < 0) {
- return;
- }
- // (14)打开解码器
- if (avcodec_open2(m_pAVCodecContext, m_pAVCodec, NULL) < 0) {
- return;
- }
- // (15)申请视频帧存储空间
- m_pAVFrameSrc = av_frame_alloc();
- if (!m_pAVFrameSrc) { // 申请视频帧存储空间失败
- return;
- }
- // (16)申请分配压缩数据包空间
- av_init_packet(m_pAVPacket);
- if (!m_pAVPacket) { // 申请分配压缩数据包空间失败
- return;
- }
- // (19)初始化图像数据存储空间
- m_pAVFrameDes = av_frame_alloc();
- if (!m_pAVFrameDes) {
- return;
- }
- av_image_alloc(m_pAVFrameDes->data, m_pAVFrameDes->linesize, m_pAVCodecParameters->width,
- m_pAVCodecParameters->height, AV_PIX_FMT_RGB24, 1);
- // (20)初始化图像格式转换
- m_pSwsContext = sws_getContext(m_pAVCodecParameters->width, m_pAVCodecParameters->height,
- (AVPixelFormat)m_pAVCodecParameters->format,
- m_pAVCodecParameters->width, m_pAVCodecParameters->height,
- AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
- }
-
- void FfmpegDecodeOld::run()
- {
- int get_pict = 0;
- int ret = -1;
- // (17)获取一个AVPacket数据
- while (0 <= av_read_frame(m_pAVFormatContext, m_pAVPacket)) {
- if (m_pAVPacket->stream_index == m_iId) {
- // (18)对AVPacket数据解码并将数据保存到m_pAVFrame中
- if (0 <= avcodec_decode_video2(m_pAVCodecContext, m_pAVFrameSrc, &get_pict,
- m_pAVPacket)) {
- if (get_pict) {
- // (21)进行图像格式转换
- sws_scale(m_pSwsContext, m_pAVFrameSrc->data, m_pAVFrameSrc->linesize, 0,
- m_pAVFrameSrc->height, m_pAVFrameDes->data, m_pAVFrameDes->linesize);
- // (22)对转换后的数据进行处理
- }
- }
- }
- }
- }
|