FFMPEG_avi转码到mp4(aac+h264)源码

来源:互联网 发布:网络翻墙用什么软件好 编辑:程序博客网 时间:2024/04/29 06:45
001#include <ffmpeg/avcodec.h>
002#include <ffmpeg/avformat.h>
003#include <stdio.h>
004#include <ffmpeg/avutil.h>
005#include <stdio.h>
006#include <stdlib.h>
007#include <string.h>
008void pstrcpy(char *buf, int buf_size, const char *str)
009{
010    int c;//why int here
011    char *q = buf;
012 
013    if (buf_size <= 0)
014        return;
015 
016    for(;;) {
017        c = *str++;
018        if (c == 0 || q >= buf + buf_size - 1)
019            break;
020        *q++ = c;
021    }
022    *q = '\0';
023}
024main(int argc,char **argv)
025{  
026  const char *input_file_name="/home/movie.avi";
027  av_register_all();//注册库中所有可用的文件格式和编码器
028  AVFormatContext *ic;
029  //输入文件处理部分
030  ic=av_alloc_format_context();
031  if(av_open_input_file(&ic,input_file_name,NULL,0,NULL)!=0)
032  {
033     printf("can't open the file %s\n",input_file_name);
034     exit(1);
035  }//打开输入文件 
036  if(av_find_stream_info(ic)<0)
037  {
038     printf("can't find suitable codec parameters\n");
039     exit(1);
040  }//取出流信息
041   
042  dump_format(ic,0,input_file_name,0);//列出输入文件的相关流信息
043  int i;
044  int videoindex=-1;int audioindex=-1;
045  for(i=0;i<ic->nb_streams;i++)
046  {  
047     if(ic->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
048         {
049            videoindex=i;
050          //printf("video\n");
051         }
052         else if(ic->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO)
053         {
054          //printf("audio\n");
055            audioindex=i;
056         }
057  }
058   if(videoindex==-1)
059   {
060          printf("can't find video stream\n");
061          exit(1);
062   }//没有找到视频流
063    
064    
065  AVCodecContext *vCodecCtx;
066  vCodecCtx=ic->streams[videoindex]->codec;//取得视频流编码上下文指针
067  AVCodec *vCodec;
068  vCodec=avcodec_find_decoder(vCodecCtx->codec_id);
069  if(vCodec==NULL)
070  {
071     printf("can't find suitable video decoder\n");
072     exit(1);
073  }//找到合适的视频解码器
074  if(avcodec_open(vCodecCtx,vCodec)<0)
075  {
076     printf("can't open the video decoder\n");
077     exit(1);
078  }//打开该视频解码器
079   
080   
081   if(audioindex==-1)
082     {
083        printf("can't find audio stream\n");
084        exit(1);
085     }//没有找到音频流
086  AVCodecContext *aCodecCtx;
087  aCodecCtx=ic->streams[audioindex]->codec;
088  AVCodec *aCodec;
089  aCodec=avcodec_find_decoder(aCodecCtx->codec_id);
090  if(aCodec==NULL)
091  {
092     printf("can't find suitable audio decoder\n");
093     exit(1);
094  }//找到合适的音频解码器
095  if(avcodec_open(aCodecCtx,aCodec)<0)
096  {
097     printf("can't open the audio decoder\n");
098     exit(1);
099  }//打开该音频解码器
100   
101   
102//下面为输出文件处理部分
103    const char *output_file_name="/home/result.aac";
104    AVOutputFormat *fmt;
105    AVFormatContext *oc;
106    AVCodecContext *oVcc,*oAcc;
107    AVCodec *oVc,*oAc;
108    AVStream *video_st,*audio_st;
109    AVFrame *oVFrame,*oAFrame;
110    double video_pts;
111    oVFrame=avcodec_alloc_frame();
112    fmt=guess_format(NULL,output_file_name,NULL);
113    if(!fmt)
114    {
115           printf("could not deduce output format from outfile extension\n");
116           exit(0);
117    }//判断是否可以判断输出文件的编码格式
118    oc=av_alloc_format_context();
119    if(!oc)
120    {
121           printf("Memory error\n");
122           exit(0);
123    }
124    oc->oformat=fmt;
125   pstrcpy(oc->filename,sizeof(oc->filename),output_file_name);
126   
127    video_st=av_new_stream(oc,0);
128    if(!video_st)
129    {
130          printf("could not alloc video stream\n");
131          exit(0);
132    }
133    oVcc=avcodec_alloc_context();
134    oVcc=video_st->codec;
135    oVcc->codec_id=CODEC_ID_H264;
136    oVcc->codec_type=CODEC_TYPE_VIDEO;
137    oVcc->bit_rate=1000000;
138    oVcc->width=320;
139    oVcc->height=240;
140    oVcc->time_base=vCodecCtx->time_base;
141    oVcc->gop_size=vCodecCtx->gop_size;
142    //oVcc->pix_fmt=vCodecCtx->pix_fmt;
143    oVcc->pix_fmt=vCodecCtx->pix_fmt;
144    oVcc->max_b_frames=vCodecCtx->max_b_frames;
145    video_st->r_frame_rate=ic->streams[videoindex]->r_frame_rate;// frame rate
146   // audio_st=av_new_stream(oc,oc->nb_streams);   //
147    audio_st=av_new_stream(oc,1);
148    if(!audio_st)
149    {
150           printf("could not alloc audio stream\n");
151           exit(0);
152    
153   // avcodec_get_context_defaults2(audio_st->codec,CODEC_TYPE_AUDIO);
154   avcodec_get_context_defaults(audio_st->codec);//  do what
155    oAcc=avcodec_alloc_context();
156    oAcc=audio_st->codec;
157    oAcc->codec_id=CODEC_ID_AAC;
158    oAcc->codec_type=CODEC_TYPE_AUDIO;
159    oAcc->bit_rate=aCodecCtx->bit_rate;// bit rate
160    oAcc->sample_rate=aCodecCtx->sample_rate;
161    oAcc->channels=2;
162    if (av_set_parameters(oc, NULL) < 0)
163    {
164           printf"Invalid output format parameters\n");                       
165              exit(0);                             
166    }//设置必要的输出参数
167    strcpy(oc->title,ic->title);
168    strcpy(oc->author,ic->author);
169    strcpy(oc->copyright,ic->copyright);
170    strcpy(oc->comment,ic->comment);
171    strcpy(oc->album,ic->album);
172    oc->year=ic->year;
173    oc->track=ic->track;
174    strcpy(oc->genre,ic->genre);
175    dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息
176    oVc=avcodec_find_encoder(CODEC_ID_H264);
177    if(!oVc)
178    {
179       printf("can't find suitable video encoder\n");
180           exit(0);
181    }//找到合适的视频编码器
182    if(avcodec_open(oVcc,oVc)<0)
183    {
184           printf("can't open the output video codec\n");
185           exit(0);
186    }//打开视频编码器
187    oAc=avcodec_find_encoder(CODEC_ID_AAC);
188    if(!oAc)
189    {
190           printf("can't find suitable audio encoder\n");
191           exit(0);
192    }//找到合适的音频编码器
193    if(avcodec_open(oAcc,oAc)<0)
194    {
195           printf("can't open the output audio codec");
196           exit(0);
197    }//打开音频编码器
198    /*if(url_exist(output_file_name))
199    {
200       printf("the output file name %s has exist,please select other\n",output_file_name);
201       exit(0);
202    }//判断该输出文件是否已经存在*/
203    if (!(oc->flags & AVFMT_NOFILE))
204    {
205       if(url_fopen(&oc->pb,output_file_name,URL_WRONLY)<0)
206       {
207              printf("can't open the output file %s\n",output_file_name);
208              exit(0);
209       }//打开输出文件
210    }
211    if(!oc->nb_streams)
212    {
213           fprintf(stderr,"output file dose not contain any stream\n");
214           exit(0);
215    }//查看输出文件是否含有流信息
216  if(av_write_header(oc)<0)
217  {
218      fprintf(stderr, "Could not write header for output file\n");
219      exit(1);
220  }
221   
222AVPacket packet;
223  uint8_t *ptr,*out_buf;
224  int out_size;
225  static short *samples=NULL;
226  static unsigned int samples_size=0;
227  uint8_t *video_outbuf,*audio_outbuf;
228  int video_outbuf_size,audio_outbuf_size;
229  video_outbuf_size=400000;
230  video_outbuf= (unsigned char *) malloc(video_outbuf_size);
231  audio_outbuf_size = 10000;
232    //audio_outbuf = av_malloc(audio_outbuf_size);
233  audio_outbuf = (unsigned char *) malloc(audio_outbuf_size);
234  int flag;int frameFinished;int len;int frame_index=0,ret;
235          while(av_read_frame(ic,&packet)>=0)//从输入文件中读取一个包
236       {
237          if(packet.stream_index==videoindex)//判断是否为当前视频流中的包
238          {
239         len=avcodec_decode_video(vCodecCtx,oVFrame,&frameFinished,packet.data,packet.size);//若为视频包,解码该视频包
240                 if(len<0)
241                 {
242                    printf("Error while decoding\n");
243                    exit(0);
244                 }
245      
246         if(frameFinished)//判断视频祯是否读完
247          
248         {
249             fflush(stdout);
250             oVFrame->pts=av_rescale(frame_index,AV_TIME_BASE*(int64_t)oVcc->time_base.num,oVcc->time_base.den);
251             oVFrame->pict_type=0;
252             out_size = avcodec_encode_video(oVcc, video_outbuf, video_outbuf_size, oVFrame);  
253             if (out_size > 0)           
254             {                 
255                 AVPacket pkt;              
256                 av_init_packet(&pkt);                             
257                 if(oVcc->coded_frame && oVcc->coded_frame->key_frame)                                      
258                     pkt.flags |= PKT_FLAG_KEY;                                      
259                     pkt.flags = packet.flags;                    
260                     pkt.stream_index= video_st->index;                                              
261                     pkt.data= video_outbuf;                                                        
262                     pkt.size= out_size;                                            
263                     ret=av_write_frame(oc, &pkt);                                      
264             }
265             frame_index++;
266         }
267         else
268            {
269              printf(".....\n");                                      
270             }
271                   #if 0
272                   if(ret!=0)
273                    {
274                      printf("while write video frame error\n");
275                     // exit(0);
276                    }
277                    #endif
278                   
279          }else if(packet.stream_index==audioindex)
280      {
281         len=packet.size;
282         ptr=packet.data;
283             int ret=0;
284             while(len>0)
285             {
286                    out_buf=NULL;
287                    out_size=0;
288                    if(&packet)
289               samples=(short *)av_fast_realloc(samples,&samples_size,FFMAX(packet.size*sizeof
290(*samples),AVCODEC_MAX_AUDIO_FRAME_SIZE));
291                    out_size=samples_size;
292                    ret=avcodec_decode_audio(aCodecCtx,samples,&out_size,ptr,len);//若为音频包,解码该音频包
293                    if(ret<0)
294                    {
295                       printf("while decode audio failure\n");
296                       exit(0);
297                    }
298            fflush(stdout);
299            ptr+=ret;
300            len-=ret;
301            if(out_size<=0)
302               continue;
303            out_buf=(uint8_t *)samples;
304            AVPacket pkt;
305            av_init_packet(&pkt);
306            pkt.size= avcodec_encode_audio(oAcc, audio_outbuf, audio_outbuf_size, (short int*)out_buf);
307            pkt.pts= av_rescale_q(oAcc->coded_frame->pts, oAcc->time_base, audio_st->time_base);
308            pkt.flags |= PKT_FLAG_KEY;
309            pkt.stream_index= audioindex;
310            pkt.data= audio_outbuf;
311            
312          #if 1
313            if (av_write_frame(oc, &pkt) != 0)
314                    {
315               fprintf(stderr, "Error while writing audio frame\n");
316               exit(1);
317                }
318              #endif 
319             }
320          }
321          av_free_packet(&packet);
322       }
323       
324av_write_trailer(oc);
325 
326for(i = 0; i < oc->nb_streams; i++)
327{           
328  av_freep(&oc->streams[i]->codec);                      
329  av_freep(&oc->streams[i]);                          
330}
331//url_fclose(oc);
332av_free(oc);
333av_free(oVFrame);
334av_free(out_buf);
335avcodec_close(vCodecCtx);
336avcodec_close(aCodecCtx);
337av_close_input_file(ic);
338 
339}
0 0