最近学习ffmpeg的一点总结

 

花了好几天研究的下ffmpeg,不知是人太笨还是怎么了,学习效率好低,现在把总结做下记录。

ffmpeg视频编码过程:

1.设置编码器的参数

   AVCodecContext *c;

   c->codec_id = codec_id;

  对于解码输出, code_id 可以根据你的保存文件名猜测  fmt = av_guess_format(NULL, filename, NULL) ,默认为mpeg
   c->codec_type = AVMEDIA_TYPE_VIDEO;

    /* put sample parameters */
    c->bit_rate = 400000;(for example)
    c->width = width;
    c->height = height;

  还有其他参数,不一一列出,将c指向流的AVCodecContext的地址, c = st->c;

  查找编码器  codec = avcodec_find_encoder(c->codec_id);

  打开编码器  avcodec_open(c, codec);

2.对于编码拿到的当然是一张原始的图片(raw picture),图片像素格式可能是YUV420P或其它。为了下一步的编码,你可能还要把原始图片的格式改变一下(比如mpeg视频编码要求原始图像格式是YUV420p),

①struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,
                                  int dstW, int dstH, enum PixelFormat dstFormat,
                                  int flags, SwsFilter *srcFilter,
                                  SwsFilter *dstFilter, const double *param);

②int sws_scale(struct SwsContext *context, const uint8_t* const srcSlice[], const int srcStride[],
              int srcSliceY, int srcSliceH, uint8_t* const dst[], const int dstStride[]);

当然改变后的图片还是没有经过编码的(raw picture)。

 

3.接着就可以对这副图编码了

int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
                         const AVFrame *pict);

编码后的一桢是放在一个包里的,这个包里的数据就是经过编码压缩的(mpeg或者H.263之类的),这个压缩量是非常可观的,大大减少数据量,这也是ffmpeg编码的核心吧(个人认为)。返回值即包的大小

4.然后就是把这个包写入视频流中

int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);

 

对于要保存视频文件(如avi格式)什么的,要把流写入文件中,就要申请一个流

av_new_stream(oc, 0);

。。。。

 

ffmpeg视频解码过程大致逆过程:

1.查看解码器信息(不是必须,但对调试有好处)

av_find_stream_info(pFormatCtx);

ffmpeg会帮我们浏览要打开的是个视频容器(即视频文件如avi格式)的流信息

dump_format(pFormatCtx,0,argv[1],0);

抛出信息。

2.查找解码器

pCodecCtx = pFormatCtx->streams[videoStream]->codec;

pCodec = avcodec_find_decoder(pCodecCtx->codec_id);

打开解码器  avcodec_open(pCodecCtx,pCodec)

3.从视频流中读取一个包,这个包可能包含了两帧图片的边界

av_read_packet(pFormatCtx, &packet)

4. 对获取的包解码

原始数据会解码到图像帧中 

bytesDecoded=avcodec_decode_video(pCodecCtx, pFrame,
                &frameFinished, rawData, bytesRemaining);

一个包解码不一定会获得一个完整帧,所以要判断framFinished标志,该标志有上面函数返回。

继续取包解码直到获得完整帧,获得的数据会放在pFrame中。

4.将这帧图像(pframe)转化为想要的图像格式

利用上述sws_getContext,sws_scale

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值