应用FFMPEG和SDL,播放视频文件

来源:互联网 发布:工信部办公软件样本 编辑:程序博客网 时间:2024/05/16 08:29

使用FFMPEG库进行视频编解码,使用SDL播放视频,代码参考dranger大神的代码。

extern "C" {#include "libavformat/avformat.h"  #include "libswscale/swscale.h"  }#include <stdlib.h>  #include <stdio.h>  #include <string.h>  #include <math.h>  #include <SDL/SDL.h>    #ifdef main  #undef main  #endif    #define SDL_AUDIO_BUFFER_SIZE 1024  static int sws_flags = SWS_BICUBIC;    int main(int argc, char *argv[])  {      AVFormatContext *pFormatCtx;      int i, videoStream(-1);      AVCodecContext *pCodecCtx;      AVCodec *pCodec;      AVFrame *pFrame;      AVPacket packet;      int frameFinished;      float aspect_ratio;      AVCodecContext *aCodecCtx;      SDL_Overlay *bmp;      SDL_Surface *screen;      SDL_Rect rect;      SDL_Event event;      if(argc < 2)      {          fprintf(stderr, "Usage: test \n");          exit(1);      }        av_register_all();      pFormatCtx = av_alloc_format_context();      if (!pFormatCtx) {          fprintf(stderr, "Memory error\n");          exit(1);      }      if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)          return -1; // Couldn't open file      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      for(i=0; i<pFormatCtx->nb_streams; i++)      {          if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && videoStream<0)          {              videoStream=i;          }      }      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;      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();        uint8_t *buffer;      int numBytes;      // Determine required buffer size and allocate buffer      numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,          pCodecCtx->height);      buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));      printf("the size of picture is %d\n",numBytes);      if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))      {          fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());          exit(1);      }    #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);      }        bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,          SDL_YV12_OVERLAY, screen);        static struct SwsContext *img_convert_ctx;      if (img_convert_ctx == NULL)      {          img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,                                           pCodecCtx->pix_fmt,                                           pCodecCtx->width, pCodecCtx->height,                                           PIX_FMT_YUV420P,                                           sws_flags, NULL, NULL, NULL);          if (img_convert_ctx == NULL)          {              fprintf(stderr, "Cannot initialize the conversion context\n");              exit(1);          }      }      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)              {                  // Convert the image from its native format to RGB                                    // Save the frame to disk                                    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                                    sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,                      0, pCodecCtx->height, pict.data, pict.linesize);                  SDL_UnlockYUVOverlay(bmp);                  rect.x = 0;                  rect.y = 0;                  rect.w = pCodecCtx->width;                  rect.h = pCodecCtx->height;                  SDL_DisplayYUVOverlay(bmp, &rect);                  //Sleep(60);              }          }            // 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 RGB image      av_free(buffer);      //av_free(pFrameRGB);      // Free the YUV frame      av_free(pFrame);      // Close the codec      avcodec_close(pCodecCtx);      // Close the video file      av_close_input_file(pFormatCtx);      return 0;  }  


原创粉丝点击