FFmpeg之AVCodec

来源:互联网 发布:数据库建表视频百度云 编辑:程序博客网 时间:2024/06/15 07:13

花满楼原创


小白:AVCodec是什么?

花满楼:avcodec,看名字就知道代表了编码器或解码器。

小白:不会吧!我还以为是用c语言来写av代码呢。

AVCodec是ffmpeg设计上的一个结构体,用来保存编解码器的信息。

小白:都有哪些信息呢?还有,能不能直观一点让我看到具体的数值?

本文写一个简单的demo,并调试查看avcodec变量中的内容。

(1)demo代码

演示代码的目录结构是这样的:

代码目录结构

其中的ffmpeg静态库是事先编译好的(这里是macos版本),编译的办法可以参考之前的文章,之前有详细介绍过编译的环节。

moments.mp4 是试用的视频文件(mp4封装格式,之前也有介绍过哦!)。

makefile是编译脚本,当然也可以直接用gcc来编译。

小白:为什么西门吹雪还没有找我,他到底还想不想讲编译工具的使用了!

show_avcodec.c就是演示代码了,内容如下:

#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"void show_avcodec(const char* filepath) {    av_register_all();    av_log_set_level(AV_LOG_DEBUG);    AVFormatContext* formatContext = avformat_alloc_context();    int status = 0;    int success = 0;    int videostreamidx = -1;    AVCodecContext* codecContext = NULL;    status = avformat_open_input(&formatContext, filepath, NULL, NULL);    if (status == 0) {        status = avformat_find_stream_info(formatContext, NULL);        if (status >= 0) {            for (int i = 0; i < formatContext->nb_streams; i ++) {                if (formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {                    videostreamidx = i;                    break;                }            }            if (videostreamidx > -1) {                codecContext = formatContext->streams[videostreamidx]->codec;                AVCodec* codec = avcodec_find_decoder(codecContext->codec_id);                if (codec) {                    status = avcodec_open2(codecContext, codec, NULL);                    if (status == 0) {                        success = 1;                    }                }            }        }        else {            av_log(NULL, AV_LOG_DEBUG, "avformat_find_stream_info error\n");        }        avformat_close_input(&formatContext);    }    avformat_free_context(formatContext);}int main(int argc, char *argv[]){    show_avcodec("moments.mp4");    return 0;}

(2)编译与调试

makefile的内容:

exe=showavcodecsrcs=show_avcodec.c $(exe):$(srcs)    gcc -o $(exe) $(srcs) -Iffmpeg/include/ -Lffmpeg -lffmpeg -liconv -lz -gclean:    rm -f $(exe) *.o

直接执行make来编译。

这里只是简单看一下avcodec的内容,所以用gdb来调试即可:

gdb showavcodecb 25r

在断点的地方,看一下avcodec变量中的值:
avcodec的内容

(3)avcodec是什么?

编解码器的结构体,在libavcodec/avcodec.h中定义。

在这个示例中,是一个解码器。

avcodec结构中的一些变量,从名字或Ffmpeg详细的注释可以知道是什么含义。

比如name是编解码的名称,而long_name就是长的名称,等等。

在设计上,avcodec是编解码器的抽象,那么就有具体的实现。事实上,每一个编解码器都有具体的实现。

比如h264的解码器(libavcodec/h264.c):
h264解码器

比如mp3lame的编码器(libavcodec/libmp3lame.c)
mp3lame编码器

小白:也就是说,我可以直接使用这些具体的全局变量了?

花满楼:是的,是FFmpeg可以直接使用。