An ffmpeg and SDL Tutorial在ffmpeg-1.0.1上的更新,tutorial02

 

 
An ffmpeg and SDL Tutorial ffmpeg-1.0.1 上的更新
 
Tutorial02
http://cutebunny.blog.51cto.com/301216/1150226
本篇和 Tutorial01 的主流程差别不大,只是将 ’DO SOMETHING WITH frame’ 从将前 5 帧保存为 PPM 文件改为以最快的解码速度将得到的帧播放出来。代码也相当简单,我们直接进入更新。
 
 
更新
Line19, 20
#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>
改为
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
详见 Tutorial01
 
Line32
AVFormatContext *pFormatCtx;
改为
AVFormatContext *pFormatCtx = NULL;
详见 Tutorial01
 
Line59
if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
    return -1; // Couldn't open file
改为
if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
    return -1; // Couldn't open file
详见 Tutorial01
 
Line67
dump_format(pFormatCtx, 0, argv[1], 0);
改为
av_dump_format(pFormatCtx, 0, argv[1], 0);
详见 Tutorial01
 
Line72
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
改为
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
详见 Tutorial01
 
Line120
avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
              packet.data, packet.size);
改为
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
              &packet);
详见 Tutorial01
 
Line137
img_convert(&pict, PIX_FMT_YUV420P,
                    (AVPicture *)pFrame, pCodecCtx->pix_fmt,
                  pCodecCtx->width, pCodecCtx->height);
改为
static struct SwsContext *img_convert_ctx;
    img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
    sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pict.data, pict.linesize);
详见 Tutorial01
 
好了,更新到此为止了。可以看到 Tutorial02 所作的修改和 Tutorial01 一模一样 ( 当然除了行号 ) ,这是因为 SDL 库的 API 是那么的一如既往,没什么太大差异。不知道 Dranger 大神 SDL 用的什么版本,我调试用的 1.2.15 ,目前应该还是最新版,而且 Sample 代码不需要针对 SDL 做任何更新。我就喜欢这种专一。
开始编译吧,以下是我的编译脚本,加入了 SDL 库,还是注意一下修改路径。同样,源代码可以从附件中下载。
 
#!/bin/sh
 
FFMPEG_ROOT="ffmpeg-1.0.1"
SDL_ROOT="SDL-1.2.15"
 
gcc $1 -g -o sample -I../$FFMPEG_ROOT \
-L../$FFMPEG_ROOT/libavformat -L../$FFMPEG_ROOT/libavcodec -L../$FFMPEG_ROOT/libavutil -L../$FFMPEG_ROOT/libswscale \
-lavformat -lavcodec -lswscale -lavutil -lz -lbz2 -lm -lpthread \
-I../$SDL_ROOT/include -D_GNU_SOURCE=1 -D_REENTRANT \
-L../$SDL_ROOT/build/.libs -Wl,-rpath,../$SDL_ROOT/build/.libs -lSDL –lpthread
 
这里我没有使用原文中采用的 sdl-config --cflags –libs, 而是手动指定路径和编译选项,确保使用的是我最新的 SDL 库。
 
 
解释
Q:
Line127 AVPicture pict;
为什么这里的 pict 没有像 Tutorial01 中的 pFrameRGB 去手动分配空间?
A:
因为 pict data linesize 已经指向了 SDL_Overlay  *bmp 的空间,随后在 sws_scale() 中对 pict 的操作实际上是对 bmp 在进行操作。
 
Q:
SDL_PollEvent(&event);
    switch(event.type) {
    case SDL_QUIT:
      SDL_Quit();
……
这个事件系统是做什么的?有什么作用?
A:
本篇中作用不大,但千万别小看了它。后面的多线程以及音视频同步都是以它为基础。
 
 
疑问
Q:
Line108
// Allocate a place to put our YUV image on that screen
 bmp = SDL_CreateYUVOverlay(pCodecCtx->width,
                             pCodecCtx->height,
                             SDL_YV12_OVERLAY,
                             screen);
创建了 YV12 类型的 overlay ,可是在最后的
Line147
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
却创建了 PIX_FMT_YUV420P 类型的 img_convert_ctx
是否前后不匹配呢?还望知情者解答。
 
最后还是根据 Tutorial02 给出一个 ffmpeg+SDL 视频解码播放的简单流程。
 

   

本文出自 “bunny技术坊” 博客,转载请与作者联系!

你可能感兴趣的:(注解,更新,ffmpeg,tutorial,1.0.1)