参考博客:https://blog.csdn.net/leixiaohua1020/article/details/12679719


int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,int *got_picture_ptr,const AVPacket *avpkt)
{//调用compat_decode函数return compat_decode(avctx, picture, got_picture_ptr, avpkt);
}//===============================================static int compat_decode(AVCodecContext *avctx, AVFrame *frame,int *got_frame, const AVPacket *pkt)
{AVCodecInternal *avci = avctx->internal;int ret = 0;av_assert0(avci->compat_decode_consumed == 0);if (avci->draining_done && pkt && pkt->size != 0) {av_log(avctx, AV_LOG_WARNING, "Got unexpected packet after EOF\n");avcodec_flush_buffers(avctx);}*got_frame = 0;if (avci->compat_decode_partial_size > 0 &&avci->compat_decode_partial_size != pkt->size) {av_log(avctx, AV_LOG_ERROR,"Got unexpected packet size after a partial decode\n");ret = AVERROR(EINVAL);goto finish;}//调用函数 avcodec_send_packet函数if (!avci->compat_decode_partial_size) {ret = avcodec_send_packet(avctx, pkt);if (ret == AVERROR_EOF)ret = 0;else if (ret == AVERROR(EAGAIN)) {/* we fully drain all the output in each decode call, so this should not* ever happen */ret = AVERROR_BUG;goto finish;} else if (ret < 0)goto finish;}while (ret >= 0) {//循环调用avcodec_receive_frame函数ret = avcodec_receive_frame(avctx, frame);if (ret < 0) {if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)ret = 0;goto finish;}if (frame != avci->compat_decode_frame) {if (!avctx->refcounted_frames) {ret = unrefcount_frame(avci, frame);if (ret < 0)goto finish;}*got_frame = 1;frame = avci->compat_decode_frame;} else {if (!avci->compat_decode_warned) {av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_decode_* ""API cannot return all the frames for this decoder. ""Some frames will be dropped. Update your code to the ""new decoding API to fix this.\n");avci->compat_decode_warned = 1;}}if (avci->draining || (!avctx->codec->bsfs && avci->compat_decode_consumed < pkt->size))break;}finish:if (ret == 0) {/* if there are any bsfs then assume full packet is always consumed */if (avctx->codec->bsfs)ret = pkt->size;elseret = FFMIN(avci->compat_decode_consumed, pkt->size);}avci->compat_decode_consumed = 0;avci->compat_decode_partial_size = (ret >= 0) ? pkt->size - ret : 0;return ret;
}
//===========================================================int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
{AVCodecInternal *avci = avctx->internal;int ret;if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))return AVERROR(EINVAL);if (avctx->internal->draining)return AVERROR_EOF;if (avpkt && !avpkt->size && avpkt->data)return AVERROR(EINVAL);av_packet_unref(avci->buffer_pkt);if (avpkt && (avpkt->data || avpkt->side_data_elems)) {ret = av_packet_ref(avci->buffer_pkt, avpkt);if (ret < 0)return ret;}ret = av_bsf_send_packet(avci->bsf, avci->buffer_pkt);if (ret < 0) {av_packet_unref(avci->buffer_pkt);return ret;}if (!avci->buffer_frame->buf[0]) {ret = decode_receive_frame_internal(avctx, avci->buffer_frame);if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)return ret;}return 0;
}//============================================================int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
{AVCodecInternal *avci = avctx->internal;int ret, changed;av_frame_unref(frame);if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))return AVERROR(EINVAL);if (avci->buffer_frame->buf[0]) {av_frame_move_ref(frame, avci->buffer_frame);} else {ret = decode_receive_frame_internal(avctx, frame);if (ret < 0)return ret;}//检查视频类型if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {ret = apply_cropping(avctx, frame);if (ret < 0) {av_frame_unref(frame);return ret;}}//帧数++avctx->frame_number++;if (avctx->flags & AV_CODEC_FLAG_DROPCHANGED) {//如果number=1if (avctx->frame_number == 1) {avci->initial_format = frame->format;switch(avctx->codec_type) {//编码类型为视频,初始化宽和高case AVMEDIA_TYPE_VIDEO:avci->initial_width  = frame->width;avci->initial_height = frame->height;break;//编码类型为音频,初始化采样率、声道、 "声道布局??"case AVMEDIA_TYPE_AUDIO:avci->initial_sample_rate = frame->sample_rate ? frame->sample_rate :avctx->sample_rate;avci->initial_channels       = frame->channels;avci->initial_channel_layout = frame->channel_layout;break;}}//如果number > 1,则if (avctx->frame_number > 1) {//初始化格式changed = avci->initial_format != frame->format;switch(avctx->codec_type) {case AVMEDIA_TYPE_VIDEO://视频类型changed |= avci->initial_width  != frame->width ||avci->initial_height != frame->height;break;case AVMEDIA_TYPE_AUDIO://音频类型changed |= avci->initial_sample_rate    != frame->sample_rate ||avci->initial_sample_rate    != avctx->sample_rate ||avci->initial_channels       != frame->channels ||avci->initial_channel_layout != frame->channel_layout;break;}if (changed) {//变化?丢弃avci->changed_frames_dropped++;av_log(avctx, AV_LOG_INFO, "dropped changed frame #%d pts %"PRId64" drop count: %d \n",avctx->frame_number, frame->pts,avci->changed_frames_dropped);av_frame_unref(frame);return AVERROR_INPUT_CHANGED;}}}return 0;
}//==============================================================static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
{AVCodecInternal *avci = avctx->internal;int ret;av_assert0(!frame->buf[0]);if (avctx->codec->receive_frame) {ret = avctx->codec->receive_frame(avctx, frame);if (ret != AVERROR(EAGAIN))av_packet_unref(avci->last_pkt_props);} elseret = decode_simple_receive_frame(avctx, frame);if (ret == AVERROR_EOF)avci->draining_done = 1;if (!ret) {frame->best_effort_timestamp = guess_correct_pts(avctx,frame->pts,frame->pkt_dts);/* the only case where decode data is not set should be decoders* that do not call ff_get_buffer() */av_assert0((frame->private_ref && frame->private_ref->size == sizeof(FrameDecodeData)) ||!(avctx->codec->capabilities & AV_CODEC_CAP_DR1));if (frame->private_ref) {FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data;if (fdd->post_process) {ret = fdd->post_process(avctx, frame);if (ret < 0) {av_frame_unref(frame);return ret;}}}}/* free the per-frame decode data */av_buffer_unref(&frame->private_ref);return ret;
}

ffmpeg 源代码简单学习 : avcodec_decode_video2()相关推荐

  1. FFmpeg源代码简单学习:avformat_find_stream_info()

    参考博客:https://blog.csdn.net/leixiaohua1020/article/details/44084321 int avformat_find_stream_info(AVF ...

  2. ffmpeg 源代码简单分析 : avcodec_decode_video2()

    2019独角兽企业重金招聘Python工程师标准>>> 此前写了好几篇ffmpeg源代码分析文章,列表如下: 图解FFMPEG打开媒体的函数avformat_open_input f ...

  3. FFmpeg源代码简单分析:libavdevice的gdigrab

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  4. FFmpeg源代码简单分析:libavdevice的avdevice_register_all()

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  5. FFmpeg源代码简单分析:configure

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  6. FFmpeg源代码简单分析:makefile

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  7. FFmpeg源代码简单分析:libswscale的sws_getContext()

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  8. FFmpeg源代码简单分析:结构体成员管理系统-AVOption

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  9. FFmpeg源代码简单分析:结构体成员管理系统-AVClass

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

最新文章

  1. poj3352(强连通分量)
  2. Python 制作微信全家福,你就是朋友圈最亮的仔!
  3. CountDownLatch的理解和使用
  4. Vue解析--如何应对面试官提问
  5. HTML 页面源代码布局介绍
  6. nodjs npm 报错:Segmentation fault: 11
  7. 网站开发综合技术 HTML
  8. 数据挖掘应用案例:RFM模型分析与客户细分(转)
  9. OpenGL基础40:Uniform缓冲
  10. 空降的主管要如何生存?
  11. 计算机科学创新实验刘琦,刘琦----中国科学院微电子研究所
  12. 兑吧开发规范《源Java手册》
  13. android 字体加粗
  14. Cors跨域(二):实现跨域Cookie共享的三要素
  15. iOS 图标和文字自定按钮
  16. 电路板级的EMC设计 (2)元件的选择和电路设计技术
  17. 随机过程基础3--宽平稳随机过程的谱分析
  18. 微信链接修改图片_微信链接修改图标
  19. 使用golang发送邮件,报错“x509: certificate signed by unknown authority”
  20. 【全网力荐】堪称最易学的Python基础入门教程

热门文章

  1. less或scss中@mixin的用法
  2. Python中的if判断语句
  3. java音乐_java实现简单音乐播放器
  4. 36个Excel技巧,50个快捷键组合,拯救你的工作效率!
  5. django Did you forget to register or load this tag?
  6. 93年小伙逆境中披荆斩棘,转型测开,从年薪15w,一下晋升年薪30w
  7. 【那些年,我们一起追的女孩】第十七章
  8. Nacos+Node基础教程
  9. SAP中GR/IR余额清单功能MB5S
  10. 57BYGH420步进电机单片机程序