FFMPEG解码学习笔记(一)
FFMPEG的基本处理流程

音频视频同步资料
获取当前帧的持续时间
av_frame_get_pkt_pos(frame)
从最后一个AVPacket进入解码重新排序的偏移量
av_frame_get_best_effort_timestamp(frame)
已流中的时间为基础预估的时间戳
/*** When decoding, this signals how much the picture must be delayed.* extra_delay = repeat_pict / (2*fps)*/int repeat_pict;
当解码时,这个信号告诉你这张图片需要要延迟多少久。
需要求出扩展延时:
extra_delay = repeat_pict / (2*fps)
/*** This is the fundamental unit of time (in seconds) in terms* of which frame timestamps are represented. For fixed-fps content,* timebase should be 1/framerate and timestamp increments should be* identically 1.* This often, but not always is the inverse of the frame rate or field rate* for video. 1/time_base is not the average frame rate if the frame rate is not* constant.** Like containers, elementary streams also can store timestamps, 1/time_base* is the unit in which these timestamps are specified.* As example of such codec time base see ISO/IEC 14496-2:2001(E)* vop_time_increment_resolution and fixed_vop_rate* (fixed_vop_rate == 0 implies that it is different from the framerate)** - encoding: MUST be set by user.* - decoding: the use of this field for decoding is deprecated.* Use framerate instead.*/AVRational time_base;
当前帧需要耗时多少秒,每一帧显示的时间
由以上两个定义可以推导:
extra_delay = repeat_pict / (2*fps)
fps=1/time_base
那么
extra_delay= repeat_pict*time_base*0.5
AVCodecContent
/*** Allocate an AVCodecContext and set its fields to default values. The* resulting struct should be freed with avcodec_free_context().** @param codec if non-NULL, allocate private data and initialize defaults* for the given codec. It is illegal to then call avcodec_open2()* with a different codec.* If NULL, then the codec-specific defaults won't be initialized,* which may result in suboptimal default settings (this is* important mainly for encoders, e.g. libx264).** @return An AVCodecContext filled with default values or NULL on failure.*/AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
分配一个AVCodecContent并为其分配默认值。(可理解为一个AVCodecContent分配内存空间)
释放它的资源使用avcodec_free_context()。
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
/*** Initialize the AVCodecContext to use the given AVCodec. Prior to using this* function the context has to be allocated with avcodec_alloc_context3().** 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.** @warning This function is not thread safe!** @note Always call this function before using decoding routines (such as* @ref avcodec_receive_frame()).** @code* 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, 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);
使用AVCodec初始化AVCodecContext。在初始化之前需要为其分配内存。
/*** Copy the settings of the source AVCodecContext into the destination* AVCodecContext. The resulting destination codec context will be* unopened, i.e. you are required to call avcodec_open2() before you* can use this AVCodecContext to decode/encode video/audio data.** @param dest target codec context, should be initialized with* avcodec_alloc_context3(NULL), but otherwise uninitialized* @param src source codec context* @return AVERROR() on error (e.g. memory allocation error), 0 on success** @deprecated The semantics of this function are ill-defined and it should not* be used. If you need to transfer the stream parameters from one codec context* to another, use an intermediate AVCodecParameters instance and the* avcodec_parameters_from_context() / avcodec_parameters_to_context()* functions.*/attribute_deprecatedint avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
该函数已不建议使用。它可以将原AVCodecContext的设置拷贝到目标AVCodecContent。
如果在使用这个数据之前调用avcodec_open2(),会导致无法打开。
建议使用avcodec_parameters_from_context() / avcodec_parameters_to_context()传递参数。
/*** Fill the parameters struct based on the values from the supplied codec* context. Any allocated fields in par are freed and replaced with duplicates* of the corresponding fields in codec.** @return >= 0 on success, a negative AVERROR code on failure*/int avcodec_parameters_from_context(AVCodecParameters *par,const AVCodecContext *codec);
从一个AVCodecContent中拷贝出AVCodecParameters
/*** Fill the codec context based on the values from the supplied codec* parameters. Any allocated fields in codec that have a corresponding field in* par are freed and replaced with duplicates of the corresponding field in par.* Fields in codec that do not have a counterpart in par are not touched.** @return >= 0 on success, a negative AVERROR code on failure.*/int avcodec_parameters_to_context(AVCodecContext *codec,const AVCodecParameters *par);
向一个AVCodecContent拷贝一个AVCodecParameters
/*** Return the next frame of a stream.* This function returns what is stored in the file, and does not validate* that what is there are valid frames for the decoder. It will split what is* stored in the file into frames and return one for each call. It will not* omit invalid data between valid frames so as to give the decoder the maximum* information possible for decoding.** If pkt->buf is NULL, then the packet is valid until the next* av_read_frame() or until avformat_close_input(). Otherwise the packet* is valid indefinitely. In both cases the packet must be freed with* av_packet_unref when it is no longer needed. For video, the packet contains* exactly one frame. For audio, it contains an integer number of frames if each* frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames* have a variable size (e.g. MPEG audio), then it contains one frame.** pkt->pts, pkt->dts and pkt->duration are always set to correct* values in AVStream.time_base units (and guessed if the format cannot* provide them). pkt->pts can be AV_NOPTS_VALUE if the video format* has B-frames, so it is better to rely on pkt->dts if you do not* decompress the payload.** @return 0 if OK, < 0 on error or end of file*/int av_read_frame(AVFormatContext *s, AVPacket *pkt);
返回下一帧的流

浙公网安备 33010602011771号