ffmpeg函数

1
int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
int *got_picture_ptr,
const AVPacket *avpkt);

作用:

是解码一帧视频数据。输入一个压缩编码的结构体AVPacket,输出一个解码后的结构体AVFrame。

int *got_picture_ptr :如果没有可以解压缩的帧,则为零,否则为非零。
ffmpeg 源代码简单分析 : avcodec_decode_video2()
2

SwsContext 三兄弟
目的:
想將某個PixelFormat轉換至另一個PixelFormat,例如,將YUV420P轉換成YUYV422,或是想變換圖的大小。
可以完成图片像素格式的转换, 图片的拉伸等工作
ffmpeg-struct SwsContext使用心得

3
avcodec_send_frame
用于将 AVFrame 结构体所封装的图像数据传入codec
avcodec_receive_packet
获取输出的码流,并保存在传入的AVpacket结构中。
avcodec_send_packet
用于将 AVpacket结构体所封装的二进制流传入解码器
avcode_receive_frame
可以从解码器中获取解码输出的图像帧结构

4
av_read_frame 读取完整帧

关于如何实现完整帧的?

这个看对应解复用器的实现,比如ff_flv_demuxer的 flv_read_packet, 是根据封装格式来的。

5
avformat_open_input
注意申请 Context 的空间
ic = avformat_alloc_context(); //分配 avformatcontext

可参考
avformat_open_input()

6
avformat_find_stream_Info
avformat_find_stream_Info

7
stream_component_open
stream_component_open函数分析

8
**int av_interleaved_write_frame(AVFormatContext s, AVPacket pkt);
说明:
将数据包写⼊输出媒体⽂件,并确保正确的交织(保持packet dts的增⻓性)。
该函数会在内部根据需要缓存packet,以确保输出⽂件中的packet按dts递增的顺序正确交织。如果⾃⼰
进⾏交织则应调⽤av_write_frame()。
参数:
s 媒体⽂件句柄
pkt
要写⼊的packet。
如果packet使⽤引⽤参考计数的内存⽅式,则此函数将获取此引⽤权(可以理解为
move了reference),并在内部在合适的时候进⾏释放。此函数返回后,调⽤者不得
通过此引⽤访问数据。如果packet没有引⽤计数,libavformat将进⾏复制。
此参数可以为NULL(在任何时候,不仅在结尾),以刷新交织队列。
Packet的stream_index字段必须设置为s-> streams中相应流的索引。
时间戳记(pts,dts)必须设置为stream’s timebase中的正确值(除⾮输出格式⽤
AVFMT_NOTIMESTAMPS标志标记,然后可以将其设置为AV_NOPTS_VALUE)。
同⼀stream后续packet的dts必须严格递增(除⾮输出格式⽤
AVFMT_TS_NONSTRICT标记,则它们只必须不减少)。duration也应设置(如果已
知)。
返回值:
成功时为0,错误时为负AVERROR。即使此函数调⽤失败,Libavformat仍将始终释放该
packet。

9
av_compare_ts

int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b);
返回值:
-1 ts_a 在ts_b之前
1 ts_a 在ts_b之后
0 ts_a 在ts_b同⼀位置
⽤伪代码:return ts_a == ts_b ? 0 : ts_a < ts_b ? -1 : 1

10
avformat_write_header

a:会更新时间基

int avformat_write_header(AVFormatContext *s, AVDictionary **options)
{
    int ret = 0;
    int already_initialized = s->internal->initialized;
    int streams_already_initialized = s->internal->streams_initialized;
    if (!already_initialized)
        if ((ret = avformat_init_output(s, options)) < 0)
            return ret;
    if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
        avio_write_marker(s->pb, AV_NOPTS_VALUE,
AVIO_DATA_MARKER_HEADER);
    if (s->oformat->write_header) {
        ret = s->oformat->write_header(s);//调用复用器接口
        if (ret >= 0 && s->pb && s->pb->error < 0)
            ret = s->pb->error;
        if (ret < 0)
            goto fail;
        flush_if_needed(s);
   }
    if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
        avio_write_marker(s->pb, AV_NOPTS_VALUE,
AVIO_DATA_MARKER_UNKNOWN);
    if (!s->internal->streams_initialized) {
        if ((ret = init_pts(s)) < 0)
            goto fail;
   }
    return streams_already_initialized;
fail:
    if (s->oformat->deinit)
        s->oformat->deinit(s);
    return ret;
}

最终调⽤到复⽤器的 write_header,⽐如

AVOutputFormat ff_flv_muxer = {
   .name           = "flv",
   .long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
   .mime_type      = "video/x-flv",
   .extensions     = "flv",
   .priv_data_size = sizeof(FLVContext),
   .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 :
AV_CODEC_ID_ADPCM_SWF,
   .video_codec    = AV_CODEC_ID_FLV1,
   .init           = flv_init,
   .write_header   = flv_write_header, // 写头部
   .write_packet   = flv_write_packet,
   .write_trailer  = flv_write_trailer, // 写⽂件尾部
   .check_bitstream= flv_check_bitstream,
   .codec_tag      = (const AVCodecTag* const []) {
                          flv_video_codec_ids, flv_audio_codec_ids, 0
                     },
   .flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
                      AVFMT_TS_NONSTRICT,
   .priv_class     = &flv_muxer_class,
  };

11
av_packet_rescale_ts
将packet中的各时间值从输入流封装格式时间基转到输出流封装格式时间基

AVStream.time_base是AVPacket中pts和dts的时间单位,输入流与输出流中time_base按如下方式确定:
对于输入流:打开输入文件后,调用avformat_find_stream_info()可获取到每个流中的time_base
对于输出流:打开输出文件后,调用avformat_write_header()可根据输出文件封装格式确定每个流的time_base并写入输出文件中

FFmpeg —— FFmpeg时间戳详解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值