我是一个比较笨的人,记忆力比较差的,可能学习到一定程度就觉得需要记录下来,这样怎能让我自己的学习完成由点到面的升华,所以我把ffmpeg源码学习中比较重要的部分记录下来,因为源码都是C/C++语言的需要有这些基础的人才能读懂源码。实事求是的说这种定制化开源源码的学习一定要从源码中提供的例子入手,从例子中先学习知识点,然后自己再通过上手编写,这样循序渐进才能得到提升。网络上这样的总结相对少很多,那么我将ffmpeg中API常用结构体以及跟和它配套使用的函数总结下来。先来张火锅图片吧,之后都是一些总结,等这些结构体和配套的函数都烂熟于心我们编写代码的时候就得心应手不少!
源码下载链接http://ffmpeg.org/,本总结的学习是基于ffmpeg-4.2,这是目前为止最新版。
下载之后使用visual stud code工具打开学习,建议从example开始学习!
1.AVPacket
This structure stores compressed data. It is typically exported by demuxers and then passed as input to decoders, or received as output from encoders and then passed to muxers.
For video, it should typically contain one compressed frame. For audio it may contain several compressed frames. Encoders are allowed to output empty packets, with no compressed data, containing only side data (e.g. to update some stream parameters at the end of encoding). AVPacket is one of the few structs in FFmpeg, whose size is a part of public ABI.
Thus it may be allocated on stack and no new fields can be added to it without libavcodec and libavformat major bump. The semantics of data ownership depends on the buf field.If it is set, the packet data is dynamically allocated and is valid indefinitely until a call to av_packet_unref() reduces the reference count to 0.
If the buf field is not set av_packet_ref() would make a copy instead of increasing the reference count.The side data is always allocated with av_malloc(), copied by av_packet_ref() and freed by av_packet_unref().
@see av_packet_ref
@see av_packet_unref
与其对应的函数是
1.1 av_packet_alloc()
Allocate an AVPacket and set its fields to default values.
The resulting struct must be freed using av_packet_free(). @return An AVPacket filled with default values or NULL on failure.
@note this only allocates the AVPacket itself, not the data buffers. Those must be allocated through other means such as av_new_packet.
@see av_new_packet
1.2 av_packet_free()
Free the packet, if the packet is reference counted, it will be unreferenced first. @param pkt packet to be freed. The pointer will be set to NULL.
@note passing NULL is a no-op.
2 AVCodec
编解码器的结构体,包括了各种变量和函数指针,官方没有给出这个结构体的英文描述,但官方给出了大部分过成员变量的描述和解释
2.1 avcodec_find_decoder()
Find a registered decoder with a matching codec ID.
@param id AVCodecID of the requested decoder @return A decoder if one was found, NULL otherwise.
3 AVCodecContext
main external API structure.New fields can be added to the end with minor version bumps.
Removal, reordering and changes to existing fields require a major version bump. You can use AVOptions (av_opt* / av_set/get*()) to access these fields from user applications.
The name string for AVOptions options matches the associated command line parameter name and can be found in libavcodec/options_table.h
The AVOption/command line parameter names differ in some cases from the C structure field names for historic reasons or brevity.
sizeof(AVCodecContext) must not be used outside libav*.
3.1 avcodec_alloc_context3()
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.
3.2 avcodec_open2()
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()).
4 AVFrame
This structure describes decoded (raw) audio or video data.AVFrame must be allocated using av_frame_alloc().
Note that this only allocates the AVFrame itself, the buffers for the data must be managed through other means (see below). AVFrame must be freed with av_frame_free(). AVFrame is typically allocated once and then reused multiple times to hold different data (e.g. a single AVFrame to hold frames received from a decoder). In such a case, av_frame_unref() will free any references held by the frame and reset it to its original clean state before it is reused again.
The data described by an AVFrame is usually reference counted through the AVBuffer API. The underlying buffer references are stored in AVFrame.buf / AVFrame.extended_buf.
An AVFrame is considered to be reference counted if at least one reference is set, i.e. if AVFrame.buf[0] != NULL. In such a case, every single data plane must be contained in one of the buffers in AVFrame.buf or AVFrame.extended_buf. There may be a single buffer for all the data, or one separate buffer for each plane, or anything in between. sizeof(AVFrame) is not a part of the public ABI, so new fields may be added to the end with a minor bump.
Fields can be accessed through AVOptions, the name string used, matches the C structure field name for fields accessible through AVOptions.
The AVClass for AVFrame can be obtained from avcodec_get_frame_class().
4.1 av_frame_alloc()
Allocate an AVFrame and set its fields to default values. The resulting struct must be freed using av_frame_free(). @return An AVFrame filled with default values or NULL on failure.
@note this only allocates the AVFrame itself, not the data buffers. Those must be allocated through other means, e.g. with av_frame_get_buffer() or manually.
4.2 av_frame_free()
Free the frame and any dynamically allocated objects in it, e.g. extended_data. If the frame is reference counted, it will be unreferenced first.
@param frame frame to be freed. The pointer will be set to NULL.
5 AVCodecParserContext
解析器内容的结构体,包括了各种变量来解释和记录frame相关的side infomation,官方没有给出这个结构体的英文描述,但官方给出了大部分过成员变量的描述和解释
5.1 av_parser_init(参数codec的ID)
利用与参数code ID匹配的解析器注册实例化并返回一个AVCodecParserContext类型。
5.2 av_parser_parse2()
Parse a packet.
@param s parser context.
@param avctx codec context.
@param poutbuf set to pointer to parsed buffer or NULL if not yet finished.
@param poutbuf_size set to size of parsed buffer or zero if not yet finished.
@param buf input buffer.
@param buf_size buffer size in bytes without the padding. I.e. the full buffer size is assumed to be buf_size + AV_INPUT_BUFFER_PADDING_SIZE. To signal EOF, this should be 0 (so that the last frame can be output). @param pts input presentation timestamp.
@param dts input decoding timestamp.
@param pos input byte position in stream.
@return the number of bytes of the input bitstream used.
Example: @code
while(in_len){ len = av_parser_parse2(myparser, AVCodecContext, &data, &size,in_data, in_len,pts, dts, pos);
in_data += len;
in_len -= len;
if(size) decode_frame(data, size); }
@endcode
5.3 av_parser_close()
关闭解析器,free所有和解析相关的解析内容结构体指针
5.4 int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder. Internally, this call will copy relevant AVCodecContext fields, which can influence decoding per-packet, and apply them when the packet is actually decoded. (For example AVCodecContext.skip_frame, which might direct the decoder to drop the frame contained by the packet sent with this function.)
@warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE larger than the actual read bytes because some optimized bitstream readers read 32 or 64 bits at once and could read over the end.
@warning Do not mix this API with the legacy API (like avcodec_decode_video2()) on the same AVCodecContext. It will return unexpected results now or in future libavcodec versions.
@note The AVCodecContext MUST have been opened with
@ref avcodec_open2() before packets may be fed to the decoder.
@param avctx codec context
@param[in] avpkt The input AVPacket. Usually, this will be a single video Ownership of the packet remains with the caller, and the decoder will not write to the packet. The decoder may create a reference to the packet data (or copy it if the packet is not reference-counted). Unlike with older APIs, the packet is always fully consumed, and if it contains multiple frames (e.g. some audio codecs),will require you to call avcodec_receive_frame() multiple times afterwards before you can send a new packet. It can be NULL (or an AVPacket with data set to NULL and size set to 0); in this case, it is considered a flushpacket, which signals the end of the stream. Sending the first flush packet will return success. Subsequent ones are unnecessary and will return AVERROR_EOF. If the decoder still has frames buffered, it will return them after sending a flush packet.
@return 0 on success, otherwise negative error code: AVERROR(EAGAIN): input is not accepted in the current state - user must read output with avcodec_receive_frame() (once all output is read, the packet should be resent, and the call will not fail with EAGAIN).
AVERROR_EOF: the decoder has been flushed, and no new packets can be sent to it (also returned if more than 1 flush packet is sent)
AVERROR(EINVAL): codec not opened, it is an encoder, or requires flush AVERROR(ENOMEM): failed to add packet to internal queue, or similar other errors: legitimate decoding errors.
5.5 int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Return decoded output data from a decoder.
@param avctx codec context
@param frame This will be set to a reference-counted video or audio frame (depending on the decoder type) allocated by the decoder. Note that the function will always call av_frame_unref(frame) before doing anything else.
@return 0: success, a frame was returned AVERROR(EAGAIN): output is not available in this state - user must try to send new input AVERROR_EOF: the decoder has been fully flushed, and there will be no more output frames AVERROR(EINVAL): codec not opened, or it is an encoder AVERROR_INPUT_CHANGED: current decoded frame has changed parameters with respect to first decoded frame.
Applicable when flag AV_CODEC_FLAG_DROPCHANGED is set. other negative values: legitimate decoding errors.
6 AVFormatContext
Format I/O context. New fields can be added to the end with minor version bumps. Removal, reordering and changes to existing fields require a major version bump.
sizeof(AVFormatContext) must not be used outside libav*, use avformat_alloc_context() to create an AVFormatContext. Fields can be accessed through AVOptions (av_opt*), the name string used matches the associated command line parameter name and can be found in libavformat/options_table.h.
The AVOption/command line parameter names differ in some cases from the C structure field names for historic reasons or brevity.
6.1 AVFormatContext *avformat_alloc_context(void)
Allocate an AVFormatContext. avformat_free_context() can be used to free the context and everything allocated by the framework within it.
6.2 void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.@param s context to free
6.3 int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header. The codecs are not opened. The stream must be closed with avformat_close_input().
@param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context). May be a pointer to NULL, in which case an AVFormatContext is allocated by this function and written into ps. Note that a user-supplied AVFormatContext will be freed on failure.
@param url URL of the stream to open.
@param fmt If non-NULL, this parameter forces a specific input format. Otherwise the format is autodetected.
@param options A dictionary filled with AVFormatContext and demuxer-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, a negative AVERROR on failure.
@note If you want to use custom IO, preallocate the format context and set its pb field.
6.4 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information. This is useful for file formats with no headers such as MPEG. This function also computes the real framerate in case of MPEG-2 repeat frame mode.The logical file position is not changed by this function; examined packets may be buffered for later processing.
@param ic media file handle
@param options If non-NULL, an ic.nb_streams long array of pointers to dictionaries, where i-th member contains options for codec corresponding to i-th stream. On return each dictionary will be filled with options that were not found.
@return >=0 if OK, AVERROR_xxx on error
@note this function isn't guaranteed to open all the codecs, so options being non-empty at return is a perfectly normal behavior.
@todo Let the user decide somehow what information is needed so that we do not waste time getting stuff the user does not need.
6.5 int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, AVCodec **decoder_ret, int flags)
Find the "best" stream in the file. The best stream is determined according to various heuristics as the most likely to be what the user expects. If the decoder parameter is non-NULL, av_find_best_stream will find the default decoder for the stream's codec; streams for which no decoder can be found are ignored.
@param ic media file handle
@param type stream type: video, audio, subtitles, etc.
@param wanted_stream_nb user-requested stream number,or -1 for automatic selection
@param related_stream try to find a stream related (eg. in the same program) to this one, or -1 if none
@param decoder_ret if non-NULL, returns the decoder for the selected stream
@param flags flags; none are currently defined
@return the non-negative stream number in case of success, AVERROR_STREAM_NOT_FOUND if no stream with the requested type could be found, AVERROR_DECODER_NOT_FOUND if streams were found but no decoder
@note If av_find_best_stream returns successfully and decoder_ret is not NULL, then *decoder_ret is guaranteed to be set to a valid AVCodec.
6.6 int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par)
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.