热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ffmpegavi转码到mp4(aac+h264)源码分享

avi转码到mp4(aach264)源码分享看了liuxinhongxin前辈的源码很受启发,但在播放时头信息会有错误,略作修改,代码如下

 

avi转码到mp4(aac+h264)源码分享

看了liuxinhongxin 前辈的源码很受启发,但在播放时头信息会有错误,略作修改,代码如下:
#include
#include
#include
#include
#include
#include
#include
void pstrcpy(char *buf, int buf_size, const char *str)
{
    int c;//why int here
    char *q = buf;

    if (buf_size <&#61; 0)
        return;

    for(;;) {
        c &#61; *str&#43;&#43;;
        if (c &#61;&#61; 0 || q >&#61; buf &#43; buf_size - 1)
            break;
        *q&#43;&#43; &#61; c;
    }
    *q &#61; &#39;/0&#39;;
}
main(int argc,char **argv)
{   
  const char *input_file_name&#61;"/home/movie.avi";
  av_register_all();//注册库中所有可用的文件格式和编码器
  AVFormatContext *ic;
  //输入文件处理部分
  ic&#61;av_alloc_format_context();
  if(av_open_input_file(&ic,input_file_name,NULL,0,NULL)!&#61;0)
  {
     printf("can&#39;t open the file %s/n",input_file_name);
     exit(1);
  }//打开输入文件  
  if(av_find_stream_info(ic)<0)
  {
     printf("can&#39;t find suitable codec parameters/n");
     exit(1);
  }//取出流信息
  
  dump_format(ic,0,input_file_name,0);//列出输入文件的相关流信息
  int i;
  int videoindex&#61;-1;int audioindex&#61;-1;
  for(i&#61;0;inb_streams;i&#43;&#43;)
  {   
     if(ic->streams[i]->codec->codec_type&#61;&#61;CODEC_TYPE_VIDEO)
         {
            videoindex&#61;i;
          //printf("video/n");
         }
         else if(ic->streams[i]->codec->codec_type&#61;&#61;CODEC_TYPE_AUDIO)
         {
          //printf("audio/n");
            audioindex&#61;i;
         }
  }
   if(videoindex&#61;&#61;-1)
   {
          printf("can&#39;t find video stream/n");
          exit(1);
   }//没有找到视频流
   
   
  AVCodecContext *vCodecCtx;
  vCodecCtx&#61;ic->streams[videoindex]->codec;//取得视频流编码上下文指针
  AVCodec *vCodec;
  vCodec&#61;avcodec_find_decoder(vCodecCtx->codec_id);
  if(vCodec&#61;&#61;NULL)
  {
     printf("can&#39;t find suitable video decoder/n");
     exit(1);
  }//找到合适的视频解码器
  if(avcodec_open(vCodecCtx,vCodec)<0)
  {
     printf("can&#39;t open the video decoder/n");
     exit(1);
  }//打开该视频解码器
  
  
   if(audioindex&#61;&#61;-1)
     {
        printf("can&#39;t find audio stream/n");
        exit(1);
     }//没有找到音频流
  AVCodecContext *aCodecCtx;
  aCodecCtx&#61;ic->streams[audioindex]->codec;
  AVCodec *aCodec;
  aCodec&#61;avcodec_find_decoder(aCodecCtx->codec_id);
  if(aCodec&#61;&#61;NULL)
  {
     printf("can&#39;t find suitable audio decoder/n");
     exit(1);
  }//找到合适的音频解码器
  if(avcodec_open(aCodecCtx,aCodec)<0)
  {
     printf("can&#39;t open the audio decoder/n");
     exit(1);
  }//打开该音频解码器
  
  
//下面为输出文件处理部分
    const char *output_file_name&#61;"/home/result.aac";
    AVOutputFormat *fmt;
    AVFormatContext *oc;
    AVCodecContext *oVcc,*oAcc;
    AVCodec *oVc,*oAc;
    AVStream *video_st,*audio_st;
    AVFrame *oVFrame,*oAFrame;
    double video_pts;
    oVFrame&#61;avcodec_alloc_frame();
    fmt&#61;guess_format(NULL,output_file_name,NULL);
    if(!fmt)
    {
           printf("could not deduce output format from outfile extension/n");
           exit(0);
    }//判断是否可以判断输出文件的编码格式
    oc&#61;av_alloc_format_context();
    if(!oc)
    {
           printf("Memory error/n");
           exit(0);
    }
    oc->oformat&#61;fmt;
   pstrcpy(oc->filename,sizeof(oc->filename),output_file_name);
  
    video_st&#61;av_new_stream(oc,0);
    if(!video_st)
    {
          printf("could not alloc video stream/n");
          exit(0);
    }
    oVcc&#61;avcodec_alloc_context();
    oVcc&#61;video_st->codec;
    oVcc->codec_id&#61;CODEC_ID_H264;
    oVcc->codec_type&#61;CODEC_TYPE_VIDEO;
    oVcc->bit_rate&#61;1000000;
    oVcc->width&#61;320;
    oVcc->height&#61;240;
    oVcc->time_base&#61;vCodecCtx->time_base;
    oVcc->gop_size&#61;vCodecCtx->gop_size;
    //oVcc->pix_fmt&#61;vCodecCtx->pix_fmt;
    oVcc->pix_fmt&#61;vCodecCtx->pix_fmt;
    oVcc->max_b_frames&#61;vCodecCtx->max_b_frames;
    video_st->r_frame_rate&#61;ic->streams[videoindex]->r_frame_rate;// frame rate
   // audio_st&#61;av_new_stream(oc,oc->nb_streams);   //
    audio_st&#61;av_new_stream(oc,1);
    if(!audio_st)
    {
           printf("could not alloc audio stream/n");
           exit(0);
    }  
   // avcodec_get_context_defaults2(audio_st->codec,CODEC_TYPE_AUDIO);
   avcodec_get_context_defaults(audio_st->codec);//  do what
    oAcc&#61;avcodec_alloc_context();
    oAcc&#61;audio_st->codec;
    oAcc->codec_id&#61;CODEC_ID_AAC;
    oAcc->codec_type&#61;CODEC_TYPE_AUDIO;
    oAcc->bit_rate&#61;aCodecCtx->bit_rate;// bit rate
    oAcc->sample_rate&#61;aCodecCtx->sample_rate;
    oAcc->channels&#61;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&#61;ic->year;
    oc->track&#61;ic->track;
    strcpy(oc->genre,ic->genre);
    dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息
    oVc&#61;avcodec_find_encoder(CODEC_ID_H264);
    if(!oVc)
    {
       printf("can&#39;t find suitable video encoder/n");
           exit(0);
    }//找到合适的视频编码器
    if(avcodec_open(oVcc,oVc)<0)
    {
           printf("can&#39;t open the output video codec/n");
           exit(0);
    }//打开视频编码器
    oAc&#61;avcodec_find_encoder(CODEC_ID_AAC);
    if(!oAc)
    {
           printf("can&#39;t find suitable audio encoder/n");
           exit(0);
    }//找到合适的音频编码器
    if(avcodec_open(oAcc,oAc)<0)
    {
           printf("can&#39;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&#39;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);
  }
  
AVPacket packet;
  uint8_t *ptr,*out_buf;
  int out_size;
  static short *samples&#61;NULL;
  static unsigned int samples_size&#61;0;
  uint8_t *video_outbuf,*audio_outbuf;
  int video_outbuf_size,audio_outbuf_size;
  video_outbuf_size&#61;400000;
  video_outbuf&#61; (unsigned char *) malloc(video_outbuf_size);
  audio_outbuf_size &#61; 10000;
    //audio_outbuf &#61; av_malloc(audio_outbuf_size);
  audio_outbuf &#61; (unsigned char *) malloc(audio_outbuf_size);
  int flag;int frameFinished;int len;int frame_index&#61;0,ret;
          while(av_read_frame(ic,&packet)>&#61;0)//从输入文件中读取一个包
       {
          if(packet.stream_index&#61;&#61;videoindex)//判断是否为当前视频流中的包
          {
         len&#61;avcodec_decode_video(vCodecCtx,oVFrame,&frameFinished,packet.data,packet.size);//若为视频包&#xff0c;解码该视频包
                 if(len<0)
                 {
                    printf("Error while decoding/n");
                    exit(0);
                 }
     
         if(frameFinished)//判断视频祯是否读完
         
         {
             fflush(stdout);
             oVFrame->pts&#61;av_rescale(frame_index,AV_TIME_BASE*(int64_t)oVcc->time_base.num,oVcc->time_base.den);
             oVFrame->pict_type&#61;0;
             out_size &#61; 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 |&#61; PKT_FLAG_KEY;                                       
                     pkt.flags &#61; packet.flags;                     
                     pkt.stream_index&#61; video_st->index;                                               
                     pkt.data&#61; video_outbuf;                                                         
                     pkt.size&#61; out_size;                                             
                     ret&#61;av_write_frame(oc, &pkt);                                       
             }
             frame_index&#43;&#43;;
         }
         else
            {
              printf("...../n");                                       
             }
                   #if 0
                   if(ret!&#61;0)
                    {
                      printf("while write video frame error/n");
                     // exit(0);
                    }
                    #endif
                  
          }

 



else if(packet.stream_index&#61;&#61;audioindex)
      {
         len&#61;packet.size;
         ptr&#61;packet.data;
             int ret&#61;0;
             while(len>0)
             {
                    out_buf&#61;NULL;
                    out_size&#61;0;
                    if(&packet)
               samples&#61;(short *)av_fast_realloc(samples,&samples_size,FFMAX(packet.size*sizeof
(*samples),AVCODEC_MAX_AUDIO_FRAME_SIZE));
                    out_size&#61;samples_size;
                    ret&#61;avcodec_decode_audio(aCodecCtx,samples,&out_size,ptr,len);//若为音频包&#xff0c;解码该音频包
                    if(ret<0)
                    {
                       printf("while decode audio failure/n");
                       exit(0);
                    }
            fflush(stdout);
            ptr&#43;&#61;ret;
            len-&#61;ret;
            if(out_size<&#61;0)
               continue;
            out_buf&#61;(uint8_t *)samples;
            AVPacket pkt;
            av_init_packet(&pkt);
            pkt.size&#61; avcodec_encode_audio(oAcc, audio_outbuf, audio_outbuf_size, (short int*)out_buf);
            pkt.pts&#61; av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base);
            pkt.flags |&#61; PKT_FLAG_KEY;
            pkt.stream_index&#61; audioindex;
            pkt.data&#61; audio_outbuf;
           
          #if 1
            if (av_write_frame(oc, &pkt) !&#61; 0)
                    {
               fprintf(stderr, "Error while writing audio frame/n");
               exit(1);
                }
              #endif  
             }
          }
          av_free_packet(&packet);
       }
      
av_write_trailer(oc);

for(i &#61; 0; i nb_streams; i&#43;&#43;)
{            
  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);



推荐阅读
author-avatar
低调酥紫_631
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有