ffmpeg学习(2)--An ffmpeg and SDL Tutorial

来源:互联网 发布:黑客与画家知乎 编辑:程序博客网 时间:2024/05/17 09:04
ffmpeg学习(2)--An ffmpeg and SDL Tutorial

安装好ffmpeg后,就开始学习如何应用了,主要也就是熟悉一些常用API。
同事推荐了一个ffmpeg的自学教程--An ffmpeg and SDL Tutorial,觉得不错,就开始照敲代码了。这个教程的网址为:http://dranger.com/ffmpeg/tutorial01.html

学习过程中敲的代码及编译makefile文件 ,已上传至http://download.csdn.net/detail/gavinr/3798699


1.教程中的内容
教程中提供8个例程:
Tutorial 01: Making Screencaps 读取一个文件解码,并保存成*.ppm格式的图片,*.ppm其实就是RGB数据添加一个简单的文件头(一个魔数、宽、高等)组成。
Tutorial 02: Outputting to the Screen 主要是在Tutorial 01基础上,将解码后的图像通过SDL输出到屏幕,
Tutorial 03: Playing Sound 增加了SDL播放声音
Tutorial 04: Spawning Threads 调整程序结构,使用了多线程机制,方便后续扩展
Tutorial 05: Synching Video 音频同步
Tutorial 06: Synching Audio 视频同步
Tutorial 07: Seeking 定位
Tutorial 08: Software Scaling 使用libswscale库进行,图像的格式转换及缩放操作
每个例程都是在前一个的基础上完成的,所以需要从第一个看起。不过有一个例外,Tutorial 08最好提前看。前面的例子中图像格式转换时,均使用了img_convert函数,但是在新版本的ffmpeg中已经不再支持,必需使用例程8讲述的方式。

2.SDL的作用
SDL是一个跨平台媒体库,似乎在游戏编程中有大量应用,例中大量使用了SDL中的函数,主要用到其以下功能:
1)视频渲染
2)音频播放
3)事件机制,可以响应键盘及自定义事件
4)线程机制,SDL提供了线程创建函数,及线程同步机制

3.编译例程遇到的问题
前5个例程,偶都敲进去编译运行了一下,遇到的问题不算太多,主要修改几个已经不再支持的宏及函数调用,主要有以下几个地方
1).宏CODEC_TYPE_VIDEO需要改为AVMEDIA_TYPE_VIDEO

2).音频解码函数

            /*              len1 = avcodec_decode_audio2(aCodecCtx, (int16_t *) audio_buf, &data_size, audio_pkt_data,             audio_pkt_size);             */            len1 = avcodec_decode_audio3(aCodecCtx, (int16_t *) audio_buf,                    &data_size, &pkt);

3).视频解码函数

            /*             avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size);             */            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

4).图像格式转换,就是Tutorial 08中提到的

 /*                 *此函数已经不用                 img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);                 */   static struct SwsContext *img_convert_ctx;...    // Convert the image into YUV format that SDL uses    if(img_convert_ctx == NULL) {      int w = is->video_st->codec->width;      int h = is->video_st->codec->height;      img_convert_ctx = sws_getContext(w, h,                         is->video_st->codec->pix_fmt,                         w, h, dst_pix_fmt, SWS_BICUBIC,                         NULL, NULL, NULL);      if(img_convert_ctx == NULL) {fprintf(stderr, "Cannot initialize the conversion context!\n");exit(1);      }    }    sws_scale(img_convert_ctx, pFrame->data,               pFrame->linesize, 0,               is->video_st->codec->height,               pict.data, pict.linesize);

4.其它一些问题

1) 编译的程序播放音频时,会比较卡,这应该是代码本身的问题。例程中的音频解码,是在回调函数中进行的,这浪费了一定的时间,如果将解码过程放到其它线程中,应该能解决这个问题。

2)关于音视频同步这块也是就tutorial 05与tutorial06的内容还没有完全弄清楚


原创粉丝点击