1,void av_register_all(void);
注册了和编解码器有关的组件,还注册了复用器,解复用器,协议处理器.
2,int avformat_network_init(void);
使用网络
3,int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
Open an input stream and read the header. The codecs are not opened.读取多媒体数据文件头,根据视音频流创建相应的AVStream。
- 返回值:0-打开成功 <0打开失败
- 参数
ps:AVFormatContext fmt_ctx,传入&fmt_ctx.
filename:const char src_filename = "cuc_ieschool.flv"; 传入src_filename
fmt:可为NULL,也可为AVOutputFormat *ofmt = NULL;传入ofmt
options:NULL - 调用:avformat_open_input(&fmt_ctx, src_filename, NULL, NULL);
4,int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
此函数需要讲解,实在不懂具体做了什么
编解码器相关的函数
5,int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, AVCodec **decoder_ret, int flags);
获取音视频对应的stream_index
- 返回值:成功-流的索引 失败-<0
- 参数
ic:AVFormatContext *fmt_ctx,传入fmt_ctx
type:AVMEDIA_TYPE_VIDEO\AVMEDIA_TYPE_AUDIO
wanted_stream_nb:可为-1
related_stream:关联流,可为-1
decoder_ret:可为NULL
flags:标志,可为0,不标示 - 调用:ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
6,AVCodec *avcodec_find_decoder(enum AVCodecID id);
根据AVCodecContext结构体的codec_id获取编解码器的结构体
- 返回值:AVCodec
- 参数:AVCodec结构体的id
- 调用:AVCodec dec = avcodec_find_decoder((codec_context)->codec_id);
7,int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
打开编解码器
- 返回值:0-打开成功 <0-打开失败
- 参数:
avctx:编解码器上下文,
AVCodecContext *codec_context = NULL; AVStream *st = fmt_ctx->streams[stream_index]; codec_context = st->codec;根据AVFormatContext获取
传入codec_context
codec:传入codec_context->codec_id
options:额外配置 - 调用:AVCodec dec = avcodec_find_decoder((codec_context)->codec_id);
解码相关的函数,AVPacket、AVFrame、SwsContext
8,AVPacket, AVFrame的初始化
- AVPacket:
AVPacket packet; initPakcet(&packet);void initPakcet(AVPacket *packet){ av_init_packet(packet); packet->data = NULL; packet->size = 0; }
void av_init_packet(AVPacket *pkt);
为AVPacket结构体初始化并分配内存,而结构体的变量data和size没有初始化 - AVFrame
AVFrame* yuvFrame = NULL; inityuvframe(&yuvFrame, codec_context); void inityuvframe(AVFrame **yuvFrame, AVCodecContext* codec_context){ *yuvFrame = av_frame_alloc(); uint8_t *out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, dst_w, dst_h)); avpicture_fill((AVPicture *)(*yuvFrame), out_buffer, AV_PIX_FMT_YUV420P, dst_w, dst_h); }
AVFrame *av_frame_alloc(void);
为AVFrame结构体初始化并分配内存,而结构体的变量data没有初始化
9,int av_read_frame(AVFormatContext *s, AVPacket *pkt);
返回流的下一帧。此函数返回存储在文件中的内容,但不验证解码器是否有有效的帧。它将把文件中存储的内容拆分为帧,并为每个调用返回一个帧。它不会忽略有效帧之间的无效数据,从而为解码器提供最大可能的解码信息。
- 返回值:0 if OK, < 0 on error or end of file
- 参数:
s:AVFormatContext *fmt_ctx;传入 fmt_ctx
pkt:AVPacket packet;传入&packet - 调用:if (av_read_frame(format_context, &packet) >= 0)
10,int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt);
没看懂源码的解释
11,struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param);
- 参数 输入输出的宽,高,像素格式
flags:用作宽高变化时的处理方式 - 调用
SwsContext *sws_ctx = sws_getContext( codec_context->width, codec_context->height, codec_context->pix_fmt, dst_w, dst_h, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
12,int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
- 返回值:the height of the output slice
- 参数:
c:SwsContext上下文
srcSlice[]:frame->data(数据的来源)
srcStride[]:frame->linesize(数据的来源)
srcSliceY:从第几行开始扫描
srcSliceH:一共扫描多少行
dst[]:yuvFrame->data(数据的输出)
dstStride[]:yuvFrame->linesize(数据的输出) - 调用:
sws_scale(sws_ctx, frame->data, frame->linesize, 0, frame->height, yuvFrame->data, yuvFrame->linesize);