1)函数声明
/**
* 根据AVCodec结构体,初始化AVCodecContext编码上下文。需要调用avcodec_alloc_context3初始化AVcodecContext.
*
* The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
* avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
* retrieving a codec.
*
* @注意函数并非线程安全
*
* @注意必须在调用解码函数例如avcodec_receive_frame之前,调用该函数进行初始化
*
* @代码例子
* avcodec_register_all();
* av_dict_set(&opts, "b", "2.5M", 0);
* codec = avcodec_find_decoder(AV_CODEC_ID_H264);
* if (!codec)
* exit(1);
*
* context = avcodec_alloc_context3(codec);
*
* if (avcodec_open2(context, codec, opts) < 0)
* exit(1);
* @endcode
*
* @param avctx The context to initialize.
* @param codec The codec to open this context for. If a non-NULL codec has been
* previously passed to avcodec_alloc_context3() or
* for this context,e then this parameter MUST be either NULL or
* equal to the previously passed codec.
* @param options A dictionary filled with AVCodecContext and codec-private options.
* On return this object will be filled with options that were not found.
*
* @return zero on success, a negative value on error
* @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
* av_dict_set(), av_opt_find().
*/
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
函数剖析:
第一步:分配内存保存解码帧数据和解码帧
avctx->internal avctx->internal->pool avctx->internal->to_free avctx->internal->compat_decode_frame
avctx->internal->buffer_frame avctx->internal->buffer_pkt avctx->internal->ds.in_pkt avctx->internal->last_pkt_props
> ffplayd.exe!h264_parse_nal_header(H2645NAL * nal, void * logctx) 行 318 C
ffplayd.exe!ff_h2645_packet_split(H2645Packet * pkt, const unsigned char * buf, int length, void * logctx, int is_nalff, int nal_length_size, AVCodecID codec_id, int small_padding, int use_ref) 行 499 C
ffplayd.exe!decode_extradata_ps(const unsigned char * data, int size, H264ParamSets * ps, int is_avc, void * logctx) 行 368 C
ffplayd.exe!ff_h264_decode_extradata(const unsigned char * data, int size, H264ParamSets * ps, int * is_avc, int * nal_length_size, int err_recognition, void * logctx) 行 502 C
ffplayd.exe!h264_decode_init(AVCodecContext * avctx) 行 416 C
ffplayd.exe!avcodec_open2(AVCodecContext * avctx, const AVCodec * codec, AVDictionary * * options) 行 934 C
ffplayd.exe!avformat_find_stream_info(AVFormatContext * ic, AVDictionary * * options) 行 3671 C
ffplayd.exe!read_thread(void * arg) 行 2808 C
ffplayd.exe!SDL_RunThread(void * data) 行 283 C
ffplayd.exe!RunThread(void * data) 行 91 C
ffplayd.exe!RunThreadViaBeginThreadEx(void * data) 行 106 C
ucrtbased.dll!00007ffa11d54fb8() 未知
ucrtbased.dll!00007ffa11d54bf1() 未知
kernel32.dll!00007ffa572b7c24() 未知
ntdll.dll!00007ffa578ed4d1() 未知
static int h264_parse_nal_header(H2645NAL *nal, void *logctx)
{
GetBitContext *gb = &nal->gb;
if (get_bits1(gb) != 0)
return AVERROR_INVALIDDATA;
nal->ref_idc = get_bits(gb, 2);
nal->type = get_bits(gb, 5);
av_log(logctx, AV_LOG_DEBUG,
"nal_unit_type: %d(%s), nal_ref_idc: %d\n",
nal->type, h264_nal_unit_name(nal->type), nal->ref_idc);
return 1;
}
在函数中打印下面两行
I:2018-01-08 14:23:00 ms:221:nal_unit_type: 7, nal_ref_idc: 3
I:2018-01-08 14:23:00 ms:221:nal_unit_type: 8, nal_ref_idc: 3
I:2018-01-08 14:23:00 ms:221:sps:0 profile:66/42 poc:0 ref:1 120x68 FRM 8B8 crop:0/0/0/8 VUI 420 1800/90000 b8 reo:-1
I:2018-01-08 14:23:00 ms:221:pps:0 sps:0 CAVLC slice_groups:1 ref:1/1 qp:26/26/0/0 LPAR
I:2018-01-08 14:23:00 ms:222:deprecated pixel format used, make sure you did set range correctly
I:2018-01-08 14:23:00 ms:250:non-existing PPS 0 referenced