ffmpeg轉碼(avi轉mp4)

來源:互聯網
上載者:User

很難很難。 前後搞了一個月有於。。。。

目的:從一個avi轉碼到mp4,avi(視頻編碼器:mpeg4,音頻編碼:mpeg2 Audio,),mp4(視頻編碼器:h264/avc,音頻編碼器:mpeg2 Audio)

結果,基本可以了,視頻還有一點問題,音頻可以了。這裡先貼代碼在這裡,接下來再慢慢完善吧,音頻肯定要重採樣的,視頻也是要重新縮放的。。。還有音視頻的同步也木有做,等都做完了再來加註釋吧。。。

int mp4Tomp4(char* srcname, char* destname ){LOGI("LOGI----------------0");  input_file_name=  srcname;  av_register_all();  AVFormatContext *ic = NULL;  LOGI("LOGI----------------02");  LOGI("LOGI----------------1 input_file %s",input_file_name);//  ic=av_alloc_format_context();//  avformat_alloc_output_context2(&ic, NULL, NULL, input_file_name);  if(avformat_open_input(&ic, input_file_name, NULL, NULL) < 0)  {     LOGI("can't open the file %s\n",input_file_name);     exit(1);  }  if(avformat_find_stream_info(ic,NULL)<0)  {     LOGI("can't find suitable codec parameters\n");     exit(1);  }  LOGI("LOGI----------------2");//  av_dump_format(ic,0,input_file_name,1);  int i;  int videoindex=-1;int audioindex=-1;  for(i=0;i<ic->nb_streams;i++)  {     if(ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)         {            videoindex=i;            LOGI("video %d\n",videoindex);         }         else if(ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)         {            audioindex=i;            LOGI("audio %d\n",audioindex);         }  }  LOGI("LOGI----------------3");   if(videoindex==-1)   {          LOGI("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)  {     LOGI("can't find suitable video decoder\n");     exit(1);  }//�ҵ����ʵ���Ƶ������  if(avcodec_open2(vCodecCtx,vCodec,NULL)<0)  {     LOGI("can't open the video decoder\n");     exit(1);  }//�
LOGI("LOGI----------------4,%d",vCodecCtx->codec_id);   if(audioindex==-1)     {        LOGI("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)  {     LOGI("can't find suitable audio decoder\n");     exit(1);  }  if(avcodec_open2(aCodecCtx,aCodec,NULL)<0)  {     LOGI("can't open the audio decoder\n");     exit(1);  }  LOGI("LOGI----------------5 output file");  const char *output_file_name= destname;    AVOutputFormat *fmt;    AVFormatContext *oc;    AVCodecContext *oVcc,*oAcc;    AVCodec *oVc,*oAc;    AVStream *video_st,*audio_st;    AVFrame *oVFrame = NULL,*oAFrame = NULL;    oVFrame=avcodec_alloc_frame();    oAFrame=avcodec_alloc_frame();//    fmt=av_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();    LOGI("LOGI----------------6");    avformat_alloc_output_context2(&oc, NULL, NULL, output_file_name);    if(!oc)    {           LOGI("Memory error\n");           exit(0);    }    oc->oformat->video_codec = AV_CODEC_ID_H264;    oc->oformat->audio_codec = aCodecCtx->codec_id;    fmt=oc->oformat;    video_st = NULL;    audio_st = NULL;   pstrcpy(oc->filename,sizeof(oc->filename),output_file_name);   LOGI("LOGI----------------7");    video_st=avformat_new_stream(oc,NULL);    if(!video_st)    {          LOGI("could not alloc video stream\n");          exit(0);    }//    oVcc=avcodec_alloc_context3(video_st->codec);    LOGI("===============%d",vCodecCtx->pix_fmt);    oVcc=video_st->codec;    oVc = avcodec_find_encoder(AV_CODEC_ID_H264);    if (!oVc) {    LOGI("1111codec not found\n");    exit(1);    }    avcodec_get_context_defaults3(oVcc,oVc);//  do what    oVcc->codec_id=AV_CODEC_ID_H264;    oVcc->codec_type=AVMEDIA_TYPE_VIDEO;    //固定碼率控制    oVcc->bit_rate=12000;//    oVcc->bit_rate_tolerance=200000;    oVcc->rc_min_rate =12000;//設定最小視頻碼率容忍度    oVcc->rc_max_rate = 12000;//設定最大視頻碼率容忍度    oVcc->bit_rate_tolerance = 12000;    oVcc->rc_buffer_size=12000;//設定碼率控制緩衝區大小    oVcc->rc_initial_buffer_occupancy = oVcc->rc_buffer_size*3/4;    oVcc->rc_buffer_aggressivity= ( float )1.0;    oVcc->rc_initial_cplx= 0.5;    oVcc->qcompress =0;//視頻量化標度壓縮(VBR)    oVcc->qmin = 10;//最小視頻量化標度(VBR) 就是採樣的比例吧。。    oVcc->qmax = 50;//最大視頻量化標度(VBR)//    oVcc->global_quality = 10;//-qscale q 使用固定的視頻量化標度(VBR)    //可變碼率控制//    oVcc->flags |= CODEC_FLAG_QSCALE;//    oVcc->rc_min_rate =100000;//    oVcc->rc_max_rate = 200000;//    oVcc->bit_rate = 150000;    oVcc->width=320;    oVcc->height=240;    oVcc->time_base.den = 25;    oVcc->time_base.num = 1;//    oVcc->time_base=vCodecCtx->time_base;    oVcc->gop_size=10;//該值表示每10幀會插入一個I幀(intra frame)    //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;// frame rate   // audio_st=av_new_stream(oc,oc->nb_streams);   //    LOGI("LOGI----------------8 %d",oVcc->codec_id);    if(! strcmp( oc-> oformat-> name, "mp4" ) || !strcmp (oc ->oformat ->name , "mov" ) || !strcmp (oc ->oformat ->name , "3gp" ))        oVcc->flags |= CODEC_FLAG_GLOBAL_HEADER ;    audio_st=avformat_new_stream(oc,NULL);    if(!audio_st)    {           LOGI("could not alloc audio stream\n");           exit(0);    }//    audio_st->id=1;    oAcc=avcodec_alloc_context3(aCodecCtx->codec);    LOGI("LOGI----------------9.6");    oAcc=audio_st->codec;    oAc = avcodec_find_encoder(aCodecCtx->codec_id);       if (!oAc) {       LOGI("1111codec not found\n");       exit(1);       }       avcodec_get_context_defaults3(oAcc,oAc);       ReSampleContext *rsc = NULL;    oAcc->codec_id=aCodecCtx->codec_id;    oAcc->codec_type=AVMEDIA_TYPE_AUDIO;    oAcc->bit_rate=aCodecCtx->bit_rate;// bit rate    oAcc->sample_rate=aCodecCtx->sample_rate;    oAcc->sample_fmt = AV_SAMPLE_FMT_S16;    oAcc->channels = 1;    oAcc->frame_size = aCodecCtx->frame_size;    if (oc->oformat->flags & AVFMT_GLOBALHEADER)    oAcc->flags |= CODEC_FLAG_GLOBAL_HEADER;    LOGI("LOGI----------------81 %d",oAcc->sample_rate);    if(! strcmp( oc-> oformat-> name, "mp4" ) || !strcmp (oc ->oformat ->name , "mov" ) || !strcmp (oc ->oformat ->name , "3gp" ))           oAcc->flags |= CODEC_FLAG_GLOBAL_HEADER ;    av_dump_format(oc,0,output_file_name,1);    oVc=avcodec_find_encoder(oVcc->codec_id);        if(!oVc)        {           LOGI("can't find suitable video encoder\n");           exit(0);        }    int rett = 0;    if((rett =avcodec_open2(oVcc,oVc,NULL))<0)    {           LOGI("can't open the output video codec  %d", rett);           exit(0);    }    oAc=avcodec_find_encoder(aCodecCtx->codec_id);           if(!oAc)           {                  LOGI("can't find suitable audio encoder\n");                  exit(0);           }    if(avcodec_open2(oAcc,oAc,NULL)<0)    {           LOGI("can't open the output audio codec11");           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 (avio_open(&oc->pb, output_file_name, AVIO_FLAG_WRITE) < 0) {       LOGI("Could not open '%s'\n", output_file_name);       return 1;       }    }    if(!oc->nb_streams)    {           LOGI("output file dose not contain any stream\n");           exit(0);    }    LOGI("LOGI----------------11");  if(avformat_write_header(oc,NULL)<0)  {      LOGI("Could not write header for output file\n");      exit(1);  }  LOGI("LOGI----------------12 hebing");  AVPacket packet;  uint8_t *ptr,*out_buf;  int out_size;  int16_t *samples=NULL,resample_buffer = NULL;  static unsigned int samples_size=0;  uint8_t *video_outbuf,*audio_outbuf;  int video_outbuf_size,audio_outbuf_size;  video_outbuf_size=100000;  video_outbuf= (unsigned char *) malloc(video_outbuf_size);  audio_outbuf_size = 10000;    //audio_outbuf = av_malloc(audio_outbuf_size);  audio_outbuf = (unsigned char *) malloc(audio_outbuf_size);  int flag;int frameFinished,frameFinished2;int len;int frame_index=0,ret,ret1; int got_output=0;  LOGI("LOGI----------------13 ");FILE* f;f = fopen("video/11111111.aac", "wb");AVFifoBuffer *fifo;fifo= av_fifo_alloc(1024);if(!fifo)return -1;//         oAFrame->nb_samples     = oAcc->frame_size;//         oAFrame->format         = oAcc->sample_fmt;//         oAFrame->channel_layout = oAcc->channel_layout;          while(av_read_frame(ic,&packet)>=0)       {          if(packet.stream_index==videoindex)          {          LOGI("LOGI----------------14.4 ");          len=avcodec_decode_video2(vCodecCtx,oVFrame,&frameFinished,&packet);          LOGI("%d",len);                 if(len<0)                 {                    LOGI("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=AV_PICTURE_TYPE_NONE;             out_size = avcodec_encode_video(oVcc, video_outbuf, video_outbuf_size, oVFrame);             if (out_size > 0)             {                 AVPacket pkt;                 av_init_packet(&pkt);//執行此語句後pkt的pts和dts都設為no了                 if(oVcc->coded_frame && oVcc->coded_frame->key_frame)                     pkt.flags |= AV_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);//                   ret=av_interleaved_write_frame(oc,&packet);                     LOGI("%d----111111----%d----",packet.size,pkt.size);             }             frame_index++;         }         else            {          LOGI("LOGI----------------16 ");              LOGI(".....\n");             }                   #if 0                   if(ret!=0)                    {                      LOGI("while write video frame error\n");                     // exit(0);                    }                    #endif          } else if (packet.stream_index == audioindex) {  LOGI("LOGI----------------17, %d ", audioindex);  int ret = 0;  while (packet.size > 0) {  LOGI("LOGI----------------18 ");  out_buf = NULL;  if (packet.size > 0)  samples = (short *) av_fast_realloc(samples, &samples_size,  FFMAX(packet.size*sizeof  (*samples),2000)); //AVCODEC_MAX_AUDIO_FRAME_SIZE=  LOGI("LOGI----------------19 ");  ret = avcodec_decode_audio4(aCodecCtx, oAFrame, &frameFinished2,  &packet);  //                   ret = avcodec_decode_audio3(aCodecCtx,samples,&out_size,&packet);//若為音頻包,解碼該音頻包  LOGI("retretret:%d", ret);  if (ret < 0) {  LOGI("while decode audio failure\n");  exit(0);  }  packet.data += ret;  packet.size -= ret;  av_fifo_generic_write(fifo,oAFrame->data[0],oAFrame->linesize[0],NULL);  if (frameFinished2) {  //                        LOGI("----------lddfd,%d",fwrite(oAFrame->data[0], oAFrame->linesize[0], 1, pcm));  //                        fflush(pcm);  //                        int data_size = av_samples_get_buffer_size(NULL, aCodecCtx->channels,  //                        oAFrame->nb_samples,  //                        aCodecCtx->sample_fmt, 1);  //                                    fwrite(oAFrame->data[0], 1, data_size/2, pcm);  //                                    fflush(pcm);  LOGI("LOGI----------------20 ");  out_buf = (uint8_t *) samples;  AVPacket pkt;  av_init_packet(&pkt);  pkt.data = NULL;  pkt.size = 0;  ret1 = avcodec_encode_audio2(oAcc, &pkt, oAFrame,  &got_output);  if (ret1 < 0) {  fprintf(stderr, "Error encoding audio frame\n");  exit(1);  }  //            pkt.size =  avcodec_encode_audio(oAcc, audio_outbuf, audio_outbuf_size, (short int*)samples);  if (got_output) {  LOGI("dfd,");  //fwrite(pkt.data, 1, pkt.size, f);//fwrite(pkt.data, 1, pkt.size, f);不用av_interleaved_write_frame,直接寫入aac檔案就可以播放,說明解碼沒有問題。  //pkt.dts = AV_NOPTS_VALUE;  if (oAcc->coded_frame&& oAcc->coded_frame->pts != AV_NOPTS_VALUE) {                          pkt.pts= av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base);  }  LOGI("===========================");  pkt.flags |= AV_PKT_FLAG_KEY;  pkt.stream_index = audio_st->index;  LOGI("=====-=-=-=----=-=-=-=-=-=-=-");  av_write_frame(oc, &pkt);  av_free_packet(&pkt);  }  }  /** 採樣,但是不對   ReSampleContext *rsc = NULL;   rsc = av_audio_resample_init(   oAcc->channels, aCodecCtx->channels,   oAcc->sample_rate, aCodecCtx->sample_rate,   oAcc->sample_fmt, aCodecCtx->sample_fmt,   16, 10, 0, 0.8);   AVFifoBuffer *iofifo;   iofifo = av_fifo_alloc(192000*2);   int bs;   bs = audio_resample(rsc, (short *)resample_buffer, samples,   out_size/(aCodecCtx->channels*2));   ret = av_fifo_generic_write(iofifo, (uint8_t *)resample_buffer,   bs*oAcc->channels*2, NULL);   audio_outbuf_size = oAcc->frame_size * 2 * oAcc->channels;   while( av_fifo_size(iofifo) >= audio_outbuf_size )   {   ret = av_fifo_generic_read(iofifo, out_buf, audio_outbuf_size, NULL);   ret = avcodec_encode_audio(oAcc, audio_outbuf,audio_outbuf_size, (short *)out_buf);   pkt.size = ret;   pkt.stream_index= audioindex;   pkt.data= audio_outbuf;   ret = av_write_frame(oc, &pkt);   }   }**/  }  }  LOGI("----------while");  av_free_packet(&packet);       }          LOGI("LOGI----------------18 ");av_write_trailer(oc);LOGI("LOGI----------------end ");for(i = 0; i < oc->nb_streams; i++){  av_freep(&oc->streams[i]->codec);  av_freep(&oc->streams[i]);}LOGI("LOGI----------------end 1");//url_fclose(oc);av_free(oc);av_free(oVFrame);//av_free(out_buf);LOGI("LOGI----------------end 2");avcodec_close(vCodecCtx);avcodec_close(aCodecCtx);avformat_close_input(&ic);LOGI("LOGI----------------end 3");return 1;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.