编解码所涉及到的函数

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);

猜你喜欢

转载自blog.csdn.net/weixin_34380296/article/details/87384021