ffmpeg examples -- demuxing_decoding
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相关推荐
- Linux网络驱动架构
转载来自:https://blog.csdn.net/zhoudengqing/article/details/47406821 转 Linux网络驱动架构 2015年08月10日 22:54:39 ...
- [ffmpeg]安装
下载源码: 我们选择去官网http://ffmpeg.org下载.版本和打包方式譬如:ffmpeg-3.1.11.tar.bz2 安装过程: tar -jxvf ./ffmpeg-3.1.11.t ...
- Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能
文章目录 前言 一.开发部署环境 二.安装前的相关包下载及环境准备 1. Qt交叉编译环境搭建 2.安装环境所需依赖包 3. 交叉编译OpenCV所需x264.FFmpeg等依赖库 3.1 nasm编 ...
- FFmpeg再学习 -- FFmpeg解码知识
继续看雷霄骅的 课程资料 - 基于FFmpeg+SDL的视频播放器的制作 前面用了五个篇幅来讲 FFmpeg,其主要目的是为实现将图片转视频的功能. 总的来说,对于 FFmepg 多少有一些了解了.但 ...
- FFMPEG 图像拉伸缩放及数据格式转换
在做摄像头数据采集处理的时候,经常会遇到摄像头输入数据格式的不同,导致编码的时候需要再进行一次数据装换.在X264的编码中,是需要将YUV的Y,U,V 三个分量的数据独立出来.遇到一些YUV交叉分布的 ...
- 基于FFmpeg的视频播放器之十六:完结
学习FFmpeg个人认为是不需要买书的,只需利用好下面四种资源 1.优秀的博客,比如雷神的博客:https://blog.csdn.net/leixiaohua1020 2.FFmppeg的exanm ...
- QT开发用ffmpeg将图片制作成视频
继上一博文:QT打开图片文件夹快速播放图片现在要将图片做成视频 1,第一种方式:cmd 的调用:因为什么都不懂,刚开始是想用命令行来做,在cmd下用命令能合成比较模糊的视频了 因输入文件的方式有两种调 ...
- 基于FFMpeg实现音频mp3/aac/wav解码
编译环境:Ubuntu16.04 64位 交叉编译工具:arm-himix200-linux-gcc 文章目录 1. ffmpeg源码下载 2. 交叉编译 3. 静态库链接 4. 头文件包含 5. 解 ...
- ffmpeg command manual
ffmpeg 命令 文章目录 ffmpeg 命令 manual DESCRIPTION DETAILED DESCRIPTION Filtering Stream copy STREAM SELECT ...
最新文章
- java 继承接口语法_java的继承、接口方面的语法及知识
- 高性能服务器架构思路「不仅是思路」
- 最短路径 - 迪杰斯特拉(Dijkstra)算法
- 全国计算机等级考试题库二级C操作题100套(第52套)
- windows 禁用ipv6服务_在 Windows 7 中禁用IPv6协议/IPv6隧道
- 程序无法启动ALL_BUILD 拒绝访问
- acer软件保护卡清除工具clear_如何清除 APT 缓存来回收宝贵的磁盘空间 | Linux 中国...
- 从C语言中的指针看C#中委托
- install pymssql on centos
- android中Intent的一些用法和总结
- ubuntu如何完全卸载和安装 Java及android环境
- 程序 卡塔_建筑钉卡塔
- 2011浙江省公务员考试申论大作文的写作
- flex子项常见属性 跟携程网首页案例制作。
- oracle中时间大小比较函数,Oracle比较时间大小
- 中断工作原理在现代计算机中的应用,中断、DMA、通道
- 剧本杀APP发展如何——“我是谜”竞品分析
- 于繁华中寻觅一份淡然(街灯上的藤蔓)
- 中国成全球最大工业机器人市场 年增长速度25%
- NR PRACH(三)时域位置
热门文章
- 十年测试老鸟聊聊移动端兼容性测试
- Top-down Visual Saliency Guided by Captions阅读笔记
- OculusClient登录错误“发生意外错误,请稍后重试(OVR40779122)”解决方法
- 计算机开机出现ROM,电脑无法开机并显示EXITING INTEL PXE ROM如何解决
- 1024程序员节:向改变世界的程序员致敬
- STM32贪吃蛇实现
- STM32汇编语言点亮led灯
- python亲和性分析_数据挖掘入门系列教程(一)之亲和性分析
- 分布式架构、大数据、机器学习、搜索、推荐、广告
- 超强指南!1分钟学会给电脑磁盘分区!