`
chriszeng87
  • 浏览: 738394 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ffmpeg函数介绍

阅读更多

本文对在使用ffmpeg进行音视频编解码时使用到的一些函数做一个简单介绍,我当前使用的ffmpeg版本为:0.8.5,因为本人发现在不同的版本中,有些函数名称会有点小改动,所以在此有必要说明下ffmpeg的版本号。

ffmpeg本人也是刚接触,本文将采用累加的方法逐个介绍我使用到的函数,如有不妥之处,还望谅解!

 

头文件引入方法:

extern "C" {

#include "libavcodec/avcodec.h"

#include "libavformat/avformat.h"

#include "libavutil/avutil.h"

#include "libavutil/mem.h"

#include "libavutil/fifo.h"

#include "libswscale/swscale.h"

};

 

1 avcodec_init()

/**

 * Initialize libavcodec.

 * If called more than once, does nothing.

 *

 * @warning This function must be called before any other libavcodec

 * function.

 *

 * @warning This function is not thread-safe.

 */

void avcodec_init(void);

// 初始化libavcodec,一般最先调用该函数

// 引入头文件: #include "libavcodec/avcodec.h"

// 实现在: \ffmpeg\libavcodec\utils.c

// 该函数必须在调用libavcodec里的其它函数前调用,一般在程序启动或模块初始化时调用,如果你调用了多次也无所谓,因为后面的调用不会做任何事情.从函数的实现里你可以发现,代码中对多次调用进行了控制.

// 该函数是非线程安全的

 

2 av_register_all()

/**

 * Initialize libavformat and register all the muxers, demuxers and

 * protocols. If you do not call this function, then you can select

 * exactly which formats you want to support.

 *

 * @see av_register_input_format()

 * @see av_register_output_format()

 * @see av_register_protocol()

 */

void av_register_all(void);

// 初始化 libavformat和注册所有的muxers、demuxers和protocols,

// 一般在调用avcodec_init后调用该方法

// 引入头文件:#include "libavformat/avformat.h"

// 实现在:\ffmpeg\libavformat\allformats.c

// 其中会调用avcodec_register_all()注册多种音视频格式的编解码器,并注册各种文件的编解复用器

// 当然,你也可以不调用该函数,而通过选择调用特定的方法来提供支持

 

3 avformat_alloc_context()

/**

 * Allocate an AVFormatContext.

 * avformat_free_context() can be used to free the context and everything

 * allocated by the framework within it.

 */

AVFormatContext *avformat_alloc_context(void);

// 分配一个AVFormatContext结构

// 引入头文件:#include "libavformat/avformat.h"

// 实现在:\ffmpeg\libavformat\options.c

// 其中负责申请一个AVFormatContext结构的内存,并进行简单初始化

// avformat_free_context()可以用来释放该结构里的所有东西以及该结构本身

// 也是就说使用 avformat_alloc_context()分配的结构,需要使用avformat_free_context()来释放

// 有些版本中函数名可能为: av_alloc_format_context();

 

4 avformat_free_context()

/**

 * Free an AVFormatContext and all its streams.

 * @param s context to free

 */

void avformat_free_context(AVFormatContext *s);

// 释放一个AVFormatContext结构

// 引入头文件:#include "libavformat/avformat.h"

// 实现在:\ffmpeg\libavformat\utils.c

// 使用 avformat_alloc_context()分配的结构,采用该函数进行释放,除释放AVFormatContext结构本身内存之外,AVFormatContext中指针所指向的内存也会一并释放

// 有些版本中函数名猜测可能为: av_free_format_context();

 

5 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*.

 */

typedef struct AVFormatContext {

 

    struct AVInputFormat *iformat;

    struct AVOutputFormat *oformat;

    AVIOContext *pb;

    unsigned int nb_streams;

    AVStream **streams;

    char filename[1024]; /**< input or output filename */

    ....

} AVFormatContext;

// AVFormatContext在FFMpeg里是一个非常重要的的结构,是其它输入、输出相关信息的一个容器

// 引入头文件:#include "libavformat/avformat.h"

// 以上只列出了其中的部分成员

// 作为输入容器时 struct AVInputFormat *iformat; 不能为空, 其中包含了输入文件的音视频流信息,程序从输入容器从读出音视频包进行解码处理

// 作为输出容器时 struct AVOutputFormat *oformat; 不能为空, 程序把编码好的音视频包写入到输出容器中

// AVIOContext *pb: I/O上下文,通过对该变量赋值可以改变输入源或输出目的

// unsigned int nb_streams; 音视频流数量

// AVStream **streams; 音视频流

 

6 AVIOContext 结构

/**

 * Bytestream IO 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(AVIOContext) must not be used outside libav*.

 *

 * @note None of the function pointers in AVIOContext should be called

 *       directly, they should only be set by the client application

 *       when implementing custom I/O. Normally these are set to the

 *       function pointers specified in avio_alloc_context()

 */

typedef struct {

    unsigned char *buffer;  /**< Start of the buffer. */

    int buffer_size;        /**< Maximum buffer size */

    unsigned char *buf_ptr; /**< Current position in the buffer */

    unsigned char *buf_end; /**< End of the data, may be less than

                                 buffer+buffer_size if the read function returned

                                 less data than requested, e.g. for streams where

                                 no more data has been received yet. */

    void *opaque;           /**< A private pointer, passed to the read/write/seek/...

                                 functions. */

    int (*read_packet)(void *opaque, uint8_t *buf,int buf_size);

    int (*write_packet)(void *opaque, uint8_t *buf,int buf_size);

    int64_t (*seek)(void *opaque, int64_t offset,int whence);

    int64_t pos;            /**< position in the file of the current buffer */

    int must_flush;         /**< true if the next seek should flush */

    int eof_reached;        /**< true if eof reached */

    int write_flag;         /**< true if open for writing */

#if FF_API_OLD_AVIO

    attribute_deprecated int is_streamed;

#endif

    int max_packet_size;

    unsigned long checksum;

    unsigned char *checksum_ptr;

    unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);

    int error;              /**< contains the error code or 0 if no error happened */

    /**

     * Pause or resume playback for network streaming protocols - e.g. MMS.

     */

    int (*read_pause)(void *opaque,int pause);

    /**

     * Seek to a given timestamp in stream with the specified stream_index.

     * Needed for some network streaming protocols which don't support seeking

     * to byte position.

     */

    int64_t (*read_seek)(void *opaque,int stream_index,

                         int64_t timestamp, int flags);

    /**

     * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.

     */

    int seekable;

} AVIOContext;

// 字节流 I/O 上下文

// 在结构的尾部增加变量可以减少版本冲突

// 移除、排序和修改已经存在的变量将会导致较大的版本冲突

// sizeof(AVIOContext)在libav*.外部不可使用

// AVIOContext里的函数指针不能直接调用,通常使用avio_alloc_context()函数来设置其中的函数指针

// unsigned char *buffer: 缓存的起始指针

// int buffer_size: 缓存的最大值

// void *opaque: 在回调函数中使用的指针

// int (*read_packet)(void *opaque, uint8_t *buf,int buf_size): 读文件回调方法

// int (*write_packet)(void *opaque, uint8_t *buf,int buf_size): 写文件回调方法

// int64_t (*seek)(void *opaque, int64_t offset,int whence): seek文件回调方法

 

7 avio_alloc_context()

/**

 * Allocate and initialize an AVIOContext for buffered I/O. It must be later

 * freed with av_free().

 *

 * @param buffer Memory block for input/output operations via AVIOContext.

 *        The buffer must be allocated with av_malloc() and friends.

 * @param buffer_size The buffer size is very important for performance.

 *        For protocols with fixed blocksize it should be set to this blocksize.

 *        For others a typical size is a cache page, e.g. 4kb.

 * @param write_flag Set to 1 if the buffer should be writable, 0 otherwise.

 * @param opaque An opaque pointer to user-specific data.

 * @param read_packet  A function for refilling the buffer, may be NULL.

 * @param write_packet A function for writing the buffer contents, may be NULL.

 * @param seek A function for seeking to specified byte position, may be NULL.

 *

 * @return Allocated AVIOContext or NULL on failure.

 */

AVIOContext *avio_alloc_context(

                  unsigned char *buffer,

                  int buffer_size,

                  int write_flag,

                  void *opaque,

                  int (*read_packet)(void *opaque, uint8_t *buf,int buf_size),

                  int (*write_packet)(void *opaque, uint8_t *buf,int buf_size),

                  int64_t (*seek)(void *opaque, int64_t offset,int whence));

// 为I/0缓存申请并初始化一个AVIOContext结构,结束使用时必须使用av_free()进行释放

// unsigned char *buffer: 输入/输出缓存内存块,必须是使用av_malloc()分配的

// int buffer_size: 缓存大小是非常重要的

// int write_flag: 如果缓存为可写则设置为1,否则设置为0

// void *opaque: 指针,用于回调时使用

// int (*read_packet): 读包函数指针

// int (*write_packet): 写包函数指针

// int64_t (*seek): seek文件函数指针

8 av_open_input_file()

/**

 * Open a media file as input. The codecs are not opened. Only the file

 * header (if present) is read.

 *

 * @param ic_ptr The opened media file handle is put here.

 * @param filename filename to open

 * @param fmt If non-NULL, force the file format to use.

 * @param buf_size optional buffer size (zero if default is OK)

 * @param ap Additional parameters needed when opening the file

 *           (NULL if default).

 * @return 0 if OK, AVERROR_xxx otherwise

 *

 * @deprecated use avformat_open_input instead.

 */

attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr,constchar *filename,

                       AVInputFormat *fmt,

                       int buf_size,

                       AVFormatParameters *ap);

 

// 以输入方式打开一个媒体文件,也即源文件,codecs并没有打开,只读取了文件的头信息.

// 引入头文件:#include "libavformat/avformat.h"

// AVFormatContext **ic_ptr 输入文件容器

//constchar *filename 输入文件名,全路径,并且保证文件存在

// AVInputFormat *fmt 输入文件格式,填NULL即可

//int buf_size,缓冲区大小,直接填0即可

// AVFormatParameters *ap, 格式参数,添NULL即可

// 成功返回0,其它失败

// 不赞成使用 avformat_open_input 代替

 

9 av_close_input_file()

/**

 * @deprecated use avformat_close_input()

 * Close a media file (but not its codecs).

 * @param s media file handle

 */

 

void av_close_input_file(AVFormatContext *s);

// 关闭使用avformat_close_input()打开的输入文件容器,但并不关系它的codecs

// 引入头文件:#include "libavformat/avformat.h"

// 使用av_open_input_file 打开的文件容器,可以使用该函数关闭

// 使用 av_close_input_file 关闭后,就不再需要使用avformat_free_context 进行释放了

 

10 av_find_stream_info()

/**

 * 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

 * @return >=0 if OK, AVERROR_xxx on error

 * @todo Let the user decide somehow what information is needed so that

 *       we do not waste time getting stuff the user does not need.

 */

int av_find_stream_info(AVFormatContext *ic);

// 通过读取媒体文件的中的包来获取媒体文件中的流信息,对于没有头信息的文件如(mpeg)是非常有用的,

// 该函数通常重算类似mpeg-2帧模式的真实帧率,该函数并未改变逻辑文件的position.

// 引入头文件:#include "libavformat/avformat.h"

// 也就是把媒体文件中的音视频流等信息读出来,保存在容器中,以便解码时使用

// 返回>=0时成功,否则失败

/***********************************************************/

1 avcodec_find_decoder()

/**

 * Find a registered decoder with a matching codec ID.

 *

 * @param id CodecID of the requested decoder

 * @return A decoder if one was found, NULL otherwise.

 */

AVCodec *avcodec_find_decoder(enum CodecID id);

// 通过code ID查找一个已经注册的音视频解码器

// 引入 #include "libavcodec/avcodec.h"

// 实现在: \ffmpeg\libavcodec\utils.c

// 查找解码器之前,必须先调用av_register_all注册所有支持的解码器

// 查找成功返回解码器指针,否则返回NULL

// 音视频解码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较解码器的ID来查找

 

2 avcodec_find_decoder_by_name()

/**

 * Find a registered decoder with the specified name.

 *

 * @param name name of the requested decoder

 * @return A decoder if one was found, NULL otherwise.

 */

AVCodec *avcodec_find_decoder_by_name(constchar *name);

// 通过一个指定的名称查找一个已经注册的音视频解码器

// 引入 #include "libavcodec/avcodec.h"

// 实现在: \ffmpeg\libavcodec\utils.c

// 查找解码器之前,必须先调用av_register_all注册所有支持的解码器

// 查找成功返回解码器指针,否则返回NULL

// 音视频解码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较解码器的name来查找

 

3 avcodec_find_encoder()

/**

 * Find a registered encoder with a matching codec ID.

 *

 * @param id CodecID of the requested encoder

 * @return An encoder if one was found, NULL otherwise.

 */

AVCodec *avcodec_find_encoder(enum CodecID id);

// 通过code ID查找一个已经注册的音视频编码器

// 引入 #include "libavcodec/avcodec.h"

// 实现在: \ffmpeg\libavcodec\utils.c

// 查找编码器之前,必须先调用av_register_all注册所有支持的编码器

// 查找成功返回编码器指针,否则返回NULL

// 音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的ID来查找

 

4 avcodec_find_encoder_by_name()

/**

 * Find a registered encoder with the specified name.

 *

 * @param name name of the requested encoder

 * @return An encoder if one was found, NULL otherwise.

 */

AVCodec *avcodec_find_encoder_by_name(constchar *name);

// 通过一个指定的名称查找一个已经注册的音视频编码器

// 引入 #include "libavcodec/avcodec.h"

// 实现在: \ffmpeg\libavcodec\utils.c

// 查找编码器之前,必须先调用av_register_all注册所有支持的编码器

// 查找成功返回编码器指针,否则返回NULL

// 音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的名称来查找

 

5 avcodec_open()

/**

 * Initialize the AVCodecContext to use the given AVCodec. Prior to using this

 * function the context has to be allocated.

 *

 * 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!

 *

 * @code

 * avcodec_register_all();

 * codec = avcodec_find_decoder(CODEC_ID_H264);

 * if (!codec)

 *     exit(1);

 *

 * context = avcodec_alloc_context();

 *

 * if (avcodec_open(context, codec) < 0)

 *     exit(1);

 * @endcode

 *

 * @param avctx The context which will be set up to use the given codec.

 * @param codec The codec to use within the context.

 * @return zero on success, a negative value on error

 * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder, avcodec_close

 */

int avcodec_open(AVCodecContext *avctx, AVCodec *codec);

// 使用给定的AVCodec初始化AVCodecContext

// 引入#include "libavcodec/avcodec.h"

// 方法: avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), avcodec_find_decoder() and avcodec_find_encoder() 提供了快速获取一个codec的途径

// 该方法在编码和解码时都会用到

// 返回0时成功,打开作为输出时,参数设置不对的话,调用会失败

 
6 av_guess_format()

/**

 * Return the output format in the list of registered output formats

 * which best matches the provided parameters, or return NULL if

 * there is no match.

 *

 * @param short_name if non-NULL checks if short_name matches with the

 * names of the registered formats

 * @param filename if non-NULL checks if filename terminates with the

 * extensions of the registered formats

 * @param mime_type if non-NULL checks if mime_type matches with the

 * MIME type of the registered formats

 */

AVOutputFormat *av_guess_format(constchar *short_name,

                                constchar *filename,

                                constchar *mime_type);

// 返回一个已经注册的最合适的输出格式

// 引入#include "libavformat/avformat.h"

// 可以通过 const char *short_name 获取,如"mpeg"

// 也可以通过 const char *filename 获取,如"E:\a.mp4"

 

7 av_new_stream()

/**

 * Add a new stream to a media file.

 *

 * Can only be called in the read_header() function. If the flag

 * AVFMTCTX_NOHEADER is in the format context, then new streams

 * can be added in read_packet too.

 *

 * @param s media file handle

 * @param id file-format-dependent stream ID

 */

AVStream *av_new_stream(AVFormatContext *s, int id);

// 为媒体文件添加一个流,一般为作为输出的媒体文件容器添加音视频流

// 引入 #include "libavformat/avformat.h"

// 再打开源文件时用户一般不需要直接调用该方法

 
8 dump_format()

#if FF_API_DUMP_FORMAT

/**

 * @deprecated Deprecated in favor of av_dump_format().

 */

attribute_deprecated void dump_format(AVFormatContext *ic,

                                      int index,

                                      constchar *url,

                                      int is_output);

#endif

// 该函数的作用就是检查下初始化过程中设置的参数是否符合规范
// 有些版本中为 av_dump_format
 
9 av_set_parameters()

#if FF_API_FORMAT_PARAMETERS

/**

 * @deprecated pass the options to avformat_write_header directly.

 */

attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);

#endif
// 设置初始化参数
// 不赞成跳过该方法,直接调用 avformat_write_header/av_write_header
 
10 av_write_header()

#if FF_API_FORMAT_PARAMETERS

/**

 * Allocate the stream private data and write the stream header to an

 * output media file.

 * @note: this sets stream time-bases, if possible to stream->codec->time_base

 * but for some formats it might also be some other time base

 *

 * @param s media file handle

 * @return 0 if OK, AVERROR_xxx on error

 *

 * @deprecated use avformat_write_header.

 */

attribute_deprecated int av_write_header(AVFormatContext *s);

#endif

// 把流头信息写入到媒体文件中
// 返回0成功
 

/**********************************************************/

1 AVPacket

typedef struct AVPacket {

    /**

     * Presentation timestamp in AVStream->time_base units; the time at which

     * the decompressed packet will be presented to the user.

     * Can be AV_NOPTS_VALUE if it is not stored in the file.

     * pts MUST be larger or equal to dts as presentation cannot happen before

     * decompression, unless one wants to view hex dumps. Some formats misuse

     * the terms dts and pts/cts to mean something different. Such timestamps

     * must be converted to true pts/dts before they are stored in AVPacket.

     */

    int64_t pts;

    /**

     * Decompression timestamp in AVStream->time_base units; the time at which

     * the packet is decompressed.

     * Can be AV_NOPTS_VALUE if it is not stored in the file.

     */

    int64_t dts;

    uint8_t *data;

    int   size;

    int   stream_index;

    int   flags;

 

int   duration;

.

.

.

} AVPacket

// AVPacket是个很重要的结构,该结构在读媒体源文件和写输出文件时都需要用到
// int64_t pts; 显示时间戳
// int64_t dts; 解码时间戳
// uint8_t *data; 包数据
// int   size; 包数据长度
// int   stream_index; 包所属流序号
// int   duration; 时长
// 以上信息,如果是在读媒体源文件那么avcodec会初始化,如果是输出文件,用户需要对以上信息赋值
 
2 av_init_packet()

/**

 * Initialize optional fields of a packet with default values.

 *

 * @param pkt packet

 */

void av_init_packet(AVPacket *pkt);

// 使用默认值初始化AVPacket
// 定义AVPacket对象后,请使用av_init_packet进行初始化
 
3 av_free_packet()

/**

 * Free a packet.

 *

 * @param pkt packet to free

 */

void av_free_packet(AVPacket *pkt);

// 释放AVPacket对象
 
av_read_frame()

/**

 * 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.

 *

 * The returned packet is valid

 * until the next av_read_frame() or until av_close_input_file() and

 * must be freed with av_free_packet. 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);

// 从输入源文件容器中读取一个AVPacket数据包

// 该函数读出的包并不每次都是有效的,对于读出的包我们都应该进行相应的解码(视频解码/音频解码),

// 在返回值>=0时,循环调用该函数进行读取,循环调用之前请调用av_free_packet函数清理AVPacket
 
avcodec_decode_video2()

/**

 * Decode the video frame of size avpkt->size from avpkt->data into picture.

 * Some decoders may support multiple frames in a single AVPacket, such

 * decoders would then just decode the first frame.

 *

 * @warning The input buffer must be FF_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 The end of the input buffer buf should be set to 0 to ensure that

 * no overreading happens for damaged MPEG streams.

 *

 * @note You might have to align the input buffer avpkt->data.

 * The alignment requirements depend on the CPU: on some CPUs it isn't

 * necessary at all, on others it won't work at all if not aligned and on others

 * it will work but it will have an impact on performance.

 *

 * In practice, avpkt->data should have 4 byte alignment at minimum.

 *

 * @note Some codecs have a delay between input and output, these need to be

 * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames.

 *

 * @param avctx the codec context

 * @param[out] picture The AVFrame in which the decoded video frame will be stored.

 *             Use avcodec_alloc_frame to get an AVFrame, the codec will

 *             allocate memory for the actual bitmap.

 *             with default get/release_buffer(), the decoder frees/reuses the bitmap as it sees fit.

 *             with overridden get/release_buffer() (needs CODEC_CAP_DR1) the user decides into what buffer the decoder

 *                   decodes and the decoder tells the user once it does not need the data anymore,

 *                   the user app can at this point free/reuse/keep the memory as it sees fit.

 *

 * @param[in] avpkt The input AVpacket containing the input buffer.

 *            You can create such packet with av_init_packet() and by then setting

 *            data and size, some decoders might in addition need other fields like

 *            flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least

 *            fields possible.

 * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.

 * @return On error a negative value is returned, otherwise the number of bytes

 * used or zero if no frame could be decompressed.

 */

int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,

                         int *got_picture_ptr,

                         AVPacket *avpkt);

// 解码视频流AVPacket
// 使用av_read_frame读取媒体流后需要进行判断,如果为视频流则调用该函数解码
// 返回结果<0时失败,此时程序应该退出检查原因
// 返回>=0时正常,假设 读取包为:AVPacket vPacket 返回值为 int vLen; 每次解码正常时,对vPacket做
// 如下处理:
//   vPacket.size -= vLen;
//   vPacket.data += vLen;
// 如果 vPacket.size==0,则继续读下一流包,否则继续调度该方法进行解码,直到vPacket.size==0
// 返回 got_picture_ptr > 0 时,表示解码到了AVFrame *picture,其后可以对picture进程处理
 
avcodec_decode_audio3()

/**

 * Decode the audio frame of size avpkt->size from avpkt->data into samples.

 * Some decoders may support multiple frames in a single AVPacket, such

 * decoders would then just decode the first frame. In this case,

 * avcodec_decode_audio3 has to be called again with an AVPacket that contains

 * the remaining data in order to decode the second frame etc.

 * If no frame

 * could be outputted, frame_size_ptr is zero. Otherwise, it is the

 * decompressed frame size in bytes.

 *

 * @warning You must set frame_size_ptr to the allocated size of the

 * output buffer before calling avcodec_decode_audio3().

 *

 * @warning The input buffer must be FF_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 The end of the input buffer avpkt->data should be set to 0 to ensure that

 * no overreading happens for damaged MPEG streams.

 *

 * @note You might have to align the input buffer avpkt->data and output buffer

 * samples. The alignment requirements depend on the CPU: On some CPUs it isn't

 * necessary at all, on others it won't work at all if not aligned and on others

 * it will work but it will have an impact on performance.

 *

 * In practice, avpkt->data should have 4 byte alignment at minimum and

 * samples should be 16 byte aligned unless the CPU doesn't need it

 * (AltiVec and SSE do).

 *

 * @param avctx the codec context

 * @param[out] samples the output buffer, sample type in avctx->sample_fmt

 * @param[in,out] frame_size_ptr the output buffer size in bytes

 * @param[in] avpkt The input AVPacket containing the input buffer.

 *            You can create such packet with av_init_packet() and by then setting

 *            data and size, some decoders might in addition need other fields.

 *            All decoders are designed to use the least fields possible though.

 * @return On error a negative value is returned, otherwise the number of bytes

 * used or zero if no frame data was decompressed (used) from the input AVPacket.

 */

int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,

                         int *frame_size_ptr,

                         AVPacket *avpkt);

// 解码音频流AVPacket
// 使用av_read_frame读取媒体流后需要进行判断,如果为音频流则调用该函数解码
// 返回结果<0时失败,此时程序应该退出检查原因
// 返回>=0时正常,假设 读取包为:AVPacket vPacket 返回值为 int vLen; 每次解码正常时,对vPacket做
// 如下处理:
//   vPacket.size -= vLen;
//   vPacket.data += vLen;
// 如果 vPacket.size==0,则继续读下一流包,否则继续调度该方法进行解码,直到vPacket.size==0
 
分享到:
评论

相关推荐

    ffmpeg函数库介绍.docx

    "ffmpeg 函数库介绍" ffmpeg 函数库是音视频处理领域中的一种功能强大且广泛使用的开源解决方案,提供了对多种媒体格式的解码、编码、处理和流媒体处理等功能。下面是对 ffmpeg 函数库中 AVPacket 结构体的详细介绍...

    FFmpeg函数说明文档

    国外开发的视频处理开发包FFmpeg的各个函数说明文档-Developed abroad FFmpeg video processing development kit documentation of all function

    ffmpeg函数使用

    在本文中,我们将深入探讨FFmpeg函数的使用,包括基本概念、核心功能以及常见的使用场景。 1. FFmpeg 库介绍 FFmpeg 提供了多个库,每个库都有其特定的职责: - libavcodec:包含了各种音频和视频编解码器。 - ...

    ffmpeg结构体以及函数介绍

    ### FFMPEG结构体及函数介绍 #### 一、引言 FFmpeg是音视频处理领域最著名的开源项目之一,提供了强大的音视频处理能力。它包含了一系列库与工具,能够帮助开发者实现音视频的编解码、转码、流媒体传输等功能。本文...

    FFMPEG内部函数逻辑图

    在FFmpeg的内部实现中,一系列精心设计的函数共同构成了复杂的逻辑流程,这些函数逻辑图对于理解FFmpeg的工作原理至关重要。下面将详细阐述标题和描述中涉及的几个关键函数及其内部逻辑。 首先,`main()`函数是任何...

    FFMPEG结构和函数介绍

    在FFmpeg中,理解和运用关键函数对于实现媒体处理任务至关重要。下面我们将详细讨论标题和描述中提到的一些关键知识点。 1. **avcodec_init()** `avcodec_init()` 是 FFmpeg 中用于初始化 libavcodec 子库的函数。...

    ffmpeg案例2

    1. **创建JNI接口**:定义Java层的接口,这些接口将映射到C/C++的FFmpeg函数。 2. **编写C/C++代码**:实现JNI接口,直接调用FFmpeg库的函数,如`av_protocol_get_list`、`avformat_query_codec`等,获取协议、编...

    ffmpeg框架函数分析

    ffmpeg调用编解码器的流程函数,详细介绍ffmpeg中解码部分涉及函数,编码部分涉及的函数。

    ffmpeg回调函数方式解码H264文件+VFW播放视频

    在本项目中,我们关注的是如何利用FFmpeg库以回调函数的方式解码H264编码的视频流,并通过Video for Windows (VFW) API来播放解码后的视频。 首先,我们需要理解H264编码。H264,也称为AVC(Advanced Video Coding...

    FFMPEG 函数中文说明附解压H264全过程很详细

    虽然 FFmpeg 并不直接与 MFC 相关,但开发者可以使用 MFC 封装 FFmpeg 函数,创建用户界面,以在 Windows 环境下集成 FFmpeg 功能。 C++ 是 FFmpeg 库的主要编程语言,其 API 设计为 C 风格,易于跨平台使用。通过 ...

    基于ffmpeg的封装成MP4文件源代码

    2. **注册所有组件**:通过调用`av_register_all()`函数,确保FFmpeg的所有编解码器、容器格式等都被注册,这样FFmpeg才能识别并处理各种不同的格式。 3. **打开输入流**:如果原始数据来自其他文件,你需要打开...

    FFmpeg使用手册(FFmpeg官方文档中文翻译)

    FFmpeg是一款强大的开源多媒体处理工具,它包含了音视频编解码、转换、流媒体处理等多种功能。本手册基于FFmpeg的官方文档进行了中文翻译,旨在帮助中国用户更好地理解和使用这个工具。 1. FFmpeg基本概念: - ...

    FFmpeg SDK的数据结构与API函数详解

    以下是对FFmpeg SDK中核心数据结构和API函数的详细解释。 **1. 数据结构** 在FFmpeg中,关键的数据结构包括: - **AVFormatContext**: 这是FFmpeg中的核心上下文结构,用于存储有关媒体文件的整体信息,如文件...

    ffmpeg命令手册及例程(官网)-2021.pdf

    ffmpeg 命令手册及例程(官网)-2021 ffmpeg 是一个功能强大且快速的视频和音频转换器,可以从直播音视频源抓取视频和音频,也可以在高质量的多相位滤波器中实时调整视频大小和采样率。ffmpeg 可以从多个输入文件...

    ffmpeg回调函数方式解码本地文件+SDL播放视频

    标题“ffmpeg回调函数方式解码本地文件+SDL播放视频”指出,这个项目或教程主要涉及如何使用FFmpeg解码本地视频文件,并通过SDL进行播放,而且采用的是回调函数的方式。回调函数是一种设计模式,在这里它用于处理...

    FFmpeg_11_视频流自定义分辨率播放

    5. **播放视频**:在 VC2010 环境下,可以利用 FFmpeg 的 `avpkt` 结构体和 `av_write_frame` 函数将编码后的帧写入输出文件。如果需要实时播放,可以构建一个简单的播放器,例如使用 `SDL` 或 `SFML` 图形库将编码...

    演示C#如何调用ffmpeg API_FFmpeg.AutoGen_ffmpeg

    FFmpeg.AutoGen提供了大量的结构体、枚举和函数,以C#的形式封装了FFmpeg的API。例如,`AVFormatContext`代表媒体容器,`AVCodecContext`代表编码或解码上下文,`AVPacket`用于传输音视频数据。 3. **初始化FFmpeg...

    FFmpeg视频解码器(雷霄骅课堂PPT)

    标题“FFmpeg视频解码器(雷霄骅课堂PPT)”指出了本次课程的核心内容是介绍FFmpeg视频解码器的使用与开发环境搭建。雷霄骅可能是课程讲师或者作者的名字,同时也是本课程PPT资源的提供者。由于内容涉及视频解码器,...

Global site tag (gtag.js) - Google Analytics