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

 

 
An ffmpeg and SDL Tutorialffmpeg-1.0.1上的更新
 
Tutorial02
本篇和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:
因为pictdatalinesize已经指向了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视频解码播放的简单流程。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章