avi转码到mp4(aac&#43;h264)源码分享看了liuxinhongxin 前辈的源码很受启发&#xff0c;但在播放时头信息会有错误&#xff0c;略作修改&#xff0c;代码如下&#xff1a; #include #include #include #include #include #include #include void pstrcpy(char *buf, int buf_size, const char *str) { int c;//why int here char *q &#61; 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;i { 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 { 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); |