现在的位置: 首页 > 综合 > 正文

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

2013年02月02日 ⁄ 综合 ⁄ 共 4558字 ⁄ 字号 评论关闭
#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)
 

抱歉!评论已关闭.