FFmpeg vc6

      最近工作无聊,看到网络上前辈门喊叫着FFmepg在VC上编译遇到很多问题,本人由于工作后期也有点需求用到FFmpeg的codec,所以就顺便整理了一份针对VC环境的视频播放软件,虽然第一个版本比较老了些,但是只是为了验证而已,后期会专门针对on2、VP6做一个全新的、单纯的只能够播放FLV视频的软件,因为要用到后期的Flash player上去.

      其实很简单,没有想象的那么复杂,我也是只用了不到一个星期的功夫就整理出来了,写点心得给能够有这方面需求的人.

      首先,我们应该清楚系统的架构,我是做系统的,所以很多软件工程的架构都大致有个了解,要明白自己要做什么,需要什么,明白自己要那些东西,对整个流程要有一定的认识,然后再去裁减,才会达到事半功倍的效果.

      其次,遇到问题不要怕,这样那样的错误其实是个好事情,最可怕的是遇不到错误,你不知道程序究竟运行到那里出了问题,诸如:指针一不小心瞄准了自己.FFmpeg是个体力活,静下心来,慢慢的就明白是怎么回事情了.

      最后,再实现播放后,裁减个最小的方便自己认真学习人家的编程思想.研究人家的算法理念.

      遇到的错误:

      ① 头文件找不到

      ② 字节对齐

      ③ SDL的问题(当然我的程序最后是不用这个东西的,因为要平台化)

      图片再相册里有.

int  main (int argc, char *argv[])
{
  AVFormatContext *pFormatCtx;
  int i, videoStream,audioStream;
  AVCodecContext *pCodecCtx,*pAudioCtx;
  AVCodec *pCodec;
  AVFrame *pFrame;
  AVFrame *pFrameYUV;
  AVPacket packet;
  PacketQueue audioq;
  int frameFinished;
  int numBytes;
  const char *filename = "3.flv";
  SDL_Surface *screen ;
  SDL_Overlay *overlay;
  SDL_AudioSpec PTempCtx,spec;
  static SDL_Rect rect;
  argv[1] = filename;
  // Register all formats and codecs
  av_register_all ();
  // 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;
  audioStream = -1;
  for (i = 0; i < pFormatCtx->nb_streams; i++)
  {
    if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO )   
    {
      videoStream = i;
     // break;
    }

    if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)   
    {
      audioStream = i;
    //  break;
    }
  }
  if (videoStream == -1)
    return -1;
  if (audioStream == -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;
  pAudioCtx = pFormatCtx->streams[audioStream]->codec;//
  / SDL initialization
  if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))/
   {
    fprintf(stderr, "Could not initialize SDL - %s/n", SDL_GetError());
        exit(1);
   }
  screen = SDL_SetVideoMode (pCodecCtx->width, pCodecCtx->height, 0, SDL_HWSURFACE);
  overlay = SDL_CreateYUVOverlay (pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen); 
  rect.x = 0;
  rect.y = 0;
  rect.w = pCodecCtx->width;
  rect.h = pCodecCtx->height;
  PTempCtx.freq = pAudioCtx->sample_rate;
  PTempCtx.format = AUDIO_S16SYS;
  PTempCtx.channels = pAudioCtx->channels;
  PTempCtx.silence = 0;
  PTempCtx.samples = SDL_AUDIO_BUFFER_SIZE;
  PTempCtx.callback = sdl_audio_callback;
  PTempCtx.userdata = pAudioCtx;
if(SDL_OpenAudio(&PTempCtx, &spec) < 0)
 {

  fprintf(stderr, "SDL_OpenAudio: %s/n", SDL_GetError());
  return -1;
 }

  //
  // Find the decoder for the video stream
  pCodec = avcodec_find_decoder (pCodecCtx->codec_id);
  if (pCodec == NULL)
    return -1;            // Codec not found
  // Open codec
  if (avcodec_open (pCodecCtx, pCodec) < 0)
    return -1;            // Could not open codec
  if (avcodec_open (pAudioCtx, pCodec) < 0)
    return -1;
  packet_queue_init(&audioq);
  SDL_PauseAudio(0);
  // Allocate video frame
  pFrame = avcodec_alloc_frame ();
  // Allocate an AVFrame structure
  pFrameYUV = avcodec_alloc_frame ();
  if (pFrameYUV == NULL)
    return -1;

  // Set SDL events
  SDL_EventState (SDL_ACTIVEEVENT, SDL_IGNORE);
  SDL_EventState (SDL_MOUSEMOTION, SDL_IGNORE);
  SDL_ShowCursor (SDL_DISABLE);

  // Read frames
  while ((av_read_frame (pFormatCtx, &packet) >= 0)
     && (SDL_PollEvent (NULL) == 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 YUV, and display

       SDL_LockYUVOverlay (overlay);
       pFrameYUV->data[0] = overlay->pixels[0];
       pFrameYUV->data[1] = overlay->pixels[2];
       pFrameYUV->data[2] = overlay->pixels[1];

       pFrameYUV->linesize[0] = overlay->pitches[0];
       pFrameYUV->linesize[1] = overlay->pitches[2];
       pFrameYUV->linesize[2] = overlay->pitches[1];

       img_convert ((AVPicture *) pFrameYUV, PIX_FMT_YUV420P,
                (AVPicture *) pFrame, pCodecCtx->pix_fmt,
                pCodecCtx->width, pCodecCtx->height);
       SDL_UnlockYUVOverlay (overlay);
       SDL_DisplayYUVOverlay (overlay, &rect); 
       SDL_Delay (40);
         }
      }
  else if (packet.stream_index == audioStream)
  {
   packet_queue_put(&audioq, &packet);
  }
 else
  {
       // Free the packet that was allocated by av_read_frame
       av_free_packet (&packet);
  }
  }
  // Free the RGB image
  av_free (pFrameYUV);
  // Free the YUV frame
  av_free (pFrame);
  // Close the codec
  avcodec_close (pCodecCtx);
  // Close the video file
  av_close_input_file (pFormatCtx);
  //
  SDL_FreeYUVOverlay (overlay);
  return 0;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值