1. 程式人生 > 實用技巧 >An ffmpeg and SDL Tutorial在ffmpeg-1.0.1上的更新,tutorial02

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

An ffmpeg and SDL Tutorialffmpeg-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: 因為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 p_w_picpath 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視訊解碼播放的簡單流程。

轉載於:https://blog.51cto.com/cutebunny/1150226