WishMaster

1+1.巴赫.酸菜鱼

原创 针对FFMPEG0.49版本API编写的简单解码程序收藏

新一篇: 调用Xvid编码器流程(基于xvid1.1.0) | 旧一篇: xvid解码 SDL显示 源程序

#include <avcodec.h>
#include <avformat.h>
#include <stdlib.h>
#include <stdio.h>
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{
 FILE *pFile;
 char szFilename[32];
 int y;
 // Open file
 sprintf(szFilename, "frame%d.ppm", iFrame);
 pFile=fopen(szFilename, "w+b");
 if(pFile==NULL)
  {fprintf(stderr, "open frame file error\n");
 return;}
 // Write header
 fprintf(pFile, "P6\n%d %d\n255\n", width, height);
 // Write pixel data
 for(y=0; y<height; y++)
 fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
 
 // Close file
 fclose(pFile);
}
static AVInputFormat *file_iformat;
int main(int argc, char *argv[])
{
 static AVPacket packet;
 AVFormatContext *pFormatCtx;
 int i, videoStream;
 AVCodecContext *pCodecCtx;
 AVCodec *pCodec;
 AVFrame *pFrame;
 AVFrame *pFrameRGB;
 int numBytes;
 uint8_t *buffer;
 int frameFinished;
 // Register all formats and codecs
 av_register_all();
 // file_iformat = av_find_input_format(argv[1]);
 // pFormatCtx = (AVFormatContext *) malloc (sizeof (AVFormatContext));
 // Open video file
 if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL) < 0){
  fprintf(stderr, "Open video file\n");
  return -1; // Couldn't open file
 }
 if (av_find_stream_info(pFormatCtx) < 0){
 fprintf(stderr, "av_find_stream_info error\n");
 }
 fprintf(stderr, "Open video file and nb_streams is %d\n", pFormatCtx->nb_streams);
 // Retrieve stream information
 if( (pFormatCtx)<0){
  fprintf(stderr, "Retrieve stream information\n");
  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[i]->codec->codec_type==CODEC_TYPE_VIDEO)
  {
   videoStream=i;
   break;
  }
 if(videoStream==-1)
 {
  fprintf(stderr, "Didn't find a video stream and pFormatCtx->nb_streams is %d\n",    pFormatCtx->nb_streams);
  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, "Codec not found\n");
  return -1; // Codec not found
 }
 // Inform the codec that we can handle truncated bitstreams -- i.e.,
 // bitstreams where frame boundaries can fall in the middle of packets
 if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
  pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
 // Open codec
 if(avcodec_open(pCodecCtx, pCodec)<0){
  fprintf(stderr, "pFrameRGB==NULL\n");
  return -1; // Could not open codec
 }
 // Hack to correct wrong frame rates that seem to be generated by some
 // codecs
 // if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1) \
 pCodecCtx->frame_rate_base=1000;
 // Allocate video frame
 pFrame=avcodec_alloc_frame();
 // Allocate an AVFrame structure
 pFrameRGB=avcodec_alloc_frame();
 if(pFrameRGB==NULL){
  fprintf(stderr, "pFrameRGB==NULL\n");
  return -1;
 }
 // Determine required buffer size and allocate buffer
 numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
 pCodecCtx->height);
 buffer=new uint8_t[numBytes];
 printf("Determine required buffer size and allocate buffer\n");
 // Assign appropriate parts of buffer to image planes in pFrameRGB
 avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
 pCodecCtx->width, pCodecCtx->height);
 printf("Assign appropriate parts of buffer to image planes in pFrameRGB\n");
 // Read frames and save first five frames to disk
 i=0;
 while(av_read_frame(pFormatCtx,&packet)>=0)
 {
  if(packet.stream_index==videoStream)
  {
   avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
              packet.data, packet.size);
   if(frameFinished)
   {
    img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, (AVPicture*)pFrame,
    pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
    // Save the frame to disk
    if(++i<=5)
     //printf("%d\n",*pFrameRGB);
     SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
     //printf("\n\n%",sizeof(pFrameRGB));
   }
  }
  av_free_packet(&packet);
 }
 // Free the RGB image
 delete [] 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;
操作系统FC4
本程序能够成功运行
Makefile 如下
 
CC=g++

TARGET=main1
SOURCE=main1.cpp
OBJECT=main1.o
CFLAGS+=-g -I. -I.. -I../libavcodec -I../libavformat\
-I../libavutil -I/usr/include/SDL
#LFLAGS+=-Wl,--warn-common -rdynamic -L../libavformat\
-lavformat -L../libavcodec -lavcodec \
-L../libutil -lavutil -lz -lSDL\
-lm -lz -ldl -L/usr/lib -lSDL -lpthread
LFLAGS+=-Wl,--warn-common -rdynamic -L../libavformat\
-lavformat -L../libavcodec -lavcodec\
-L../libavutil -lavutil -lSDL -lz\
-lm -lz -ldl -L/usr/lib -lpthread

$(TARGET):$(OBJECT)
    $(CC) -o $(TARGET) $(OBJECT) $(CFLAGS) $(LFLAGS)
$(OBJECT):$(SOURCE)
    $(CC) -o $(OBJECT) -c $(SOURCE) $(CFLAGS)
clean:
    rm -f $(TARGET) $(OBJECT)
 

发表于 @ 2007年03月15日 22:51:00|评论(loading...)|编辑

新一篇: 调用Xvid编码器流程(基于xvid1.1.0) | 旧一篇: xvid解码 SDL显示 源程序

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © WishMaster