- 解封装
- 软硬解码
- 像素格式转换
- 重采样
- pts/dts
- 同步策略
avcodec_find_decoder
avcodec_register_all(); // 注册所有的解码器
AVCodec *avcodec_find_decoder(enum AVCodecID id)
AVCodec 只是存放了解码器格式的配置信息
AVCodec *avcodec_find_decoder_by_name(const char *name)
avcodec_find_decoder_by_name("h264_mediacodec") // 用Android里面自带的解码模块,ARM CPU是一个集合,里面自带一个解码模块,其实就是调用了Android里面的java接口
AVCodecContext
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) // 可以不传解码器,只是创建的解码器上下文里面会没有解码器
void avcodec_free_context(AVCodecContext **avctx)
// 打开
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); // 如果AVCodecContext里面已经有解码器,就不需要传codec,options:参考/libavcodec/options_table.h
int thread_count; // 多线程
time_base // 时间的基数
avcodec_parameters_to_context
将codec的参数拷贝到context
avcodec_parameters_to_context(codec, p);
AVFrame
AVFrame *frame = av_frame_alloc();
void av_frame_free(AVFrame **frame);// 引用计数减一,并释放本身
int av_frame_ref(AVFrame *dst, const AVFrame *src); // 引用计数加一
AVFrame *av_frame_clone(const AVFrame *src); // 复制,并引用计数加一
void av_frame_unref(AVFrame *frame); // 直接引用计数减一
成员:
uint8_t *data[AV_NUM_DATA_POINTERS] // 可能是交叉模式或平面模式
int linesize[AV_NUM_DATA_POINTERS] // 视频表示一行数据大小,音频表示一个通道数据大小
int width;
int height;
int nb_samples; // 音频,表示单通道样本数量,一般1024
int64_t pts;
int64_t pkt_dts;
int sample_rate;
uint64_t channel_layout;
int channels;
int format; // AVPixelFormat AVSampleFormat
linesize
平面模式(因为有对齐的原因):
0 | Y大小 |
1 | U大小 |
2 | V大小 |
3 | NULL |
0 | 左声道(planner)大小 |
1 | 右声道大小 |
2 | NULL |
0 | RGB RGB RGB大小 |
1 | NULL |
avcodec_send_packet
int avcodec_send_packet(
AVCodecContext *avctx,
const AVPacket *avpkt);
// 调用完这个函数后,可以安全的释放avpkt,因为内部已经缓存了一个AVPacket空间
avcodec_receive_frame
int avcodec_receive_frame(
AVCodecContext *avctx,
AVFrame *frame);
可能前面几帧解不出来,获取的这一帧可能是之前的,怎么取出结尾中的几帧,也可能取到多个