#include <Windows.h> #pragma comment(lib, "avutil.lib") #pragma comment(lib, "avcodec.lib") #pragma comment(lib, "avformat.lib") #pragma comment(lib, "swscale.lib") extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" } void usage(char* szExeName) { printf("usage: %s InputFile OutputFile/n", szExeName); } char* input_file_name = NULL; char* output_file_name = NULL; int main(int argc,char **argv) { if ( 3 != argc ) { usage(argv[0]); return -1; } else { input_file_name = argv[1]; output_file_name = argv[2]; } av_register_all(); AVFormatContext *ic = av_alloc_format_context(); if (av_open_input_file(&ic,input_file_name,NULL,0,NULL)!=0) { return -1; } if (av_find_stream_info(ic)<0) { return -1; } // 列出输入文件的相关流信息,然后停顿1秒,以便有时间看清这些信息。 printf("--------------------------------/n"); dump_format(ic,0,input_file_name,0); printf("--------------------------------/n/n"); Sleep(1000); unsigned int i = 0; int videoindex = -1; int audioindex = -1; for (i=0; i<ic->nb_streams; i++) { if (ic->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) { videoindex=i; } else if (ic->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) { audioindex=i; } } AVCodecContext *vCodecCtx = NULL; if (videoindex!=-1) { vCodecCtx=ic->streams[videoindex]->codec; AVCodec *vCodec=avcodec_find_decoder(vCodecCtx->codec_id); if (vCodec==NULL) { printf("can't find video decoder/n"); return -1; } if (avcodec_open(vCodecCtx,vCodec)<0) { printf("can't open video decoder/n"); return -1; } } AVCodecContext *aCodecCtx = NULL; if (audioindex!=-1) { aCodecCtx=ic->streams[audioindex]->codec; AVCodec *aCodec=avcodec_find_decoder(aCodecCtx->codec_id); if (aCodec==NULL) { printf("can't find audio decoder/n"); return -1; } if (avcodec_open(aCodecCtx,aCodec)<0) { printf("can't open audio decoder/n"); return -1; } } AVStream *video_st=NULL; AVStream *audio_st=NULL; AVCodecContext *oVcc=NULL; AVCodecContext *oAcc=NULL; AVCodec *oVc=NULL; AVCodec *oAc=NULL; AVOutputFormat *fmt = guess_format(NULL,output_file_name,NULL); if (!fmt) { return -1; } AVFormatContext *oc = av_alloc_format_context(); if (!oc) { return -1; } oc->oformat=fmt; strcpy(oc->filename, output_file_name); if ( vCodecCtx != NULL ) { video_st=av_new_stream(oc,0); if(!video_st) { return -1; } oVcc = video_st->codec; oVcc->codec_id=CODEC_ID_H264; oVcc->codec_type=CODEC_TYPE_VIDEO; oVcc->bit_rate=vCodecCtx->bit_rate; oVcc->width=vCodecCtx->width; oVcc->height=vCodecCtx->height; oVcc->time_base=vCodecCtx->time_base; oVcc->gop_size=vCodecCtx->gop_size; 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; oVc=avcodec_find_encoder(CODEC_ID_H264); if(!oVc) { return -1; } if(avcodec_open(oVcc,oVc)<0) { return -1; } } if ( aCodecCtx != NULL ) { audio_st=av_new_stream(oc,1); if(!audio_st) { return -1; } avcodec_get_context_defaults(audio_st->codec); 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; oAc=avcodec_find_encoder(CODEC_ID_MP3); if(!oAc) { return -1; } if(avcodec_open(oAcc,oAc)<0) { return -1; } } if (av_set_parameters(oc, NULL) < 0) { return -1; } 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); // 列出输出文件的相关流信息,然后停顿1秒,以便有时间看清这些信息。 printf("--------------------------------/n"); dump_format(oc,0,output_file_name,1); printf("--------------------------------/n/n"); Sleep(1000); /* if (url_exist(output_file_name)) { // 如果输出文件已存在,则退出。 return -1; }*/ if (!(oc->flags & AVFMT_NOFILE)) { if(url_fopen(&oc->pb,output_file_name,URL_WRONLY)<0) { return -1; } } if (!oc->nb_streams) { fprintf(stderr,"output file dose not contain any stream/n"); return -1; } AVPacket packet; uint8_t *ptr,*out_buf; int out_size; static short *samples=NULL; static unsigned int samples_size=0; int frame_index=0,ret,len,frameFinished; const int video_outbuf_size = 512*1024; // 512KB uint8_t *video_outbuf = (unsigned char *)malloc(video_outbuf_size); const int audio_outbuf_size = 16*1024; // 16KB uint8_t *audio_outbuf = (unsigned char *)malloc(audio_outbuf_size); AVFrame *oVFrame = avcodec_alloc_frame(); if (av_write_header(oc)<0) { fprintf(stderr, "Could not write header for output file/n"); return -1; } 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("avcodec_decode_video is err!/n"); return -1; } 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; if ( av_write_frame(oc, &pkt) != 0 ) { printf("v av_write_frame is err!/n"); return -1; } else { printf("v.../n"); } } frame_index++; } } else if (packet.stream_index==audioindex) { len=packet.size; ptr=packet.data; while (len>0) { out_buf=NULL; out_size=0; if (&packet) { samples = (short *)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("avcodec_decode_audio is err!/n"); return -1; } 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, (short int*)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) { printf("a av_write_frame is err!/n"); return -1; } else { printf("a.../n"); } } } av_free_packet(&packet); } if (av_write_trailer(oc)<0) { return -1; } for(i = 0; i < oc->nb_streams; i++) { av_freep(&oc->streams[i]->codec); av_freep(&oc->streams[i]); } if ( video_outbuf ) free(video_outbuf); if ( audio_outbuf ) free(audio_outbuf); if ( oc->pb ) url_fclose(oc->pb); if ( oVFrame ) av_free(oVFrame); if ( vCodecCtx ) avcodec_close(vCodecCtx); if ( aCodecCtx ) avcodec_close(aCodecCtx); if ( ic ) av_close_input_file(ic); if ( oc ) av_free(oc); printf("Ok.../n"); return 0; }