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視頻解碼播放的簡單流程。
 

 

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