demuxing_decoding

1 概要

样例Demo,主要展示解复用和解码。样例Demo的时序图如下,对于重点关注的接口,我用了实线箭头来做指向。

2 av_register_all

官方给定的接口解释如下,用于注册所有的formats和codecs。
针对这个接口分析,网上的资料较多,建议直接学习这篇Blog:ffmpeg 源代码简单分析 : 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()*/
void av_register_all(void);

3 avformat_open_input

先看下官方给定的接口注释,该函数用于打开多媒体数据并且获得一些相关的信息。fmt参数不为NULL时,强制指定AVFormatContext中AVInputFormat的。样例Demo中设置成NULL,这里先从简分析下,利用av_find_input_format接口先查找指定的fmt,再用作入参提供给avformat_open_input接口。参考Blog如下:
1. 图解FFMPEG打开媒体的函数avformat_open_input
2. FFMPEG源码分析:avformat_open_input() 媒体打开函数
3. FFmpeg源代码简单分析:avformat_open_input()

/*** 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.*/
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);

这里分析的是mp4文件,所以指定的fmt是ff_mov_demuxer。由于这里指定了fmt,init_input接口内部处理变得简单多了,只剩下io_open处理。

正常情况下需要探测视频文件的格式,这个过程也比较有趣。如果感兴趣的话,可以单独拎出来看。
avformat_open_input大致的调用流程见下面的流程图:

3.1 io_open

参考Blog:FFmpeg源代码简单分析:avio_open2()

step3-5: 从代码中可以看出,ffurl_alloc()主要调用了2个函数:url_find_protocol()根据文件路径查找合适的URLProtocol,url_alloc_for_protocol()为查找到的URLProtocol创建URLContext。由于这里使用本地文件调试,所以匹配的URL是file.c。
step9: 指定read_packet和write_packet,这样就关联到protocol的url_read和url_write。
step8: 再回到ffio_fdopen(),会发现它初始化AVIOContext的结构体的时候,首先将自己分配的Buffer设置为该AVIOContext的Buffer;然后将URLContext作为用户自定义数据(对应AVIOContext的opaque变量)提供给该AVIOContext;最后分别将3个函数作为该AVIOContext的读,写,跳转函数:ffurl_read(),ffurl_write(),ffurl_seek()。

3.2 read_header

这里还是以mp4文件为例,所以read_header实际指向的是mov_read_header接口。参考内容:MPEG-4 Part 14; Elements of the H.264 Video/AAC Audio MP4 Movie.pdf。

下面内容是执行 ffplay -loglevel 56 VID_20180131_195311.mp4,读取到的header信息。需要关注的是stts和stco box,前者表示 Sample To Time映射关系,后者是Chunk Offset Table。具体的结构描述见Elements of the H.264 Video/AAC Audio MP4 Movie.pdf文档。

调用mov_read_trak接口解析trak box时,每调用一次,都会用avformat_new_stream创建一个AVStream,离开mov_read_trak接口前,nb_streams也会自增一。
read_header解析日志:(read_header读取到的内容填充到AVStream结构体内部的×priv_data变量)

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’ftyp’ parent:’root’ sz: 24 8 3705390
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] ISO: File Type Major Brand: mp42
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’moov’ parent:’root’ sz: 1915 32 3705390
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’mvhd’ parent:’moov’ sz: 108 8 1907
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] time scale = 1000
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’udta’ parent:’moov’ sz: 38 116 1907
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’[169]xyz’ parent:’udta’ sz: 30 8 30
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’meta’ parent:’moov’ sz: 121 154 1907
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’hdlr’ parent:’meta’ sz: 33 8 113
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] ctype=[0][0][0][0]
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] stype=mdta
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’keys’ parent:’meta’ sz: 43 41 113
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’ilst’ parent:’meta’ sz: 37 84 113
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’[0][0][0][1]’ parent:’ilst’ sz: 29 8 29
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’trak’ parent:’moov’ sz: 821 275 1907
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’tkhd’ parent:’trak’ sz: 92 8 813
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’mdia’ parent:’trak’ sz: 721 100 813
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’mdhd’ parent:’mdia’ sz: 32 8 713
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’hdlr’ parent:’mdia’ sz: 44 40 713
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] ctype=[0][0][0][0]
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] stype=vide
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’minf’ parent:’mdia’ sz: 637 84 713
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’vmhd’ parent:’minf’ sz: 20 8 629
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’dinf’ parent:’minf’ sz: 36 28 629
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’dref’ parent:’dinf’ sz: 28 8 28
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] Unknown dref type 0x206c7275 size 12
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stbl’ parent:’minf’ sz: 573 64 629
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stsd’ parent:’stbl’ sz: 177 8 565
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] size=161 4CC=avc1 codec_type=0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’avcC’ parent:’stsd’ sz: 40 8 75
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’pasp’ parent:’stsd’ sz: 16 48 75
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’colr’ parent:’stsd’ sz: 19 64 75
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] nclx: pri 1 trc 1 matrix 1 full 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stts’ parent:’stbl’ sz: 144 185 565
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] track[0].stts.entries = 16
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] sample_count=1, sample_duration=7172
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] sample_count=2, sample_duration=5397
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] sample_count=4, sample_duration=6303

……
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stss’ parent:’stbl’ sz: 24 329 565
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] keyframe_count = 2
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stsz’ parent:’stbl’ sz: 156 353 565
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] sample_size = 0 sample_count = 34
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stsc’ parent:’stbl’ sz: 40 509 565
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] track[0].stsc.entries = 2
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stco’ parent:’stbl’ sz: 24 549 565
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] AVIndex stream 0, sample 0, offset 65fc1, dts 0, size 106006, distance 0, keyframe 1
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] AVIndex stream 0, sample 1, offset 7fdd7, dts 7172, size 83091, distance 1, keyframe 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] AVIndex stream 0, sample 2, offset 9426a, dts 12569, size 97852, distance 2, keyframe 0

……
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’trak’ parent:’moov’ sz: 819 1096 1907
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’tkhd’ parent:’trak’ sz: 92 8 811
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’mdia’ parent:’trak’ sz: 719 100 811
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’mdhd’ parent:’mdia’ sz: 32 8 711
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’hdlr’ parent:’mdia’ sz: 44 40 711
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] ctype=[0][0][0][0]
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] stype=soun
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’minf’ parent:’mdia’ sz: 635 84 711
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’smhd’ parent:’minf’ sz: 16 8 627
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’dinf’ parent:’minf’ sz: 36 24 627
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’dref’ parent:’dinf’ sz: 28 8 28
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] Unknown dref type 0x206c7275 size 12
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stbl’ parent:’minf’ sz: 575 60 627
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stsd’ parent:’stbl’ sz: 91 8 567
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] size=75 4CC=mp4a codec_type=1
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] audio channels 2
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] version =0, isom =1
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’esds’ parent:’stsd’ sz: 39 8 39
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] MPEG-4 description: tag=0x03 len=25
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] MPEG-4 description: tag=0x04 len=17
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] esds object type id 0x40
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] MPEG-4 description: tag=0x05 len=2
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] Specific MPEG-4 header len=2
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] mp4a config channels 2 obj 2 ext obj 0 sample rate 48000 ext sample rate 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stts’ parent:’stbl’ sz: 32 99 567
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] track[1].stts.entries = 2
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] sample_count=1, sample_duration=1024
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] sample_count=89, sample_duration=1024
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stsz’ parent:’stbl’ sz: 380 131 567
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] sample_size = 0 sample_count = 90
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stsc’ parent:’stbl’ sz: 40 511 567
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] track[1].stsc.entries = 2
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’stco’ parent:’stbl’ sz: 24 551 567
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] AVIndex stream 1, sample 0, offset 62ec1, dts 0, size 256, distance 0, keyframe 1
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] AVIndex stream 1, sample 1, offset 62fc1, dts 1024, size 256, distance 0, keyframe 1
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] AVIndex stream 1, sample 2, offset 630c1, dts 2048, size 256, distance 0, keyframe 1
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] AVIndex stream 1, sample 3, offset 631c1, dts 3072, size 256, distance 0, keyframe 1

……
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’free’ parent:’root’ sz: 403238 1947 3705390
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f3b40000920] type:’mdat’ parent:’root’ sz: 3300213 405185 3705390

4 avformat_find_stream_info

依旧看下官方的接口注释,该接口从文件中读取部分音视频数据 用于获取相关信息。参考Blog:FFmpeg源代码简单分析:avformat_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* @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.*/
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

5 avcodec_find_decoder

依旧看下官方的接口注释,很直白就是查找FFmpeg的解码器。它有个类似接口avcodec_find_decoder_by_name(通过name来查找,而上面那个是通过codec_id来查找)。参考Blog:FFmpeg源代码简单分析:av_find_decoder()和av_find_encoder()

/*** 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.*/
AVCodec *avcodec_find_decoder(enum AVCodecID id);

6 avcodec_open2

看下官方的接口注释,avcodec_open2调用至少需要传参两个(codec和context)。该接口用传入的codec来初始化context,拿h264解码来讲,还会解析SPS和PPS来填充context。参考Blog:FFmpeg源代码简单分析: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()).** @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);

7 av_dump_format

接口注解中描述该接口就是用于打印context中的format信息,包括duration,bitrate,streams,conttariner,programs,metadta,side data,codec和time base。

/*** Print detailed information about the input or output format, such as* duration, bitrate, streams, container, programs, metadata, side data,* codec and time base.** @param ic        the context to analyze* @param index     index of the stream to dump information about* @param url       the URL to print, such as source or destination file* @param is_output Select whether the specified context is an input(0) or output(1)*/
void av_dump_format(AVFormatContext *ic, int index,const char *url,int is_output);

下面的信息就是av_dump_format接口打印的,使用 ffplay -hide_banner -i VID_20180131_195311.mp4指令来进行演示。

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from ‘VID_20180131_195311.mp4’:
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2018-01-31T11:53:15.000000Z
location : +31.9674+118.7412/
location-eng : +31.9674+118.7412/
com.android.version: 7.1.2
Duration: 00:00:01.92, start: 0.000000, bitrate: 15439 kb/s
Stream #0:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuvj420p(pc, smpte170m), 1280x720, 13724 kb/s, SAR 1:1 DAR 16:9, 17.80 fps, 90k tbr, 90k tbn, 180k tbc (default)
Metadata:
creation_time : 2018-01-31T11:53:15.000000Z
handler_name : VideoHandle
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 96 kb/s (default)
Metadata:
creation_time : 2018-01-31T11:53:15.000000Z
handler_name : SoundHandle

8 av_read_frame

接口描述:该接口的作用是读取码流中的音频若干帧或者视频一帧。参考Blog:ffmpeg 源代码简单分析 : 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.** 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);

av_read_frame的函数调用大致如下:

9 avcodec_decode_video2

简单的来说这个接口的功能是解码AVPacket中的数据,然后输出到AVFrame结构体中。注解中建议使用avcodec_send_packet和avcodec_receive_frame接口。参考Blog:ffmpeg 源代码简单分析 : avcodec_decode_video2()

avcodec_decode_video2接口实现和try_decode_frame类似,关键点都是调用avcodec_send_packet和avcodec_receive_frame来配合。

/*** 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 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 The end of the input buffer buf should be set to 0 to ensure that* no overreading happens for damaged MPEG streams.** @note Codecs which have the AV_CODEC_CAP_DELAY capability set 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.** @note The AVCodecContext MUST have been opened with @ref avcodec_open2()* before packets may be fed to the decoder.** @param avctx the codec context* @param[out] picture The AVFrame in which the decoded video frame will be stored.*             Use av_frame_alloc() to get an AVFrame. The codec will*             allocate memory for the actual bitmap by calling the*             AVCodecContext.get_buffer2() callback.*             When AVCodecContext.refcounted_frames is set to 1, the frame is*             reference counted and the returned reference belongs to the*             caller. The caller must release the frame using av_frame_unref()*             when the frame is no longer needed. The caller may safely write*             to the frame if av_frame_is_writable() returns 1.*             When AVCodecContext.refcounted_frames is set to 0, the returned*             reference belongs to the decoder and is valid only until the*             next call to this function or until closing or flushing the*             decoder. The caller may not write to it.** @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.** @deprecated Use avcodec_send_packet() and avcodec_receive_frame().*/
attribute_deprecated
int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,int *got_picture_ptr,const AVPacket *avpkt);

ffmpeg examples -- demuxing_decoding相关推荐

  1. Linux网络驱动架构

    转载来自:https://blog.csdn.net/zhoudengqing/article/details/47406821 转 Linux网络驱动架构 2015年08月10日 22:54:39 ...

  2. [ffmpeg]安装

    下载源码: 我们选择去官网http://ffmpeg.org下载.版本和打包方式譬如:ffmpeg-3.1.11.tar.bz2 安装过程: tar   -jxvf ./ffmpeg-3.1.11.t ...

  3. Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能

    文章目录 前言 一.开发部署环境 二.安装前的相关包下载及环境准备 1. Qt交叉编译环境搭建 2.安装环境所需依赖包 3. 交叉编译OpenCV所需x264.FFmpeg等依赖库 3.1 nasm编 ...

  4. FFmpeg再学习 -- FFmpeg解码知识

    继续看雷霄骅的 课程资料 - 基于FFmpeg+SDL的视频播放器的制作 前面用了五个篇幅来讲 FFmpeg,其主要目的是为实现将图片转视频的功能. 总的来说,对于 FFmepg 多少有一些了解了.但 ...

  5. FFMPEG 图像拉伸缩放及数据格式转换

    在做摄像头数据采集处理的时候,经常会遇到摄像头输入数据格式的不同,导致编码的时候需要再进行一次数据装换.在X264的编码中,是需要将YUV的Y,U,V 三个分量的数据独立出来.遇到一些YUV交叉分布的 ...

  6. 基于FFmpeg的视频播放器之十六:完结

    学习FFmpeg个人认为是不需要买书的,只需利用好下面四种资源 1.优秀的博客,比如雷神的博客:https://blog.csdn.net/leixiaohua1020 2.FFmppeg的exanm ...

  7. QT开发用ffmpeg将图片制作成视频

    继上一博文:QT打开图片文件夹快速播放图片现在要将图片做成视频 1,第一种方式:cmd 的调用:因为什么都不懂,刚开始是想用命令行来做,在cmd下用命令能合成比较模糊的视频了 因输入文件的方式有两种调 ...

  8. 基于FFMpeg实现音频mp3/aac/wav解码

    编译环境:Ubuntu16.04 64位 交叉编译工具:arm-himix200-linux-gcc 文章目录 1. ffmpeg源码下载 2. 交叉编译 3. 静态库链接 4. 头文件包含 5. 解 ...

  9. ffmpeg command manual

    ffmpeg 命令 文章目录 ffmpeg 命令 manual DESCRIPTION DETAILED DESCRIPTION Filtering Stream copy STREAM SELECT ...

最新文章

  1. java 继承接口语法_java的继承、接口方面的语法及知识
  2. 高性能服务器架构思路「不仅是思路」
  3. 最短路径 - 迪杰斯特拉(Dijkstra)算法
  4. 全国计算机等级考试题库二级C操作题100套(第52套)
  5. windows 禁用ipv6服务_在 Windows 7 中禁用IPv6协议/IPv6隧道
  6. 程序无法启动ALL_BUILD 拒绝访问
  7. acer软件保护卡清除工具clear_如何清除 APT 缓存来回收宝贵的磁盘空间 | Linux 中国...
  8. 从C语言中的指针看C#中委托
  9. install pymssql on centos
  10. android中Intent的一些用法和总结
  11. ubuntu如何完全卸载和安装 Java及android环境
  12. 程序 卡塔_建筑钉卡塔
  13. 2011浙江省公务员考试申论大作文的写作
  14. flex子项常见属性 跟携程网首页案例制作。
  15. oracle中时间大小比较函数,Oracle比较时间大小
  16. 中断工作原理在现代计算机中的应用,中断、DMA、通道
  17. 剧本杀APP发展如何——“我是谜”竞品分析
  18. 于繁华中寻觅一份淡然(街灯上的藤蔓)
  19. 中国成全球最大工业机器人市场 年增长速度25%
  20. NR PRACH(三)时域位置

热门文章

  1. 十年测试老鸟聊聊移动端兼容性测试
  2. Top-down Visual Saliency Guided by Captions阅读笔记
  3. OculusClient登录错误“发生意外错误,请稍后重试(OVR40779122)”解决方法
  4. 计算机开机出现ROM,电脑无法开机并显示EXITING INTEL PXE ROM如何解决
  5. 1024程序员节:向改变世界的程序员致敬
  6. STM32贪吃蛇实现
  7. STM32汇编语言点亮led灯
  8. python亲和性分析_数据挖掘入门系列教程(一)之亲和性分析
  9. 分布式架构、大数据、机器学习、搜索、推荐、广告
  10. 超强指南!1分钟学会给电脑磁盘分区!