Mercurial > mplayer.hg
comparison mencoder.c @ 8585:27da710563c2
the long-waited MUXER layer, and new MPEG-PS muxer
patch by Andriy N. Gritsenko <andrej@lucky.net>
author | arpi |
---|---|
date | Fri, 27 Dec 2002 22:43:20 +0000 |
parents | bcf1b010bf14 |
children | 824481376632 |
comparison
equal
deleted
inserted
replaced
8584:2d4328af7ea9 | 8585:27da710563c2 |
---|---|
45 | 45 |
46 #include "libmpdemux/stream.h" | 46 #include "libmpdemux/stream.h" |
47 #include "libmpdemux/demuxer.h" | 47 #include "libmpdemux/demuxer.h" |
48 #include "libmpdemux/stheader.h" | 48 #include "libmpdemux/stheader.h" |
49 #include "libmpdemux/mp3_hdr.h" | 49 #include "libmpdemux/mp3_hdr.h" |
50 #include "libmpdemux/aviwrite.h" | 50 #include "libmpdemux/muxer.h" |
51 | 51 |
52 | 52 |
53 #include "libvo/video_out.h" | 53 #include "libvo/video_out.h" |
54 | 54 |
55 #include "libao2/afmt.h" | 55 #include "libao2/afmt.h" |
105 static char** audio_fm_list=NULL; // override audio codec family | 105 static char** audio_fm_list=NULL; // override audio codec family |
106 static char** video_fm_list=NULL; // override video codec family | 106 static char** video_fm_list=NULL; // override video codec family |
107 | 107 |
108 static int out_audio_codec=-1; | 108 static int out_audio_codec=-1; |
109 static int out_video_codec=-1; | 109 static int out_video_codec=-1; |
110 | |
111 int out_file_format=MUXER_TYPE_AVI; // default to AVI | |
110 | 112 |
111 // audio stream skip/resync functions requires only for seeking. | 113 // audio stream skip/resync functions requires only for seeking. |
112 // (they should be implemented in the audio codec layer) | 114 // (they should be implemented in the audio codec layer) |
113 //void skip_audio_frame(sh_audio_t *sh_audio){} | 115 //void skip_audio_frame(sh_audio_t *sh_audio){} |
114 //void resync_audio_stream(sh_audio_t *sh_audio){} | 116 //void resync_audio_stream(sh_audio_t *sh_audio){} |
299 static void exit_sighandler(int x){ | 301 static void exit_sighandler(int x){ |
300 at_eof=1; | 302 at_eof=1; |
301 interrupted=1; | 303 interrupted=1; |
302 } | 304 } |
303 | 305 |
304 static aviwrite_t* muxer=NULL; | 306 static muxer_t* muxer=NULL; |
305 static FILE* muxer_f=NULL; | 307 static FILE* muxer_f=NULL; |
306 | 308 |
307 // callback for ve_*.c: | 309 // callback for ve_*.c: |
308 void mencoder_write_chunk(aviwrite_stream_t *s,int len,unsigned int flags){ | 310 void mencoder_write_chunk(muxer_stream_t *s,int len,unsigned int flags){ |
309 aviwrite_write_chunk(muxer,s,muxer_f,len,flags); | 311 muxer_write_chunk(muxer,s,muxer_f,len,flags); |
310 } | 312 } |
311 | 313 |
312 extern void print_wave_header(WAVEFORMATEX *h); | 314 extern void print_wave_header(WAVEFORMATEX *h); |
313 | 315 |
314 int main(int argc,char* argv[]){ | 316 int main(int argc,char* argv[]){ |
333 uint32_t videosamples=1; | 335 uint32_t videosamples=1; |
334 uint32_t skippedframes=0; | 336 uint32_t skippedframes=0; |
335 uint32_t duplicatedframes=0; | 337 uint32_t duplicatedframes=0; |
336 uint32_t badframes=0; | 338 uint32_t badframes=0; |
337 | 339 |
338 aviwrite_stream_t* mux_a=NULL; | 340 muxer_stream_t* mux_a=NULL; |
339 aviwrite_stream_t* mux_v=NULL; | 341 muxer_stream_t* mux_v=NULL; |
340 off_t muxer_f_size=0; | 342 off_t muxer_f_size=0; |
341 | 343 |
342 #ifdef HAVE_MP3LAME | 344 #ifdef HAVE_MP3LAME |
343 lame_global_flags *lame; | 345 lame_global_flags *lame; |
344 #endif | 346 #endif |
598 if(!muxer_f) { | 600 if(!muxer_f) { |
599 printf(MSGTR_CannotOpenOutputFile, out_filename); | 601 printf(MSGTR_CannotOpenOutputFile, out_filename); |
600 mencoder_exit(1,NULL); | 602 mencoder_exit(1,NULL); |
601 } | 603 } |
602 | 604 |
603 muxer=aviwrite_new_muxer(); | 605 muxer=muxer_new_muxer(out_file_format); |
604 | 606 |
605 // ============= VIDEO =============== | 607 // ============= VIDEO =============== |
606 | 608 |
607 mux_v=aviwrite_new_stream(muxer,AVIWRITE_TYPE_VIDEO); | 609 mux_v=muxer_new_stream(muxer,MUXER_TYPE_VIDEO); |
608 | 610 |
609 mux_v->buffer_size=0x200000; // 2MB | 611 mux_v->buffer_size=0x200000; // 2MB |
610 mux_v->buffer=malloc(mux_v->buffer_size); | 612 mux_v->buffer=malloc(mux_v->buffer_size); |
611 | 613 |
612 mux_v->source=sh_video; | 614 mux_v->source=sh_video; |
696 //if(demuxer->file_format!=DEMUXER_TYPE_AVI) pts_from_bps=0; // it must be 0 for mpeg/asf! | 698 //if(demuxer->file_format!=DEMUXER_TYPE_AVI) pts_from_bps=0; // it must be 0 for mpeg/asf! |
697 | 699 |
698 // ============= AUDIO =============== | 700 // ============= AUDIO =============== |
699 if(sh_audio){ | 701 if(sh_audio){ |
700 | 702 |
701 mux_a=aviwrite_new_stream(muxer,AVIWRITE_TYPE_AUDIO); | 703 mux_a=muxer_new_stream(muxer,MUXER_TYPE_AUDIO); |
702 | 704 |
703 mux_a->buffer_size=0x100000; //16384; | 705 mux_a->buffer_size=0x100000; //16384; |
704 mux_a->buffer=malloc(mux_a->buffer_size); | 706 mux_a->buffer=malloc(mux_a->buffer_size); |
705 | 707 |
706 mux_a->source=sh_audio; | 708 mux_a->source=sh_audio; |
807 } | 809 } |
808 | 810 |
809 } // if(sh_audio) | 811 } // if(sh_audio) |
810 | 812 |
811 printf(MSGTR_WritingAVIHeader); | 813 printf(MSGTR_WritingAVIHeader); |
812 aviwrite_write_header(muxer,muxer_f); | 814 muxer_write_header(muxer,muxer_f); |
813 | 815 |
814 decoded_frameno=0; | 816 decoded_frameno=0; |
815 | 817 |
816 if(sh_audio) | 818 if(sh_audio) |
817 switch(mux_a->codec){ | 819 switch(mux_a->codec){ |
874 // > 1. do the first pass for the whole file, and use -ss for 2nd/3rd pases only | 876 // > 1. do the first pass for the whole file, and use -ss for 2nd/3rd pases only |
875 // > 2. do all the 3 passes with the same -ss value | 877 // > 2. do all the 3 passes with the same -ss value |
876 // this line enables behaviour 1. (and kills 2. at the same time): | 878 // this line enables behaviour 1. (and kills 2. at the same time): |
877 // if(demuxer2) demux_seek(demuxer2, d, 1); | 879 // if(demuxer2) demux_seek(demuxer2, d, 1); |
878 } | 880 } |
881 | |
882 if (out_file_format == MUXER_TYPE_MPEG) | |
883 { | |
884 if (audio_preload > 0.4) { | |
885 fprintf(stderr,"Limiting audio preload to 0.4s\n"); | |
886 audio_preload = 0.4; | |
887 } | |
888 if (audio_density < 4) { | |
889 fprintf(stderr,"Increasing audio density to 4\n"); | |
890 audio_preload = 4; | |
891 } | |
892 } | |
879 | 893 |
880 if(tv_param_on == 1) | 894 if(tv_param_on == 1) |
881 { | 895 { |
882 fprintf(stderr,"Forcing audio preload to 0, max pts correction to 0\n"); | 896 fprintf(stderr,"Forcing audio preload to 0, max pts correction to 0\n"); |
883 audio_preload = 0.0; | 897 audio_preload = 0.0; |
981 break; | 995 break; |
982 #endif | 996 #endif |
983 } | 997 } |
984 } | 998 } |
985 if(len<=0) break; // EOF? | 999 if(len<=0) break; // EOF? |
986 aviwrite_write_chunk(muxer,mux_a,muxer_f,len,0x10); | 1000 muxer_write_chunk(muxer,mux_a,muxer_f,len,0x10); |
987 if(!mux_a->h.dwSampleSize && mux_a->timer>0) | 1001 if(!mux_a->h.dwSampleSize && mux_a->timer>0) |
988 mux_a->wf->nAvgBytesPerSec=0.5f+(double)mux_a->size/mux_a->timer; // avg bps (VBR) | 1002 mux_a->wf->nAvgBytesPerSec=0.5f+(double)mux_a->size/mux_a->timer; // avg bps (VBR) |
989 if(mux_a->buffer_len>=len){ | 1003 if(mux_a->buffer_len>=len){ |
990 mux_a->buffer_len-=len; | 1004 mux_a->buffer_len-=len; |
991 memcpy(mux_a->buffer,mux_a->buffer+len,mux_a->buffer_len); | 1005 memcpy(mux_a->buffer,mux_a->buffer+len,mux_a->buffer_len); |
1061 ptimer_start = GetTimerMS(); | 1075 ptimer_start = GetTimerMS(); |
1062 | 1076 |
1063 switch(mux_v->codec){ | 1077 switch(mux_v->codec){ |
1064 case VCODEC_COPY: | 1078 case VCODEC_COPY: |
1065 mux_v->buffer=start; | 1079 mux_v->buffer=start; |
1066 if(skip_flag<=0) aviwrite_write_chunk(muxer,mux_v,muxer_f,in_size,(sh_video->ds->flags&1)?0x10:0); | 1080 if(skip_flag<=0) muxer_write_chunk(muxer,mux_v,muxer_f,in_size,(sh_video->ds->flags&1)?0x10:0); |
1067 break; | 1081 break; |
1068 case VCODEC_FRAMENO: | 1082 case VCODEC_FRAMENO: |
1069 mux_v->buffer=(unsigned char *)&decoded_frameno; // tricky | 1083 mux_v->buffer=(unsigned char *)&decoded_frameno; // tricky |
1070 if(skip_flag<=0) aviwrite_write_chunk(muxer,mux_v,muxer_f,sizeof(int),0x10); | 1084 if(skip_flag<=0) muxer_write_chunk(muxer,mux_v,muxer_f,sizeof(int),0x10); |
1071 break; | 1085 break; |
1072 default: | 1086 default: |
1073 // decode_video will callback down to ve_*.c encoders, through the video filters | 1087 // decode_video will callback down to ve_*.c encoders, through the video filters |
1074 blit_frame=decode_video(sh_video,start,in_size,(skip_flag>0)?1:0); | 1088 blit_frame=decode_video(sh_video,start,in_size,(skip_flag>0)?1:0); |
1075 if(!blit_frame){ | 1089 if(!blit_frame){ |
1076 badframes++; | 1090 badframes++; |
1077 if(skip_flag<=0){ | 1091 if(skip_flag<=0){ |
1078 // unwanted skipping of a frame, what to do? | 1092 // unwanted skipping of a frame, what to do? |
1079 if(skip_limit==0){ | 1093 if(skip_limit==0){ |
1080 // skipping not allowed -> write empty frame: | 1094 // skipping not allowed -> write empty frame: |
1081 aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0); | 1095 muxer_write_chunk(muxer,mux_v,muxer_f,0,0); |
1082 } else { | 1096 } else { |
1083 // skipping allowed -> skip it and distriubute timer error: | 1097 // skipping allowed -> skip it and distriubute timer error: |
1084 v_timer_corr-=(float)mux_v->h.dwScale/mux_v->h.dwRate; | 1098 v_timer_corr-=(float)mux_v->h.dwScale/mux_v->h.dwRate; |
1085 } | 1099 } |
1086 } | 1100 } |
1093 if(skip_flag<0){ | 1107 if(skip_flag<0){ |
1094 // duplicate frame | 1108 // duplicate frame |
1095 if(!tv_param_on && !verbose) printf(MSGTR_DuplicateFrames,-skip_flag); | 1109 if(!tv_param_on && !verbose) printf(MSGTR_DuplicateFrames,-skip_flag); |
1096 while(skip_flag<0){ | 1110 while(skip_flag<0){ |
1097 duplicatedframes++; | 1111 duplicatedframes++; |
1098 aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0); | 1112 muxer_write_chunk(muxer,mux_v,muxer_f,0,0); |
1099 ++skip_flag; | 1113 ++skip_flag; |
1100 } | 1114 } |
1101 } else | 1115 } else |
1102 if(skip_flag>0){ | 1116 if(skip_flag>0){ |
1103 // skip frame | 1117 // skip frame |
1252 mux_a->h.dwRate,((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nBlockSize); | 1266 mux_a->h.dwRate,((MPEGLAYER3WAVEFORMAT*)(mux_a->wf))->nBlockSize); |
1253 } | 1267 } |
1254 #endif | 1268 #endif |
1255 | 1269 |
1256 printf(MSGTR_WritingAVIIndex); | 1270 printf(MSGTR_WritingAVIIndex); |
1257 aviwrite_write_index(muxer,muxer_f); | 1271 muxer_write_index(muxer,muxer_f); |
1258 muxer_f_size=ftello(muxer_f); | 1272 muxer_f_size=ftello(muxer_f); |
1259 printf(MSGTR_FixupAVIHeader); | 1273 printf(MSGTR_FixupAVIHeader); |
1260 fseek(muxer_f,0,SEEK_SET); | 1274 fseek(muxer_f,0,SEEK_SET); |
1261 aviwrite_write_header(muxer,muxer_f); // update header | 1275 muxer_write_header(muxer,muxer_f); // update header |
1262 if(ferror(muxer_f) || fclose(muxer_f) != 0) { | 1276 if(ferror(muxer_f) || fclose(muxer_f) != 0) { |
1263 mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile, out_filename); | 1277 mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_ErrorWritingFile, out_filename); |
1264 mencoder_exit(1, NULL); | 1278 mencoder_exit(1, NULL); |
1265 } | 1279 } |
1266 if(vobsub_writer) | 1280 if(vobsub_writer) |