FFmpeg Muxing流程

FFmpeg Muxing流程_第1张图片

介绍

FFmpeg的Muxing主要分为三步操作:

  • avformat_write_header : 写文件头
  • av_write_frame/av_interleaved_write_frame: 写packet
  • av_write_trailer : 写文件尾
1、av_format_write_head
/**
 * Allocate the stream private data and write the stream header to
 * an output media file.
 *
 * @param s Media file handle, must be allocated with avformat_alloc_context().
 *          Its oformat field must be set to the desired output format;
 *          Its pb field must be set to an already opened AVIOContext.
 * @param options  An AVDictionary filled with AVFormatContext and muxer-private options.
 *                 On return this parameter will be destroyed and replaced with a dict containing
 *                 options that were not found. May be NULL.
 *
 * @return 0 on success, negative AVERROR on failure.
 *
 * @see av_opt_find, av_dict_set, avio_open, av_oformat_next.
 */
int avformat_write_header(AVFormatContext *s, AVDictionary **options);

简单描述其功能:

s:用于输出的AVFormatContext。
options:额外的选项,目前没有深入研究过,一般为NULL。

2、av_write_frame/av_interleaved_write_frame
2.1 av_write_frame

av_write_frame 直接将包写进Mux,没有缓存和重新排序,一切都需要用户自己设置。

/**
 * Write a packet to an output media file.
 *
 * This function passes the packet directly to the muxer, without any buffering
 * or reordering. The caller is responsible for correctly interleaving the
 * packets if the format requires it. Callers that want libavformat to handle
 * the interleaving should call av_interleaved_write_frame() instead of this
 * function.
 *
 * @param s media file handle
 * @param pkt The packet containing the data to be written. Note that unlike
 *            av_interleaved_write_frame(), this function does not take
 *            ownership of the packet passed to it (though some muxers may make
 *            an internal reference to the input packet).
 *            
* This parameter can be NULL (at any time, not just at the end), in * order to immediately flush data buffered within the muxer, for * muxers that buffer up data internally before writing it to the * output. *
* Packet's @ref AVPacket.stream_index "stream_index" field must be * set to the index of the corresponding stream in @ref * AVFormatContext.streams "s->streams". It is very strongly * recommended that timing information (@ref AVPacket.pts "pts", @ref * AVPacket.dts "dts", @ref AVPacket.duration "duration") is set to * correct values. * @return < 0 on error, = 0 if OK, 1 if flushed and there is no more data to flush * * @see av_interleaved_write_frame() */
int av_write_frame(AVFormatContext *s, AVPacket *pkt);
2.2 av_interleaved_write_frame

av_interleaved_write_frame 将对 packet 进行缓存和 pts 检查,这是区别于 av_write_frame 的地方。

/**
 * Write a packet to an output media file ensuring correct interleaving.
 *
 * This function will buffer the packets internally as needed to make sure the
 * packets in the output file are properly interleaved in the order of
 * increasing dts. Callers doing their own interleaving should call
 * av_write_frame() instead of this function.
 *
 * @param s media file handle
 * @param pkt The packet containing the data to be written.
 *            
* If the packet is reference-counted, this function will take * ownership of this reference and unreference it later when it sees * fit. * The caller must not access the data through this reference after * this function returns. If the packet is not reference-counted, * libavformat will make a copy. *
* This parameter can be NULL (at any time, not just at the end), to * flush the interleaving queues. *
* Packet's @ref AVPacket.stream_index "stream_index" field must be * set to the index of the corresponding stream in @ref * AVFormatContext.streams "s->streams". It is very strongly * recommended that timing information (@ref AVPacket.pts "pts", @ref * AVPacket.dts "dts", @ref AVPacket.duration "duration") is set to * correct values. * * @return 0 on success, a negative AVERROR on error. Libavformat will always * take care of freeing the packet, even if this function fails. * * @see av_write_frame(), AVFormatContext.max_interleave_delta */
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
结论是:在有多个流的情况下要用av_interleaved_write_frame,只有单一流2个函数都可以用
3、av_write_trailer()

av_write_trailer()用于输出文件尾,它的声明位于libavformat\avformat.h,如下所示

/**
 * Write the stream trailer to an output media file and free the
 * file private data.
 *
 * May only be called after a successful call to avformat_write_header.
 *
 * @param s media file handle
 * @return 0 if OK, AVERROR_xxx on error
 */
int av_write_trailer(AVFormatContext *s);

av_write_trailer()主要完成了以下两步工作:

  • (1)循环调用interleave_packet()以及write_packet(),将还未输出的AVPacket输出出来。
  • (2)调用AVOutputFormat的write_trailer(),输出文件尾。

你可能感兴趣的:(FFmpeg,ffmpeg)