LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3351|回复: 3

最简单的基于ffmpeg库的视频播放代码(a bare bone media player based on ffmpeg li

[复制链接]
发表于 2006-3-7 10:43:42 | 显示全部楼层 |阅读模式
没有帧率控制,没有声音。主要功能是提取单帧图像。
需要安装比0.4.9-pre1新的ffmpeg的cvs版本。
avcodec2.c代码:
[php]
// g++ -o avcodec2 avcodec2.cpp -lavformat -lavcodec -lSDL
// written by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de)
// Hacked by wei lian (lianwei2003.student@sina.com)
// passed compilation for the cvs version newer than 0.4.9-pre1 of ffmpeg

#include <SDL/SDL.h>
#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>
#include <stdio.h>

int
main (int argc, char *argv[])
{
  AVFormatContext *pFormatCtx;
  int i, videoStream;
  AVCodecContext *pCodecCtx;
  AVCodec *pCodec;
  AVFrame *pFrame;
  AVFrame *pFrameYUV;
  AVPacket packet;
  int frameFinished;
  int numBytes;

  // 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], false);
  // Find the first video stream
  videoStream = -1;
  for (i = 0; i < pFormatCtx->nb_streams; i++)
    if (pFormatCtx->streams->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;        //////////
  ///////// SDL initialization
  SDL_Surface *screen =
    SDL_SetVideoMode (pCodecCtx->width, pCodecCtx->height, 0, SDL_HWSURFACE);
  SDL_Overlay *overlay =
    SDL_CreateYUVOverlay (pCodecCtx->width, pCodecCtx->height,
                          SDL_YV12_OVERLAY,
                          screen);
  static SDL_Rect rect;
  rect.x = 0;
  rect.y = 0;
  rect.w = pCodecCtx->width;
  rect.h = pCodecCtx->height;
  //////////
  // 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

  // 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 (10);
      }
    }
    // 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;
}
[/php]
编译:
g++ -o avcodec2 avcodec2.cpp -lavformat -lavcodec -lSDL
参考:
http://www.inb.uni-luebeck.de/%7Eboehme/using_libavcodec.html
http://www.inb.uni-luebeck.de/%7Eboehme/libavcodec_update.html
http://lianwei3.googlepages.com/otherprograms
发表于 2006-3-7 14:33:23 | 显示全部楼层
一些高级特性都没提供,没有使用双缓冲,没有提供overlay,没有提供deinterlace,没有提供硬件flip。
另外版权和授权也没有说明。
回复 支持 反对

使用道具 举报

发表于 2006-3-7 20:28:05 | 显示全部楼层
哈哈,楼上的把问题严重化了,不过确实应该写明版权问题的,这是个好习惯用人家的东西
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-9 22:45:33 | 显示全部楼层
Post by realtang
一些高级特性都没提供,没有使用双缓冲,没有提供overlay,没有提供deinterlace,没有提供硬件flip。
另外版权和授权也没有说明。

deinterlace是什么?硬件flip是什么?双缓冲没必要吧?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表