Chinaunix首页 | 论坛 | 博客
  • 博客访问: 379937
  • 博文数量: 35
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 797
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-02 08:51
文章分类

全部博文(35)

文章存档

2011年(1)

2010年(3)

2009年(3)

2008年(28)

我的朋友

分类: WINDOWS

2010-05-25 13:09:04

希望对像我一样开始学习有难度的有帮助,我花费了很长时间吆

本程序实现转码一个普通视频文件为视频mpeg4,音频mp3的功能
#include
#include
#include
#include
#include
#include
#include
main(int argc,char **argv)
{   
   const char *input_file_name="/root/movies/ddh1.mpg";
   av_register_all();//注册库中所有可用的文件格式和编码
   AVFormatContext *ic;
   //输入文件处理部分
   ic=av_alloc_format_context();
   if(av_open_input_file(&ic,input_file_name,NULL,0,NULL)!=0)
   {
      printf("can't open the file %s\n",input_file_name);
      exit(1);
   }//打开输入文件

   if(av_find_stream_info(ic)<0)
   {
      printf("can't find suitable codec parameters\n");
      exit(1);
   }//取出流信息
   dump_format(ic,0,input_file_name,0);//列出输入文件的相关流信息

   int i;
   int videoindex=-1;int audioindex=-1;
   for(i=0;inb_streams;i++)
   {   
      if(ic->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
          {
             videoindex=i;
           //printf("video\n");
          }
          else if(ic->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO)
          {
           //printf("audio\n");
             audioindex=i;
          }
   }
    if(videoindex==-1)
    {
           printf("can't find video stream\n");
           exit(1);
    }//没有找到视频流

   AVCodecContext *vCodecCtx;

   vCodecCtx=ic->streams[videoindex]->codec;//取得视频流编码上下文指针

   AVCodec *vCodec;
   vCodec=avcodec_find_decoder(vCodecCtx->codec_id);
   if(vCodec==NULL)
   {
      printf("can't find suitable video decoder\n");
      exit(1);
   }//找到合适的视频解码器



   if(avcodec_open(vCodecCtx,vCodec)<0)
   {
      printf("can't open the video decoder\n");
      exit(1);
   }//打开该视频解码器

    if(audioindex==-1)
      {
         printf("can't find audio stream\n");
         exit(1);
      }//没有找到音频流

   AVCodecContext *aCodecCtx;

   aCodecCtx=ic->streams[audioindex]->codec;
   AVCodec *aCodec;
   aCodec=avcodec_find_decoder(aCodecCtx->codec_id);
   if(aCodec==NULL)
   {
      printf("can't find suitable audio decoder\n");
      exit(1);
   }//找到合适的音频解码器


   if(avcodec_open(aCodecCtx,aCodec)<0)
   {
      printf("can't open the audio decoder\n");
      exit(1);

   }//打开该音频解码器

//下面为输出文件处理部分
     const char *output_file_name="/root/123.avi";
     AVOutputFormat *fmt;
     AVFormatContext *oc;
     AVCodecContext *oVcc,*oAcc;
     AVCodec *oVc,*oAc;
     AVStream *video_st,*audio_st;
     AVFrame *oVFrame,*oAFrame;
     double video_pts;

     oVFrame=avcodec_alloc_frame();
     fmt=guess_format(NULL,output_file_name,NULL);
     if(!fmt)
     {
            printf("could not deduce output format from outfile extension\n");
            exit(0);
     }//判断是否可以判断输出文件的编码格式

     oc=av_alloc_format_context();
     if(!oc)
     {
            printf("Memory error\n");
            exit(0);
     }
     oc->oformat=fmt;
     pstrcpy(oc->filename,sizeof(oc->filename),output_file_name);

     video_st=av_new_stream(oc,0);
     if(!video_st)
     {
           printf("could not alloc video stream\n");
           exit(0);
     }

     
     oVcc=avcodec_alloc_context();
     oVcc=video_st->codec;
     oVcc->codec_id=CODEC_ID_MPEG4;
     oVcc->codec_type=CODEC_TYPE_VIDEO;
     oVcc->bit_rate=2500000;
     oVcc->width=704;
     oVcc->height=480;
     oVcc->time_base=vCodecCtx->time_base;
     oVcc->gop_size=vCodecCtx->gop_size;
     //oVcc->pix_fmt=vCodecCtx->pix_fmt;
     oVcc->pix_fmt=vCodecCtx->pix_fmt;
     oVcc->max_b_frames=vCodecCtx->max_b_frames;
     video_st->r_frame_rate=ic->streams[videoindex]->r_frame_rate;

     audio_st=av_new_stream(oc,oc->nb_streams);
     if(!audio_st)
     {
            printf("could not alloc audio stream\n");
            exit(0);
     }  
     avcodec_get_context_defaults2(audio_st->codec,CODEC_TYPE_AUDIO);
     oAcc=avcodec_alloc_context();
     oAcc=audio_st->codec;
     oAcc->codec_id=CODEC_ID_MP3;
     oAcc->codec_type=CODEC_TYPE_AUDIO;
     oAcc->bit_rate=aCodecCtx->bit_rate;
     oAcc->sample_rate=aCodecCtx->sample_rate;
     oAcc->channels=2;

     if (av_set_parameters(oc, NULL) < 0)
     {
            printf( "Invalid output format parameters\n");                        
               exit(0);                              
     }//设置必要的输出参数

     strcpy(oc->title,ic->title);
     strcpy(oc->author,ic->author);
     strcpy(oc->copyright,ic->copyright);
     strcpy(oc->comment,ic->comment);
     strcpy(oc->album,ic->album);
     oc->year=ic->year;
     oc->track=ic->track;
     strcpy(oc->genre,ic->genre);

     dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息

     oVc=avcodec_find_encoder(CODEC_ID_MPEG4);
     if(!oVc)
     {
        printf("can't find suitable video encoder\n");
            exit(0);
     }//找到合适的视频编码器

     if(avcodec_open(oVcc,oVc)<0)
     {
            printf("can't open the output video codec\n");
            exit(0);
     }//打开视频编码器

     oAc=avcodec_find_encoder(CODEC_ID_MP3);
     if(!oAc)
     {
            printf("can't find suitable audio encoder\n");
            exit(0);
     }//找到合适的音频编码器
   
     if(avcodec_open(oAcc,oAc)<0)
     {
            printf("can't open the output audio codec");
            exit(0);
     }//打开音频编码器
   
     /*if(url_exist(output_file_name))
     {
        printf("the output file name %s has exist,please select other\n",output_file_name);
        exit(0);
     }//判断该输出文件是否已经存在*/
     if (!(oc->flags & AVFMT_NOFILE))
     {
        if(url_fopen(&oc->pb,output_file_name,URL_WRONLY)<0)
        {
               printf("can't open the output file %s\n",output_file_name);
               exit(0);
        }//打开输出文件
     }

     if(!oc->nb_streams)
     {
            fprintf(stderr,"output file dose not contain any stream\n");
            exit(0);
     }//查看输出文件是否含有流信息

   if(av_write_header(oc)<0)
   {
       fprintf(stderr, "Could not write header for output file\n");
       exit(1);
   }[/i][/i]

AVPacket packet;
   uint8_t *ptr,*out_buf;
   int out_size;
   static short *samples=NULL;
   static unsigned int samples_size=0;
   uint8_t *video_outbuf,*audio_outbuf;int video_outbuf_size,audio_outbuf_size;
   video_outbuf_size=400000;
   video_outbuf= (unsigned char *) malloc(video_outbuf_size);
   audio_outbuf_size = 10000;
   audio_outbuf = av_malloc(audio_outbuf_size);

   int flag;int frameFinished;int len;int frame_index=0,ret;

           while(av_read_frame(ic,&packet)>=0)//从输入文件中读取一个包
        {
           if(packet.stream_index==videoindex)//判断是否为当前视频流中的包
           {
          len=avcodec_decode_video(vCodecCtx,oVFrame,&frameFinished,packet.data,packet.size);//若为视频包,解码该视频包
                  if(len<0)
                  {
                     printf("Error while decoding\n");
                     exit(0);
                  }
          if(frameFinished)//判断视频祯是否读完
          {
              fflush(stdout);
              oVFrame->pts=av_rescale(frame_index,AV_TIME_BASE*(int64_t)oVcc->time_base.num,oVcc->time_base.den);
              oVFrame->pict_type=0;
              out_size = avcodec_encode_video(oVcc, video_outbuf, video_outbuf_size, oVFrame);   
              if (out_size > 0)            
              {                  
                  AVPacket pkt;               
                  av_init_packet(&pkt);                              
                  if(oVcc->coded_frame && oVcc->coded_frame->key_frame)                                       
                      pkt.flags |= PKT_FLAG_KEY;                                       
                      pkt.flags = packet.flags;                     
                      pkt.stream_index= video_st->index;                                               
                      pkt.data= video_outbuf;                                                         
                      pkt.size= out_size;                                             
                      ret=av_write_frame(oc, &pkt);                                       
              }
                     
              frame_index++;
          }
          else
              ret=av_write_frame(oc, &packet);
                     //img_convert((AVPicture *)vFrame, PIX_FMT_RGB24, (AVPicture*)oVFrame, oVcc->pix_fmt,oVcc->width,oVcc->height);
             //SaveFrame(vFrame,oVcc->width,oVcc->height,frame_index);
                     if(ret!=0)
                     {
                       printf("while write video frame error\n");
                       exit(0);
                     }
           }
           else if(packet.stream_index==audioindex)
       {
          len=packet.size;
          ptr=packet.data;
              int ret=0;
              while(len>0)
              {
                     out_buf=NULL;
                     out_size=0;
                     if(&packet)
                samples=av_fast_realloc(samples,&samples_size,FFMAX(packet.size*sizeof(*samples),AVCODEC_MAX_AUDIO_FRAME_SIZE));
                     out_size=samples_size;
                     ret=avcodec_decode_audio(aCodecCtx,samples,&out_size,ptr,len);//若为音频包,解码该音频包
                     if(ret<0)
                     {
                        printf("while decode audio failure\n");
                        exit(0);
                     }

             fflush(stdout);
             ptr+=ret;
             len-=ret;
             if(out_size<=0)
                continue;
             out_buf=(uint8_t *)samples;
             AVPacket pkt;
             av_init_packet(&pkt);
             pkt.size= avcodec_encode_audio(oAcc, audio_outbuf, audio_outbuf_size, out_buf);
             pkt.pts= av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base);
             pkt.flags |= PKT_FLAG_KEY;
             pkt.stream_index= audioindex;
             pkt.data= audio_outbuf;
             if (av_write_frame(oc, &pkt) != 0)
             {
                fprintf(stderr, "Error while writing audio frame\n");
                exit(1);
                 }
          }
           }
           av_free_packet(&packet);
        }
av_write_trailer(oc);
for(i = 0; i < oc->nb_streams; i++)
{            
   av_freep(&oc->streams[i]->codec);                       
   av_freep(&oc->streams[i]);                           
}
url_fclose(oc);
av_free(oc);
av_free(oVFrame);
av_free(out_buf);
avcodec_close(vCodecCtx);
avcodec_close(aCodecCtx);
av_close_input_file(ic);

}
阅读(3395) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~