当前位置: 首页> 文旅> 美景 > FFmpeg编解码的那些事(2)

FFmpeg编解码的那些事(2)

时间:2025/7/11 7:40:09来源:https://blog.csdn.net/fengzhongye51460/article/details/139283519 浏览次数:0次

软解码

1.构建输入AVFormatContext

    AVFormatContext* avFormatContext = avformat_alloc_context();int res = avformat_open_input(&avFormatContext,filename.toUtf8().data(), NULL, NULL);//打开文件if (res < 0) {qCritical()<<__FUNCTION__<<__LINE__<<"error "<<res<<"in avformat_open_input";return res;}

2.查找视频信息流

    res = avformat_find_stream_info(avFormatContext, nullptr);//取出流信息if (res < 0){return res;}//查找视频流和音频流av_dump_format(avFormatContext, 0,filename.toUtf8().data(), 0);//列出输入文件的相关流信息for (unsigned int i = 0; i < avFormatContext->nb_streams; i++){if (avFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){if(video_index==-1){video_index = i;}}}m_width   = avFormatContext->streams[video_index]->codec->width;m_height  = avFormatContext->streams[video_index]->codec->height;

3.初始化软解码

    AVCodecContext *avCodecContext = avFormatContext->streams[video_index]->codec;AVCodec* m_codec = avcodec_find_decoder(avCodecContext->codec_id);if (avcodec_open2(avCodecContext, m_codec, NULL) < 0){return false;}

4.初始化SwsContext图像转换上下文

    img_convert_ctx = sws_getContext(m_width,m_height,avCodecContext->pix_fmt,m_width,m_height,AV_PIX_FMT_BGRA,SWS_BICUBIC,NULL, NULL, NULL);

5.循环读取数据

    while (true){int ret = av_read_frame(avFormatContext, avPacket);if (ret < 0){qDebug()<< "read end";break;}else if (avPacket->stream_index == video_index){decode_to_photo(avPacket);}av_packet_unref(avPacket);}void decode_to_photo(const AVPacket *avPacket)
{int ret = avcodec_send_packet(avCodecContext, avPacket);if (ret < 0) {char error[1024];av_strerror(ret, error, 1024);qDebug() << "发送解码失败:" << error;}while (true){ret = avcodec_receive_frame(avCodecContext, avFrame);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){//qDebug() << "avcodec_receive_frame end:" << ret;break;}else if (ret < 0){//qDebug()<< "获取解码数据失败"<<ret;return;}else{QImage pixLogo2;int m_rotat = getRotateAngle(avFormatContext->streams[video_index]);if(dec_st == AV_SOFTWARE_DECODER){sws_scale(img_convert_ctx,(const unsigned char* const*)avFrame->data,avFrame->linesize, 0,avFrame->height,bgrFrame->data,bgrFrame->linesize);QImage pixLogo(bgrFrame->data[0],bgrFrame->width,bgrFrame->height,bgrFrame->width * 4, QImage::Format_ARGB32);QMatrix matrix;matrix.rotate(m_rotat);pixLogo2 = pixLogo.transformed(matrix,Qt::FastTransformation);/*这里可以进行必要的图片处理操作*/}curcount++;av_frame_unref(sw_frame);av_frame_unref(avFrame);}}
}

tips:

根据pts来计算一桢在整个视频中的时间位置

timestamp(秒) = pts * av_q2d(st->time_base) 
timestamp(毫秒) = pts * av_q2d(st->time_base) * 1000 

计算视频长度的方法

time(秒) = st->duration * av_q2d(st->time_base)

关键字:FFmpeg编解码的那些事(2)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: