SDL和FFMPEG视频播放例子

SDL和FFMPEG 视频播放例子

// tutorial02.c   
// A pedagogical video player that will stream through every video frame as fast as it can.   
//   
// Code based on FFplay, Copyright (c) 2003 Fabrice Bellard,    
// and a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de)   
// Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1   
// Use   
//   
// gcc -o v_play v_play.c -lavformat -lavcodec -lz -lm `sdl-config --cflags --libs`   
// to build (assuming libavformat and libavcodec are correctly installed,    
// and assuming you have sdl-config. Please refer to SDL docs for your installation.)   
//   
// Run using   
// v_play myvideofile.mpg   
//   
// to play the video stream on your screen. 


#include <libavcodec/avcodec.h>   
#include <libavformat/avformat.h>
#include <SDL/SDL.h>   
#include <SDL/SDL_thread.h>   
  
#undef main /* Prevents SDL from overriding main() */   
  
#include <stdio.h>   
  
int main(int argc, char *argv[]) {  
  AVFormatContext *pFormatCtx;  
  int             i, videoStream;  
  AVCodecContext  *pCodecCtx;  
  AVCodec         *pCodec;  
  AVFrame         *pFrame;   
  AVPacket        packet;  
  int             frameFinished;  
  float           aspect_ratio;  
  
  SDL_Overlay     *bmp;  
  SDL_Surface     *screen;  
  SDL_Rect        rect;  
  SDL_Event       event;  
  
  if(argc < 2) {  
    fprintf(stderr, "Usage: test <file>\n");  
    exit(1);  
  }  
  // Register all formats and codecs   
  av_register_all();  
    
  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {  
    fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());  
    exit(1);  
  }  
  
  // Open video file   
  if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)  
    return -1; // Couldn't open file   
    
  // Retrieve stream information   
  if(av_find_stream_info(pFormatCtx)<0)  
    return -1; // Couldn't find stream information   
    
  // Dump information about file onto standard error   
  dump_format(pFormatCtx, 0, argv[1], 0);  
    
  // Find the first video stream   
  videoStream=-1;  
  for(i=0; i<pFormatCtx->nb_streams; i++)  
    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_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;  
    
  // 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_open(pCodecCtx, pCodec)<0)  
    return -1; // Could not open codec   
    
  // Allocate video frame   
  pFrame=avcodec_alloc_frame();  
  
  // Make a screen to put our video   
#ifndef __DARWIN__   
        screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);  
#else   
        screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0);  
#endif   
  if(!screen) {  
    fprintf(stderr, "SDL: could not set video mode - exiting\n");  
    exit(1);  
  }  
    
  // Allocate a place to put our YUV image on that screen   
  bmp = SDL_CreateYUVOverlay(pCodecCtx->width,  
                 pCodecCtx->height,  
                 SDL_YV12_OVERLAY,  
                 screen);  
  
  
  // Read frames and save first five frames to disk   
  i=0;  
  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_video(pCodecCtx, pFrame, &frameFinished,   
               packet.data, packet.size);  
        
      // Did we get a video frame?   
      if(frameFinished) {  
    SDL_LockYUVOverlay(bmp);  
  
    AVPicture pict;  
    pict.data[0] = bmp->pixels[0];  
    pict.data[1] = bmp->pixels[2];  
    pict.data[2] = bmp->pixels[1];  
  
    pict.linesize[0] = bmp->pitches[0];  
    pict.linesize[1] = bmp->pitches[2];  
    pict.linesize[2] = bmp->pitches[1];  
  
    // Convert the image into YUV format that SDL uses   
    img_convert(&pict, PIX_FMT_YUV420P,  
                    (AVPicture *)pFrame, pCodecCtx->pix_fmt,   
            pCodecCtx->width, pCodecCtx->height);  
      
    SDL_UnlockYUVOverlay(bmp);  
      
    rect.x = 0;  
    rect.y = 0;  
    rect.w = pCodecCtx->width;  
    rect.h = pCodecCtx->height;  
    SDL_DisplayYUVOverlay(bmp, &rect);  
        
      }  
    }  
      
    // Free the packet that was allocated by av_read_frame   
    av_free_packet(&packet);  
    SDL_PollEvent(&event);  
    switch(event.type) {  
    case SDL_QUIT:  
      SDL_Quit();  
      exit(0);  
      break;  
    default:  
      break;  
    }  
  
  }  
    
  // Free the YUV frame   
  av_free(pFrame);  
    
  // Close the codec   
  avcodec_close(pCodecCtx);  
    
  // Close the video file   
  av_close_input_file(pFormatCtx);  
    
  return 0;  
} 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值