FFMPEG解码学习笔记

Posted 绝望的老猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FFMPEG解码学习笔记相关的知识,希望对你有一定的参考价值。

FFMPEG的基本处理流程

 
音频视频同步资料

av_frame_get_pkt_duration(frame)
获取当前帧的持续时间

av_frame_get_pkt_pos(frame)
从最后一个AVPacket进入解码重新排序的偏移量


av_frame_get_best_effort_timestamp(frame)
已流中的时间为基础预估的时间戳

  1. /**
  2. * When decoding, this signals how much the picture must be delayed.
  3. * extra_delay = repeat_pict / (2*fps)
  4. */
  5. int repeat_pict;
当解码时,这个信号告诉你这张图片需要要延迟多少久。
需要求出扩展延时:
extra_delay = repeat_pict / (2*fps)

  1. /**
  2. * This is the fundamental unit of time (in seconds) in terms
  3. * of which frame timestamps are represented. For fixed-fps content,
  4. * timebase should be 1/framerate and timestamp increments should be
  5. * identically 1.
  6. * This often, but not always is the inverse of the frame rate or field rate
  7. * for video. 1/time_base is not the average frame rate if the frame rate is not
  8. * constant.
  9. *
  10. * Like containers, elementary streams also can store timestamps, 1/time_base
  11. * is the unit in which these timestamps are specified.
  12. * As example of such codec time base see ISO/IEC 14496-2:2001(E)
  13. * vop_time_increment_resolution and fixed_vop_rate
  14. * (fixed_vop_rate == 0 implies that it is different from the framerate)
  15. *
  16. * - encoding: MUST be set by user.
  17. * - decoding: the use of this field for decoding is deprecated.
  18. * Use framerate instead.
  19. */
  20. AVRational time_base;
当前帧需要耗时多少秒,每一帧显示的时间

由以上两个定义可以推导:
extra_delay = repeat_pict / (2*fps)
fps=1/time_base
那么
extra_delay= repeat_pict*time_base*0.5

AVCodecContent
  1. /**
  2. * Allocate an AVCodecContext and set its fields to default values. The
  3. * resulting struct should be freed with avcodec_free_context().
  4. *
  5. * @param codec if non-NULL, allocate private data and initialize defaults
  6. * for the given codec. It is illegal to then call avcodec_open2()
  7. * with a different codec.
  8. * If NULL, then the codec-specific defaults won\'t be initialized,
  9. * which may result in suboptimal default settings (this is
  10. * important mainly for encoders, e.g. libx264).
  11. *
  12. * @return An AVCodecContext filled with default values or NULL on failure.
  13. */
  14. AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
分配一个AVCodecContent并为其分配默认值。(可理解为一个AVCodecContent分配内存空间)
释放它的资源使用avcodec_free_context()。

int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
  1. /**
  2. * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
  3. * function the context has to be allocated with avcodec_alloc_context3().
  4. *
  5. * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
  6. * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
  7. * retrieving a codec.
  8. *
  9. * @warning This function is not thread safe!
  10. *
  11. * @note Always call this function before using decoding routines (such as
  12. * @ref avcodec_receive_frame()).
  13. *
  14. * @code
  15. * avcodec_register_all();
  16. * av_dict_set(&opts, "b", "2.5M", 0);
  17. * codec = avcodec_find_decoder(AV_CODEC_ID_H264);
  18. * if (!codec)
  19. * exit(1);
  20. *
  21. * context = avcodec_alloc_context3(codec);
  22. *
  23. * if (avcodec_open2(context, codec, opts) < 0)
  24. * exit(1);
  25. * @endcode
  26. *
  27. * @param avctx The context to initialize.
  28. * @param codec The codec to open this context for. If a non-NULL codec has been
  29. * previously passed to avcodec_alloc_context3() or
  30. * for this context, then this parameter MUST be either NULL or
  31. * equal to the previously passed codec.
  32. * @param options A dictionary filled with AVCodecContext and codec-private options.
  33. * On return this object will be filled with options that were not found.
  34. *
  35. * @return zero on success, a negative value on error
  36. * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
  37. * av_dict_set(), av_opt_find().
  38. */
  39. int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
使用AVCodec初始化AVCodecContext。在初始化之前需要为其分配内存。

  1. /**
  2. * Copy the settings of the source AVCodecContext into the destination
  3. * AVCodecContext. The resulting destination codec context will be
  4. * unopened, i.e. you are required to call avcodec_open2() before you
  5. * can use this AVCodecContext to decode/encode video/audio data.
  6. *
  7. * @param dest target codec context, should be initialized with
  8. * avcodec_alloc_context3(NULL), but otherwise uninitialized
  9. * @param src source codec context
  10. * @return AVERROR() on error (e.g. memory allocation error), 0 on success
  11. *
  12. * @deprecated The semantics of this function are ill-defined and it should not
  13. * be used. If you need to transfer the stream parameters from one codec context
  14. * to another, use an intermediate AVCodecParameters instance and the
  15. * avcodec_parameters_from_context() / avcodec_parameters_to_context()
  16. * functions.
  17. */
  18. attribute_deprecated
  19. int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
该函数已不建议使用。它可以将原AVCodecContext的设置拷贝到目标AVCodecContent。
如果在使用这个数据之前调用avcodec_open2(),会导致无法打开。
建议使用avcodec_parameters_from_context() / avcodec_parameters_to_context()传递参数。

  1. /**
  2. * Fill the parameters struct based on the values from the supplied codec
  3. * context. Any allocated fields in par are freed and replaced with duplicates
  4. * of the corresponding fields in codec.
  5. *
  6. * @return >= 0 on success, a negative AVERROR code on failure
  7. */
  8. int avcodec_parameters_from_context(AVCodecParameters *par,
  9. const AVCodecContext *codec);
从一个AVCodecContent中拷贝出AVCodecParameters
  1. /**
  2. * Fill the codec context based on the values from the supplied codec
  3. * parameters. Any allocated fields in codec that have a corresponding field in
  4. * par are freed and replaced with duplicates of the corresponding field in par.
  5. * Fields in codec that do not have a counterpart in par are not touched.
  6. *
  7. * @return >= 0 on success, a negative AVERROR code on failure.
  8. */
  9. int avcodec_parameters_to_context(AVCodecContext *codec,
  10. const AVCodecParameters *par);
向一个AVCodecContent拷贝一个AVCodecParameters

  1. /**
  2. * Return the next frame of a stream.
  3. * This function returns what is stored in the file, and does not validate
  4. * that what is there are valid frames for the decoder. It will split what is
  5. * stored in the file into frames and return one for each call. It will not
  6. * omit invalid data between valid frames so as to give the decoder the maximum
  7. * information possible for decoding.
  8. *
  9. * If pkt->buf is NULL, then the packet is valid until the next
  10. * av_read_frame() or until avformat_close_input(). Otherwise the packet
  11. * is valid indefinitely. In both cases the packet must be freed with
  12. * av_packet_unref when it is no longer needed. For video, the packet contains
  13. * exactly one frame. For audio, it contains an integer number of frames if each
  14. * frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames
  15. * have a variable size (e.g. MPEG audio), then it contains one frame.
  16. *
  17. * pkt->pts, pkt->dts and pkt->duration are always set to correct
  18. * values in AVStream.time_base units (and guessed if the format cannot
  19. * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format
  20. * has B-frames, so it is better to rely on pkt->dts if you do not
  21. * decompress the payload.
  22. *
  23. * @return 0 if OK, < 0 on error or end of file
  24. */
  25. int av_read_frame(AVFormatContext *s, AVPacket *pkt);
返回下一帧的流





以上是关于FFMPEG解码学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

ffmpeg史诗级教学-学习笔记

NDK学习笔记:java类封装c++类

ffmpeg解码音视频过程(附代码)

零基础学习视频解码之FFMpeg中比较重要的函数以及数据结构(转)

音视频编解码——解码:代码实现

FFmpeg 入门学习 07--创建音视频解码管理类