音视频处理-ffmpeg+sdl视频播放

本文介绍了使用FFmpeg实现简易播放器的过程,包括播放器的主要流程:初始化、解码及渲染等关键步骤,并针对每一步提供了详细的解释。此外,还对比了与原作者代码的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题记:感谢雷博的开源ffmpeg播放器,了解到了视频的解码/播放知识。在学习过程中,感觉雷博的代码写的比较随意,对整个流程的讲解也比较少,更偏向于原理性的东西,并且主要是在windows下验证。在学习过程中,觉得比较难以吸收。所以我在linux下重写了播放器的代码,希望能对ffmpeg有进一步的学习。
组织后的代码:
git@github.com:z-chenxin/simplest_player.git
git源码仅供参考 源代码从雷博的blog参考而来,并作了一定的修改。原播放器bloghttp://blog.youkuaiyun.com/leixiaohua1020/article/details/38868499

播放器播放流程/架构:ffmpeg部分
1、av_register_all(); 初始化ffmpeg,且只会被调用一次

void av_register_all(void)
{
    static int initialized;

    if (initialized)
        return;

    avcodec_register_all();

很明显,除非实在进程中重复调用av_register_all 否则这个api只会被调用一次。

2、avformat_open_input(); 解析文件的header 获取文件信息

3、av_find_stream_info(); 尝试读取文件的部分帧获取信息
avformat_open_input 和 av_find_stream_info 这两个API的作用概括一下就是获取文件信息,不理解其中某一个的具体作用也无伤大雅。参见另一篇blog tinyjpeg的解码流程,就可以明白http://blog.youkuaiyun.com/qq_21358401/article/details/52952161

4、avcodec_find_decoder(); 根据获得的信息寻找解码器

5、avcodec_open(); 打开解码器
播放264、265格式视频的时候可能会失败,因为h264和h265的库在编译ffmpeg的时候一般没有包含。需要单独引入

6、av_read_frame();
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
从av_read_frame的原型可以看出,api的作用是读取一帧压缩格式的数据。
AVPAcket和AVFrame的区别就在于AVPacket对应压缩格式比如jpeg数据,AVFrame对应非压缩格式如YUV420P数据

7、av_image_fill_arrays();将具体的图像buffer同AVFrame联系起来

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
    /**
     * pointer to the picture/channel planes.
     * This might be different from the first allocated byte
     *
     * Some decoders access areas outside 0,0 - width,height, please
     * see avcodec_align_dimensions2(). Some filters and swscale can read
     * up to 16 bytes beyond the planes, if these filters are to be used,
     * then 16 extra bytes must be allocated.
     *
     * NOTE: Except for hwaccel formats, pointers not needed by the format
     * MUST be set to NULL.
     */
    uint8_t *data[AV_NUM_DATA_POINTERS];
截取AVFrame的部分 可以看出AVFrame中的数据存储使用的是一个指针数组,并没有实际指向的buffer。指针数组中的每一个指针都指向一块buffer,比如data[0]可以对应YUV420P的Y等等
而把AVFrame的data同buffer对应起来就是av_image_fill_arrays的工作,在ffmpeg中类似的API还有av_picture_fill 
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
                   enum AVPixelFormat pix_fmt, int width, int height)
{
    return av_image_fill_arrays(picture->data, picture->linesize,
                                ptr, pix_fmt, width, height, 1);
}
也就是av_image_fill_arrays的简单封装。

8、sws_getContext();获取格式转换容器

9、sws_scale();  根据格式转换容器 转换图像

10、avcodec_decode_video2();解码

SDL部分:
什么是SDL?安装/移植?参见我的另一blog音视频处理-SDL http://blog.youkuaiyun.com/qq_21358401/article/details/53003276

1、SDL_CreateWindow();创建窗体

2、SDL_CreateRenderer(); 创建渲染器

3、SDL_CreateTexture(); 创建纹理
纹理和渲染器的概念参见http://blog.youkuaiyun.com/yinhaijing123/article/details/46446017

4、SDL_RenderClear(); 清除渲染器内容

5、SDL_RenderCopy();拷贝渲染内容到纹理

6、SDL_RenderPresent(); 显示渲染内容

7、SDL_UpdateYUVTexture(); 更新YUV纹理

//先到这 明天写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值