// Turtorial1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
extern "C"
{
#include"libavcodec\avcodec.h"
#include"libavformat\avformat.h"
#include "libswscale\swscale.h"
#include"sdl\SDL.h"
}
int _tmain(int argc, _TCHAR* argv[])
{
av_register_all();
AVFormatContext *pFormatCtx=NULL;
char *pVideoFile="e:\\测试片源\\1.avi";
// Open video fil
if(avformat_open_input(&pFormatCtx, pVideoFile, NULL, 0)!=0)
return -1; // Couldn't open file
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
return -1; // Couldn't find stream information
int i,videoStream;
AVCodecContext *pCodecCtx;
// Find the first video stream
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoStream=i;
break;
}
if(videoStream==-1)
return -1; // Didn't find a video stream
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
AVCodec *pCodec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
fprintf(stderr, "Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
return -1; // Could not open codec
AVFrame *pFrame,*pFrameRGB;
// Allocate video frame
pFrame=avcodec_alloc_frame();
// Allocate an AVFrame structure
pFrameRGB=avcodec_alloc_frame();
if(pFrameRGB==NULL)
return -1;
uint8_t *buffer;
int numBytes;
// Determine required buffer size and allocate buffer
//numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
// pCodecCtx->height);
numBytes=avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width,pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_YUV420P,
pCodecCtx->width, pCodecCtx->height);
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( "Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
SDL_Surface *screen;
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
if(!screen)
{
printf("SDL: could not set video mode - exiting\n");
return -1;
}
int frameFinished;
AVPacket packet;
SDL_Overlay *bmp;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,SDL_YV12_OVERLAY, screen);
SDL_Rect rect;
i=0;
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);
while(av_read_frame(pFormatCtx, &packet)>=0)
{
// Is this a packet from the video stream?
if(packet.stream_index==videoStream)
{
// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
&packet);
// Did we get a video frame?
if(frameFinished)
{
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
SDL_LockYUVOverlay(bmp);
bmp->pixels[0]=pFrameRGB->data[0];
bmp->pixels[2]=pFrameRGB->data[1];
bmp->pixels[1]=pFrameRGB->data[2];
bmp->pitches[0]=pFrameRGB->linesize[0];
bmp->pitches[2]=pFrameRGB->linesize[1];
bmp->pitches[1]=pFrameRGB->linesize[2];
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL_DisplayYUVOverlay(bmp, &rect);
SDL_Delay(40);
}
// Free the packet that was allocated by av_read_frame
}
av_free_packet(&packet);
}
sws_freeContext(img_convert_ctx);
delete[] buffer;
av_free(pFrameRGB);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
教程上的版本都不是最新的,在学习过程中利用最新的版本试着替换了一下,可以运行。