2001-12-08 13:21:23 +01:00
# define VCODEC_COPY 0
2001-12-07 00:59:46 +01:00
# define VCODEC_FRAMENO 1
2002-04-11 04:52:03 +02:00
// real codecs:
2001-12-07 00:59:46 +01:00
# define VCODEC_DIVX4 2
2001-12-15 18:12:20 +01:00
# define VCODEC_LIBAVCODEC 4
2002-01-31 01:38:53 +01:00
# define VCODEC_RAWRGB 6
2002-02-07 21:22:03 +01:00
# define VCODEC_VFW 7
2002-04-12 23:50:38 +02:00
# define VCODEC_LIBDV 8
2002-09-21 14:41:29 +02:00
# define VCODEC_XVID 9
2002-12-16 02:49:39 +01:00
# define VCODEC_QTVIDEO 10
2001-12-07 00:59:46 +01:00
2001-12-08 14:30:06 +01:00
# define ACODEC_COPY 0
2001-10-31 01:25:28 +01:00
# define ACODEC_PCM 1
# define ACODEC_VBRMP3 2
2002-01-27 01:43:57 +01:00
# define ACODEC_NULL 3
2001-10-29 02:11:18 +01:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <signal.h>
2002-04-12 12:40:38 +02:00
# include <sys/time.h>
2001-10-29 02:11:18 +01:00
2001-10-31 17:08:01 +01:00
# include "config.h"
2002-09-29 21:26:40 +02:00
2001-11-18 20:12:25 +01:00
# include "version.h"
2002-09-29 21:26:40 +02:00
# include "mp_msg.h"
2001-10-29 02:11:18 +01:00
# include "help_mp.h"
2001-11-18 20:12:25 +01:00
static char * banner_text =
" \n \n "
2002-08-07 20:24:25 +02:00
" MEncoder " VERSION MSGTR_MEncoderCopyright
2001-11-18 20:12:25 +01:00
" \n " ;
2001-12-04 22:35:18 +01:00
# include "cpudetect.h"
2001-10-29 02:11:18 +01:00
# include "codec-cfg.h"
2002-11-12 02:56:42 +01:00
# ifdef NEW_CONFIG
# include "m_option.h"
# include "m_config.h"
# include "parser-mecmd.h"
# else
2002-01-25 00:02:59 +01:00
# include "cfgparser.h"
2002-11-12 02:56:42 +01:00
# include "playtree.h"
# endif
2001-10-29 02:11:18 +01:00
2002-09-29 21:26:40 +02:00
# include "libmpdemux/stream.h"
# include "libmpdemux/demuxer.h"
# include "libmpdemux/stheader.h"
# include "libmpdemux/mp3_hdr.h"
2002-12-27 23:43:20 +01:00
# include "libmpdemux/muxer.h"
2001-10-29 02:11:18 +01:00
# include "libvo/video_out.h"
2002-10-06 00:55:45 +02:00
# include "libao2/afmt.h"
2002-09-22 02:43:14 +02:00
# include "libmpcodecs/mp_image.h"
2002-04-13 21:14:34 +02:00
# include "libmpcodecs/dec_audio.h"
# include "libmpcodecs/dec_video.h"
2002-06-27 21:33:28 +02:00
# include "libmpcodecs/vf.h"
2001-10-30 22:55:28 +01:00
2002-09-22 02:43:14 +02:00
// for MPEGLAYER3WAVEFORMAT:
# include "loader/wine/mmreg.h"
2001-12-06 23:27:09 +01:00
# ifdef HAVE_MP3LAME
2002-06-27 21:33:28 +02:00
# undef CDECL
2001-10-31 17:08:01 +01:00
# include <lame/lame.h>
2001-12-06 23:27:09 +01:00
# endif
2001-10-31 01:25:28 +01:00
2001-12-16 12:37:23 +01:00
# ifdef HAVE_LIBCSS
# include "libmpdemux/dvdauth.h"
# endif
2001-12-01 02:29:25 +01:00
# include <inttypes.h>
2002-09-29 21:26:40 +02:00
# include "libvo/fastmemcpy.h"
2001-12-08 14:30:06 +01:00
2002-09-22 04:33:28 +02:00
# include "linux/timer.h"
2002-04-07 04:12:15 +02:00
int vo_doublebuffering = 0 ;
int vo_directrendering = 0 ;
int vo_config_count = 0 ;
2002-01-27 19:39:53 +01:00
2001-10-29 02:11:18 +01:00
//--------------------------
// cache2:
2002-10-24 00:07:29 +02:00
int stream_cache_size = - 1 ;
2001-10-29 02:11:18 +01:00
# ifdef USE_STREAM_CACHE
extern int cache_fill_status ;
# else
# define cache_fill_status 0
# endif
2001-11-02 02:25:13 +01:00
int vcd_track = 0 ;
int audio_id = - 1 ;
int video_id = - 1 ;
int dvdsub_id = - 1 ;
2002-03-29 04:17:57 +01:00
int vobsub_id = - 1 ;
2002-09-29 21:26:40 +02:00
static char * audio_lang = NULL ;
static char * dvdsub_lang = NULL ;
2002-03-29 04:17:57 +01:00
static char * spudec_ifo = NULL ;
2001-11-02 02:25:13 +01:00
2002-09-29 21:26:40 +02:00
static char * * audio_codec_list = NULL ; // override audio codec
static char * * video_codec_list = NULL ; // override video codec
static char * * audio_fm_list = NULL ; // override audio codec family
static char * * video_fm_list = NULL ; // override video codec family
2001-10-29 02:11:18 +01:00
2002-09-29 21:26:40 +02:00
static int out_audio_codec = - 1 ;
static int out_video_codec = - 1 ;
2002-02-10 01:07:34 +01:00
2002-12-27 23:43:20 +01:00
int out_file_format = MUXER_TYPE_AVI ; // default to AVI
2001-10-29 02:11:18 +01:00
// audio stream skip/resync functions requires only for seeking.
// (they should be implemented in the audio codec layer)
//void skip_audio_frame(sh_audio_t *sh_audio){}
//void resync_audio_stream(sh_audio_t *sh_audio){}
2001-11-02 02:25:13 +01:00
int verbose = 0 ; // must be global!
2001-10-29 02:11:18 +01:00
double video_time_usage = 0 ;
double vout_time_usage = 0 ;
2002-02-24 12:23:48 +01:00
double max_video_time_usage = 0 ;
double max_vout_time_usage = 0 ;
2002-02-24 16:54:13 +01:00
double cur_video_time_usage = 0 ;
double cur_vout_time_usage = 0 ;
2002-02-24 18:10:06 +01:00
int benchmark = 0 ;
2001-10-29 02:11:18 +01:00
2001-11-01 03:31:23 +01:00
// A-V sync:
int delay_corrected = 1 ;
static float default_max_pts_correction = - 1 ; //0.01f;
static float max_pts_correction = 0 ; //default_max_pts_correction;
static float c_total = 0 ;
2002-09-29 21:26:40 +02:00
static float audio_preload = 0.5 ;
static float audio_delay = 0.0 ;
static int audio_density = 2 ;
2002-08-01 10:39:33 +02:00
2002-09-29 21:26:40 +02:00
static float force_fps = 0 ;
static float force_ofps = 0 ; // set to 24 for inverse telecine
2002-04-15 04:33:05 +02:00
static int skip_limit = - 1 ;
2001-10-29 02:11:18 +01:00
2002-09-29 21:26:40 +02:00
static int force_srate = 0 ;
2002-10-06 13:23:02 +02:00
static int audio_output_format = 0 ;
2001-11-02 02:25:13 +01:00
2002-07-08 23:44:51 +02:00
char * vobsub_out = NULL ;
unsigned int vobsub_out_index = 0 ;
char * vobsub_out_id = NULL ;
2001-11-02 04:22:33 +01:00
char * out_filename = " test.avi " ;
2001-12-22 15:32:08 +01:00
char * force_fourcc = NULL ;
2002-04-11 04:52:03 +02:00
char * passtmpfile = " divx2pass.log " ;
2001-11-03 01:44:02 +01:00
static int play_n_frames = - 1 ;
2002-06-28 19:13:18 +02:00
static int play_n_frames_mf = - 1 ;
2001-11-03 01:44:02 +01:00
2002-04-17 23:51:18 +02:00
# include "libvo/font_load.h"
# include "libvo/sub.h"
// sub:
char * font_name = NULL ;
float font_factor = 0.75 ;
char * sub_name = NULL ;
float sub_delay = 0 ;
float sub_fps = 0 ;
int sub_auto = 0 ;
2002-07-25 05:37:28 +02:00
int subcc_enabled = 0 ;
2002-12-05 01:03:35 +01:00
int suboverlap_enabled = 1 ;
2002-04-17 23:51:18 +02:00
# ifdef USE_SUB
static subtitle * subtitles = NULL ;
float sub_last_pts = - 303 ;
# endif
2002-08-29 22:50:49 +02:00
// infos are empty by default
char * info_name = NULL ;
char * info_artist = NULL ;
char * info_genre = NULL ;
char * info_subject = NULL ;
char * info_copyright = NULL ;
char * info_sourceform = NULL ;
char * info_comment = NULL ;
2002-04-17 23:51:18 +02:00
2001-11-04 00:01:17 +01:00
//char *out_audio_codec=NULL; // override audio codec
//char *out_video_codec=NULL; // override video codec
2001-11-02 04:22:33 +01:00
2001-10-31 17:08:01 +01:00
//#include "libmpeg2/mpeg2.h"
//#include "libmpeg2/mpeg2_internal.h"
2001-12-06 23:27:09 +01:00
# ifdef HAVE_MP3LAME
2001-11-02 04:22:33 +01:00
int lame_param_quality = 0 ; // best
2002-05-01 16:42:42 +02:00
int lame_param_algqual = 5 ; // same as old default
2001-11-02 04:22:33 +01:00
int lame_param_vbr = vbr_default ;
int lame_param_mode = - 1 ; // unset
int lame_param_padding = - 1 ; // unset
int lame_param_br = - 1 ; // unset
int lame_param_ratio = - 1 ; // unset
2002-04-26 22:19:31 +02:00
float lame_param_scale = - 1 ; // unset
2002-12-21 23:16:49 +01:00
# if HAVE_MP3LAME >= 392
int lame_param_fast = 0 ; // unset
static char * lame_param_preset = NULL ; // unset
static int lame_presets_set ( lame_t gfp , int fast , int cbr , const char * preset_name ) ;
static void lame_presets_longinfo_dm ( FILE * msgfp ) ;
# endif
2001-12-06 23:27:09 +01:00
# endif
2001-11-02 04:22:33 +01:00
2002-09-29 21:26:40 +02:00
//static int vo_w=0, vo_h=0;
2002-03-23 14:13:12 +01:00
2001-11-02 02:25:13 +01:00
//-------------------------- config stuff:
2002-01-15 00:38:49 +01:00
m_config_t * mconfig ;
2002-11-12 02:56:42 +01:00
# ifdef NEW_CONFIG
extern int
m_config_parse_config_file ( m_config_t * config , char * conffile ) ;
# endif
2001-11-02 02:25:13 +01:00
static int cfg_inc_verbose ( struct config * conf ) { + + verbose ; return 0 ; }
static int cfg_include ( struct config * conf , char * filename ) {
2002-01-15 00:38:49 +01:00
return m_config_parse_config_file ( mconfig , filename ) ;
2001-11-02 02:25:13 +01:00
}
2002-02-10 01:07:34 +01:00
static char * seek_to_sec = NULL ;
static off_t seek_to_byte = 0 ;
2002-01-15 01:20:50 +01:00
static int parse_end_at ( struct config * conf , const char * param ) ;
2002-09-20 20:54:22 +02:00
//static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width, int height);
2002-01-15 01:20:50 +01:00
2001-11-02 02:25:13 +01:00
# include "get_path.c"
# include "cfg-mplayer-def.h"
# include "cfg-mencoder.h"
2002-01-11 17:06:45 +01:00
# ifdef USE_DVDREAD
# include "spudec.h"
# endif
2002-03-29 04:17:57 +01:00
# include "vobsub.h"
2002-01-11 17:06:45 +01:00
2002-02-17 14:50:26 +01:00
/* FIXME */
void mencoder_exit ( int level , char * how )
{
if ( how )
printf ( " Exiting... (%s) \n " , how ) ;
else
printf ( " Exiting... \n " ) ;
exit ( level ) ;
}
2002-02-03 00:39:53 +01:00
void parse_cfgfiles ( m_config_t * conf )
{
char * conffile ;
if ( ( conffile = get_path ( " mencoder " ) ) = = NULL ) {
mp_msg ( MSGT_CPLAYER , MSGL_ERR , MSGTR_GetpathProblem ) ;
} else {
if ( m_config_parse_config_file ( conf , conffile ) < 0 )
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , " configfile error " ) ;
2002-02-03 00:39:53 +01:00
free ( conffile ) ;
}
}
2002-04-12 12:40:38 +02:00
2001-10-31 17:08:01 +01:00
//---------------------------------------------------------------------------
2002-09-29 21:26:40 +02:00
static int dec_audio ( sh_audio_t * sh_audio , unsigned char * buffer , int total ) {
2001-10-31 17:08:01 +01:00
int size = 0 ;
2002-06-13 23:35:10 +02:00
int at_eof = 0 ;
while ( size < total & & ! at_eof ) {
2001-10-31 17:08:01 +01:00
int len = total - size ;
if ( len > MAX_OUTBURST ) len = MAX_OUTBURST ;
2002-10-06 00:55:45 +02:00
if ( len > sh_audio - > a_out_buffer_size ) len = sh_audio - > a_out_buffer_size ;
if ( len > sh_audio - > a_out_buffer_len ) {
2001-10-31 17:08:01 +01:00
int ret = decode_audio ( sh_audio ,
2002-10-06 00:55:45 +02:00
& sh_audio - > a_out_buffer [ sh_audio - > a_out_buffer_len ] ,
len - sh_audio - > a_out_buffer_len ,
sh_audio - > a_out_buffer_size - sh_audio - > a_out_buffer_len ) ;
if ( ret > 0 ) sh_audio - > a_out_buffer_len + = ret ; else at_eof = 1 ;
2001-10-31 17:08:01 +01:00
}
2002-10-06 00:55:45 +02:00
if ( len > sh_audio - > a_out_buffer_len ) len = sh_audio - > a_out_buffer_len ;
memcpy ( buffer + size , sh_audio - > a_out_buffer , len ) ;
sh_audio - > a_out_buffer_len - = len ; size + = len ;
if ( sh_audio - > a_out_buffer_len > 0 )
memcpy ( sh_audio - > a_out_buffer , & sh_audio - > a_out_buffer [ len ] , sh_audio - > a_out_buffer_len ) ;
2001-10-31 17:08:01 +01:00
}
return size ;
}
//---------------------------------------------------------------------------
2001-10-29 02:11:18 +01:00
2002-06-13 23:35:10 +02:00
static int at_eof = 0 ;
2001-12-04 21:35:31 +01:00
static int interrupted = 0 ;
2001-10-29 02:11:18 +01:00
2002-01-15 01:20:50 +01:00
enum end_at_type_t { END_AT_NONE , END_AT_TIME , END_AT_SIZE } ;
static enum end_at_type_t end_at_type = END_AT_NONE ;
2002-12-05 00:34:29 +01:00
static double end_at ;
2002-01-15 01:20:50 +01:00
2001-10-29 02:11:18 +01:00
static void exit_sighandler ( int x ) {
2002-06-13 23:35:10 +02:00
at_eof = 1 ;
2001-12-04 21:35:31 +01:00
interrupted = 1 ;
2001-10-29 02:11:18 +01:00
}
2002-12-27 23:43:20 +01:00
static muxer_t * muxer = NULL ;
2002-09-29 21:26:40 +02:00
static FILE * muxer_f = NULL ;
2002-04-11 04:52:03 +02:00
// callback for ve_*.c:
2002-12-27 23:43:20 +01:00
void mencoder_write_chunk ( muxer_stream_t * s , int len , unsigned int flags ) {
muxer_write_chunk ( muxer , s , muxer_f , len , flags ) ;
2002-04-11 04:52:03 +02:00
}
2002-11-07 00:54:29 +01:00
extern void print_wave_header ( WAVEFORMATEX * h ) ;
2002-04-11 04:52:03 +02:00
2002-08-31 17:04:18 +02:00
int main ( int argc , char * argv [ ] ) {
2001-10-29 02:11:18 +01:00
stream_t * stream = NULL ;
demuxer_t * demuxer = NULL ;
2002-01-26 23:30:02 +01:00
stream_t * stream2 = NULL ;
demuxer_t * demuxer2 = NULL ;
2001-10-29 02:11:18 +01:00
demux_stream_t * d_audio = NULL ;
demux_stream_t * d_video = NULL ;
demux_stream_t * d_dvdsub = NULL ;
sh_audio_t * sh_audio = NULL ;
sh_video_t * sh_video = NULL ;
int file_format = DEMUXER_TYPE_UNKNOWN ;
2002-03-16 23:51:07 +01:00
int i ;
2002-07-08 23:44:51 +02:00
void * vobsub_writer = NULL ;
2001-10-29 02:11:18 +01:00
2002-04-12 12:40:38 +02:00
uint32_t ptimer_start ;
uint32_t audiorate = 0 ;
uint32_t videorate = 0 ;
uint32_t audiosamples = 1 ;
uint32_t videosamples = 1 ;
uint32_t skippedframes = 0 ;
uint32_t duplicatedframes = 0 ;
2002-09-11 01:19:20 +02:00
uint32_t badframes = 0 ;
2002-04-12 12:40:38 +02:00
2002-12-27 23:43:20 +01:00
muxer_stream_t * mux_a = NULL ;
muxer_stream_t * mux_v = NULL ;
2002-04-12 12:40:38 +02:00
off_t muxer_f_size = 0 ;
2001-10-29 02:11:18 +01:00
2001-12-06 23:27:09 +01:00
# ifdef HAVE_MP3LAME
2001-10-31 17:08:01 +01:00
lame_global_flags * lame ;
2001-12-06 23:27:09 +01:00
# endif
2001-10-31 01:25:28 +01:00
2001-11-01 22:47:28 +01:00
double v_pts_corr = 0 ;
double v_timer_corr = 0 ;
2001-11-01 03:31:23 +01:00
2002-11-12 02:56:42 +01:00
# ifdef NEW_CONFIG
m_entry_t * filelist = NULL ;
# else
2002-01-15 00:38:49 +01:00
play_tree_t * playtree ;
play_tree_iter_t * playtree_iter ;
2002-11-12 02:56:42 +01:00
# endif
2001-11-02 02:25:13 +01:00
char * filename = NULL ;
2002-01-26 23:30:02 +01:00
char * frameno_filename = " frameno.avi " ;
2001-11-02 02:25:13 +01:00
2001-12-07 00:59:46 +01:00
int decoded_frameno = 0 ;
2002-01-26 23:30:02 +01:00
int next_frameno = - 1 ;
2001-12-07 00:59:46 +01:00
2002-01-27 19:29:33 +01:00
unsigned int timer_start ;
2002-03-20 16:38:13 +01:00
mp_msg_init ( ) ;
mp_msg_set_level ( MSGL_STATUS ) ;
2001-11-18 20:12:25 +01:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " %s " , banner_text ) ;
2001-11-02 03:08:00 +01:00
2001-12-04 22:35:18 +01:00
/* Test for cpu capabilities (and corresponding OS support) for optimizing */
GetCpuCaps ( & gCpuCaps ) ;
2003-01-18 20:29:46 +01:00
# ifdef ARCH_X86
2001-12-04 22:35:18 +01:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " CPUflags: Type: %d MMX: %d MMX2: %d 3DNow: %d 3DNow2: %d SSE: %d SSE2: %d \n " ,
gCpuCaps . cpuType , gCpuCaps . hasMMX , gCpuCaps . hasMMX2 ,
gCpuCaps . has3DNow , gCpuCaps . has3DNowExt ,
gCpuCaps . hasSSE , gCpuCaps . hasSSE2 ) ;
# endif
2002-04-28 19:48:45 +02:00
// check codec.conf
if ( ! parse_codec_cfg ( get_path ( " codecs.conf " ) ) ) {
if ( ! parse_codec_cfg ( CONFDIR " /codecs.conf " ) ) {
2002-12-16 00:45:19 +01:00
if ( ! parse_codec_cfg ( NULL ) ) {
mp_msg ( MSGT_MENCODER , MSGL_HINT , MSGTR_CopyCodecsConf ) ;
exit ( 0 ) ;
}
mp_msg ( MSGT_MENCODER , MSGL_INFO , MSGTR_BuiltinCodecsConf ) ;
2002-04-28 19:48:45 +02:00
}
}
2002-11-12 02:56:42 +01:00
// FIXME: get rid of -dvd and other tricky options
2002-01-26 23:30:02 +01:00
stream2 = open_stream ( frameno_filename , 0 , & i ) ;
if ( stream2 ) {
2003-01-19 01:21:54 +01:00
demuxer2 = demux_open ( stream2 , DEMUXER_TYPE_AVI , - 1 , - 1 , - 2 , NULL ) ;
2002-08-07 20:24:25 +02:00
if ( demuxer2 ) printf ( MSGTR_UsingPass3ControllFile , frameno_filename ) ;
2003-01-12 20:41:38 +01:00
else mp_msg ( MSGT_DEMUXER , MSGL_ERR , MSGTR_FormatNotRecognized ) ;
2002-01-26 23:30:02 +01:00
}
2002-11-12 02:56:42 +01:00
// New config code
# ifdef NEW_CONFIG
mconfig = m_config_new ( ) ;
m_config_register_options ( mconfig , mencoder_opts ) ;
parse_cfgfiles ( mconfig ) ;
filelist = m_config_parse_me_command_line ( mconfig , argc , argv ) ;
if ( ! filelist ) mencoder_exit ( 1 , " error parsing cmdline " ) ;
m_entry_set_options ( mconfig , & filelist [ 0 ] ) ;
filename = filelist [ 0 ] . name ;
// Warn the user if he put more than 1 filename ?
# else
2002-01-15 00:38:49 +01:00
playtree = play_tree_new ( ) ;
mconfig = m_config_new ( playtree ) ;
m_config_register_options ( mconfig , mencoder_opts ) ;
2002-02-03 00:39:53 +01:00
parse_cfgfiles ( mconfig ) ;
2002-01-15 00:38:49 +01:00
2002-08-31 17:04:18 +02:00
if ( m_config_parse_command_line ( mconfig , argc , argv ) < 0 ) mencoder_exit ( 1 , " error parsing cmdline " ) ;
2002-01-15 00:38:49 +01:00
playtree = play_tree_cleanup ( playtree ) ;
if ( playtree ) {
playtree_iter = play_tree_iter_new ( playtree , mconfig ) ;
if ( playtree_iter ) {
if ( play_tree_iter_step ( playtree_iter , 0 , 0 ) ! = PLAY_TREE_ITER_ENTRY ) {
play_tree_iter_free ( playtree_iter ) ;
playtree_iter = NULL ;
}
filename = play_tree_iter_get_file ( playtree_iter , 1 ) ;
}
}
2002-11-12 02:56:42 +01:00
# endif
2002-01-15 00:38:49 +01:00
if ( ! filename & & ! vcd_track & & ! dvd_title & & ! tv_param_on ) {
2002-08-07 20:24:25 +02:00
printf ( MSGTR_MissingFilename ) ;
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , NULL ) ;
2001-11-02 02:25:13 +01:00
}
2002-03-20 16:38:13 +01:00
mp_msg_set_level ( verbose + MSGL_STATUS ) ;
2001-10-31 23:59:56 +01:00
2002-06-02 17:25:52 +02:00
// check font
# ifdef USE_OSD
2002-08-28 22:52:02 +02:00
# ifdef HAVE_FREETYPE
init_freetype ( ) ;
# else
2002-06-02 17:25:52 +02:00
if ( font_name ) {
vo_font = read_font_desc ( font_name , font_factor , verbose > 1 ) ;
if ( ! vo_font ) mp_msg ( MSGT_CPLAYER , MSGL_ERR , MSGTR_CantLoadFont , font_name ) ;
} else {
// try default:
vo_font = read_font_desc ( get_path ( " font/font.desc " ) , font_factor , verbose > 1 ) ;
if ( ! vo_font )
vo_font = read_font_desc ( DATADIR " /font/font.desc " , font_factor , verbose > 1 ) ;
}
2002-08-28 22:52:02 +02:00
# endif
2002-06-02 17:25:52 +02:00
# endif
vo_init_osd ( ) ;
2001-11-02 02:25:13 +01:00
stream = open_stream ( filename , vcd_track , & file_format ) ;
2001-10-29 02:11:18 +01:00
if ( ! stream ) {
2002-08-07 20:24:25 +02:00
printf ( MSGTR_CannotOpenFile_Device ) ;
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , NULL ) ;
2001-10-29 02:11:18 +01:00
}
printf ( " success: format: %d data: 0x%X - 0x%X \n " , file_format , ( int ) ( stream - > start_pos ) , ( int ) ( stream - > end_pos ) ) ;
2002-04-01 00:01:54 +02:00
# ifdef USE_DVDREAD
if ( stream - > type = = STREAMTYPE_DVD ) {
if ( audio_lang & & audio_id = = - 1 ) audio_id = dvd_aid_from_lang ( stream , audio_lang ) ;
if ( dvdsub_lang & & dvdsub_id = = - 1 ) dvdsub_id = dvd_sid_from_lang ( stream , dvdsub_lang ) ;
}
# endif
2002-04-15 02:36:21 +02:00
stream - > start_pos + = seek_to_byte ;
2001-10-29 02:11:18 +01:00
2002-01-04 15:03:02 +01:00
# ifdef HAVE_LIBCSS
// current_module="libcss";
if ( dvdimportkey ) {
if ( dvd_import_key ( dvdimportkey ) ) {
mp_msg ( MSGT_CPLAYER , MSGL_FATAL , MSGTR_ErrorDVDkey ) ;
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , NULL ) ;
2002-01-04 15:03:02 +01:00
}
mp_msg ( MSGT_CPLAYER , MSGL_INFO , MSGTR_CmdlineDVDkey ) ;
}
if ( dvd_auth_device ) {
// if (dvd_auth(dvd_auth_device,f)) {
if ( dvd_auth ( dvd_auth_device , filename ) ) {
2002-08-07 20:24:25 +02:00
mp_msg ( MSGT_CPLAYER , MSGL_FATAL , MSGTR_ErrorDVDAuth ) ;
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , NULL ) ;
2002-01-04 15:03:02 +01:00
}
mp_msg ( MSGT_CPLAYER , MSGL_INFO , MSGTR_DVDauthOk ) ;
}
# endif
2002-10-24 00:07:29 +02:00
if ( stream_cache_size > 0 ) stream_enable_cache ( stream , stream_cache_size * 1024 , 0 , 0 ) ;
2002-04-15 02:36:21 +02:00
2002-09-28 20:45:47 +02:00
if ( demuxer2 ) audio_id = - 2 ; /* do NOT read audio packets... */
2002-01-26 17:32:06 +01:00
2001-11-13 22:43:29 +01:00
//demuxer=demux_open(stream,file_format,video_id,audio_id,dvdsub_id);
2003-01-19 01:21:54 +01:00
demuxer = demux_open ( stream , file_format , audio_id , video_id , dvdsub_id , filename ) ;
2001-10-29 02:11:18 +01:00
if ( ! demuxer ) {
2003-01-12 20:41:38 +01:00
mp_msg ( MSGT_DEMUXER , MSGL_ERR , MSGTR_FormatNotRecognized ) ;
2002-08-07 20:24:25 +02:00
printf ( MSGTR_CannotOpenDemuxer ) ;
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , NULL ) ;
2001-10-29 02:11:18 +01:00
}
2002-01-26 23:30:02 +01:00
d_audio = demuxer2 ? demuxer2 - > audio : demuxer - > audio ;
2001-10-29 02:11:18 +01:00
d_video = demuxer - > video ;
d_dvdsub = demuxer - > sub ;
sh_audio = d_audio - > sh ;
sh_video = d_video - > sh ;
if ( ! video_read_properties ( sh_video ) ) {
2002-10-19 22:26:04 +02:00
printf ( MSGTR_CannotReadVideoProperties ) ;
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , NULL ) ;
2001-10-29 02:11:18 +01:00
}
2001-11-02 03:08:00 +01:00
mp_msg ( MSGT_MENCODER , MSGL_INFO , " [V] filefmt:%d fourcc:0x%X size:%dx%d fps:%5.2f ftime:=%6.4f \n " ,
2001-10-29 02:11:18 +01:00
demuxer - > file_format , sh_video - > format , sh_video - > disp_w , sh_video - > disp_h ,
sh_video - > fps , sh_video - > frametime
) ;
2002-03-18 02:51:47 +01:00
2002-12-05 00:37:17 +01:00
if ( force_fps ) {
sh_video - > fps = force_fps ;
sh_video - > frametime = 1.0f / sh_video - > fps ;
mp_msg ( MSGT_MENCODER , MSGL_INFO , " input fps will be interpreted as %5.2f instead \n " , sh_video - > fps ) ;
}
2002-08-05 15:41:32 +02:00
if ( sh_audio & & out_audio_codec < 0 ) {
2003-01-05 15:18:53 +01:00
if ( audio_id = = - 2 )
2003-01-05 15:35:35 +01:00
mp_msg ( MSGT_MENCODER , MSGL_ERR , " This demuxer doesn't support -nosound yet. \n " ) ;
2002-08-07 20:24:25 +02:00
mp_msg ( MSGT_MENCODER , MSGL_FATAL , MSGTR_NoAudioEncoderSelected ) ;
2002-08-05 15:41:32 +02:00
mencoder_exit ( 1 , NULL ) ;
}
if ( sh_video & & out_video_codec < 0 ) {
2002-08-07 20:24:25 +02:00
mp_msg ( MSGT_MENCODER , MSGL_FATAL , MSGTR_NoVideoEncoderSelected ) ;
2002-08-05 15:41:32 +02:00
mencoder_exit ( 1 , NULL ) ;
}
2002-02-10 01:07:34 +01:00
if ( sh_audio & & ( out_audio_codec | | seek_to_sec | | ! sh_audio - > wf ) ) {
2001-10-31 00:17:35 +01:00
// Go through the codec.conf and find the best codec...
2002-09-26 01:45:34 +02:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
2002-09-28 04:23:20 +02:00
if ( ! init_best_audio_codec ( sh_audio , audio_codec_list , audio_fm_list ) ) {
2002-09-26 01:45:34 +02:00
sh_audio = d_audio - > sh = NULL ; // failed to init :(
2001-10-31 00:17:35 +01:00
}
2002-09-26 01:45:34 +02:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
2001-10-31 00:17:35 +01:00
}
2001-10-29 02:11:18 +01:00
// set up video encoder:
2002-07-08 23:44:51 +02:00
if ( vobsub_out ) {
unsigned int palette [ 16 ] , width , height ;
unsigned char tmp [ 3 ] = { 0 , 0 , 0 } ;
if ( spudec_ifo & & vobsub_parse_ifo ( NULL , spudec_ifo , palette , & width , & height , 1 , dvdsub_id , tmp ) > = 0 )
vobsub_writer = vobsub_out_open ( vobsub_out , palette , sh_video - > disp_w , sh_video - > disp_h ,
2002-09-01 16:30:55 +02:00
vobsub_out_id ? vobsub_out_id : ( char * ) tmp , vobsub_out_index ) ;
2002-07-08 23:44:51 +02:00
# ifdef USE_DVDREAD
if ( vobsub_writer = = NULL ) {
char tmp [ 3 ] ;
if ( vobsub_out_id = = NULL & & stream - > type = = STREAMTYPE_DVD ) {
int i ;
dvd_priv_t * dvd = ( dvd_priv_t * ) stream - > priv ;
for ( i = 0 ; i < dvd - > nr_of_subtitles ; + + i )
if ( dvd - > subtitles [ i ] . id = = dvdsub_id ) {
tmp [ 0 ] = ( dvd - > subtitles [ i ] . language > > 8 ) & 0xff ;
tmp [ 1 ] = dvd - > subtitles [ i ] . language & 0xff ;
tmp [ 2 ] = 0 ;
vobsub_out_id = tmp ;
break ;
}
}
vobsub_writer = vobsub_out_open ( vobsub_out , stream - > type = = STREAMTYPE_DVD ? ( ( dvd_priv_t * ) ( stream - > priv ) ) - > cur_pgc - > palette : NULL ,
sh_video - > disp_w , sh_video - > disp_h , vobsub_out_id , vobsub_out_index ) ;
}
# endif
}
else {
2002-03-29 04:17:57 +01:00
if ( spudec_ifo ) {
unsigned int palette [ 16 ] , width , height ;
2002-07-08 23:44:51 +02:00
if ( vobsub_parse_ifo ( NULL , spudec_ifo , palette , & width , & height , 1 , - 1 , NULL ) > = 0 )
2002-03-29 04:17:57 +01:00
vo_spudec = spudec_new_scaled ( palette , sh_video - > disp_w , sh_video - > disp_h ) ;
}
2002-01-11 17:06:45 +01:00
# ifdef USE_DVDREAD
2002-03-29 16:12:41 +01:00
if ( vo_spudec = = NULL ) {
2002-02-06 23:55:47 +01:00
vo_spudec = spudec_new_scaled ( stream - > type = = STREAMTYPE_DVD ? ( ( dvd_priv_t * ) ( stream - > priv ) ) - > cur_pgc - > palette : NULL ,
2002-01-11 17:06:45 +01:00
sh_video - > disp_w , sh_video - > disp_h ) ;
2002-03-29 04:17:57 +01:00
}
2002-01-11 17:06:45 +01:00
# endif
2002-07-08 23:44:51 +02:00
}
2002-01-11 17:06:45 +01:00
2002-04-17 23:51:18 +02:00
# ifdef USE_SUB
// after reading video params we should load subtitles because
// we know fps so now we can adjust subtitles time to ~6 seconds AST
// check .sub
// current_module="read_subtitles_file";
if ( sub_name ) {
subtitles = sub_read_file ( sub_name , sh_video - > fps ) ;
if ( ! subtitles ) mp_msg ( MSGT_CPLAYER , MSGL_ERR , MSGTR_CantLoadSub , sub_name ) ;
} else
if ( sub_auto ) { // auto load sub file ...
subtitles = sub_read_file ( filename ? sub_filename ( get_path ( " sub/ " ) , filename )
: " default.sub " , sh_video - > fps ) ;
}
# endif
2001-10-29 02:11:18 +01:00
// set up output file:
2001-11-02 04:22:33 +01:00
muxer_f = fopen ( out_filename , " wb " ) ;
2001-11-14 00:43:33 +01:00
if ( ! muxer_f ) {
2002-08-07 20:24:25 +02:00
printf ( MSGTR_CannotOpenOutputFile , out_filename ) ;
2002-02-17 14:50:26 +01:00
mencoder_exit ( 1 , NULL ) ;
2001-11-14 00:43:33 +01:00
}
2002-12-27 23:43:20 +01:00
muxer = muxer_new_muxer ( out_file_format ) ;
2001-10-31 00:17:35 +01:00
// ============= VIDEO ===============
2002-12-27 23:43:20 +01:00
mux_v = muxer_new_stream ( muxer , MUXER_TYPE_VIDEO ) ;
2001-10-29 02:11:18 +01:00
2002-02-07 21:22:03 +01:00
mux_v - > buffer_size = 0x200000 ; // 2MB
2001-10-29 02:11:18 +01:00
mux_v - > buffer = malloc ( mux_v - > buffer_size ) ;
mux_v - > source = sh_video ;
mux_v - > h . dwSampleSize = 0 ; // VBR
mux_v - > h . dwScale = 10000 ;
2001-11-01 22:47:28 +01:00
mux_v - > h . dwRate = mux_v - > h . dwScale * ( force_ofps ? force_ofps : sh_video - > fps ) ;
2001-10-29 02:11:18 +01:00
2001-11-04 00:01:17 +01:00
mux_v - > codec = out_video_codec ;
2001-10-30 22:55:28 +01:00
2002-04-11 04:52:03 +02:00
mux_v - > bih = NULL ;
sh_video - > codec = NULL ;
sh_video - > video_out = NULL ;
sh_video - > vfilter = NULL ; // fixme!
2001-10-29 02:11:18 +01:00
switch ( mux_v - > codec ) {
2001-12-08 13:21:23 +01:00
case VCODEC_COPY :
if ( sh_video - > bih )
mux_v - > bih = sh_video - > bih ;
else
{
mux_v - > bih = malloc ( sizeof ( BITMAPINFOHEADER ) ) ;
mux_v - > bih - > biSize = sizeof ( BITMAPINFOHEADER ) ;
mux_v - > bih - > biWidth = sh_video - > disp_w ;
mux_v - > bih - > biHeight = sh_video - > disp_h ;
mux_v - > bih - > biCompression = sh_video - > format ;
mux_v - > bih - > biPlanes = 1 ;
mux_v - > bih - > biBitCount = 24 ; // FIXME!!!
mux_v - > bih - > biSizeImage = mux_v - > bih - > biWidth * mux_v - > bih - > biHeight * ( mux_v - > bih - > biBitCount / 8 ) ;
}
printf ( " videocodec: framecopy (%dx%d %dbpp fourcc=%x) \n " ,
mux_v - > bih - > biWidth , mux_v - > bih - > biHeight ,
mux_v - > bih - > biBitCount , mux_v - > bih - > biCompression ) ;
2001-10-29 02:11:18 +01:00
break ;
2001-12-07 00:59:46 +01:00
case VCODEC_FRAMENO :
mux_v - > bih = malloc ( sizeof ( BITMAPINFOHEADER ) ) ;
mux_v - > bih - > biSize = sizeof ( BITMAPINFOHEADER ) ;
2002-09-29 21:26:40 +02:00
mux_v - > bih - > biWidth = sh_video - > disp_w ;
mux_v - > bih - > biHeight = sh_video - > disp_h ;
2001-12-07 00:59:46 +01:00
mux_v - > bih - > biPlanes = 1 ;
mux_v - > bih - > biBitCount = 24 ;
mux_v - > bih - > biCompression = mmioFOURCC ( ' F ' , ' r ' , ' N ' , ' o ' ) ;
mux_v - > bih - > biSizeImage = mux_v - > bih - > biWidth * mux_v - > bih - > biHeight * ( mux_v - > bih - > biBitCount / 8 ) ;
break ;
2002-04-11 04:52:03 +02:00
default :
2001-12-08 02:43:02 +01:00
2002-04-11 04:52:03 +02:00
switch ( mux_v - > codec ) {
case VCODEC_DIVX4 :
2002-06-27 21:33:28 +02:00
sh_video - > vfilter = vf_open_encoder ( NULL , " divx4 " , ( char * ) mux_v ) ; break ;
2002-04-11 04:52:03 +02:00
case VCODEC_LIBAVCODEC :
2002-06-27 21:33:28 +02:00
sh_video - > vfilter = vf_open_encoder ( NULL , " lavc " , ( char * ) mux_v ) ; break ;
2002-04-11 04:52:03 +02:00
case VCODEC_RAWRGB :
2002-06-27 21:33:28 +02:00
sh_video - > vfilter = vf_open_encoder ( NULL , " rawrgb " , ( char * ) mux_v ) ; break ;
2002-04-11 04:52:03 +02:00
case VCODEC_VFW :
2002-06-27 21:33:28 +02:00
sh_video - > vfilter = vf_open_encoder ( NULL , " vfw " , ( char * ) mux_v ) ; break ;
2002-04-12 23:50:38 +02:00
case VCODEC_LIBDV :
2002-06-27 21:33:28 +02:00
sh_video - > vfilter = vf_open_encoder ( NULL , " libdv " , ( char * ) mux_v ) ; break ;
2002-09-21 14:41:29 +02:00
case VCODEC_XVID :
sh_video - > vfilter = vf_open_encoder ( NULL , " xvid " , ( char * ) mux_v ) ; break ;
2002-12-16 02:49:39 +01:00
case VCODEC_QTVIDEO :
sh_video - > vfilter = vf_open_encoder ( NULL , " qtvideo " , ( char * ) mux_v ) ; break ;
2002-01-26 21:18:59 +01:00
}
2002-04-11 04:52:03 +02:00
if ( ! mux_v - > bih | | ! sh_video - > vfilter ) {
2002-08-07 20:24:25 +02:00
mp_msg ( MSGT_MENCODER , MSGL_FATAL , MSGTR_EncoderOpenFailed ) ;
2002-04-11 04:52:03 +02:00
mencoder_exit ( 1 , NULL ) ;
2002-01-26 21:18:59 +01:00
}
2002-04-17 23:51:18 +02:00
// append 'expand' filter, it fixes stride problems and renders osd:
sh_video - > vfilter = vf_open_filter ( sh_video - > vfilter , " expand " , " -1:-1:-1:-1:1 " ) ;
2002-04-11 04:52:03 +02:00
sh_video - > vfilter = append_filters ( sh_video - > vfilter ) ;
2002-09-26 01:45:34 +02:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
2002-09-26 03:31:18 +02:00
init_best_video_codec ( sh_video , video_codec_list , video_fm_list ) ;
2002-09-26 01:45:34 +02:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
if ( ! sh_video - > inited ) mencoder_exit ( 1 , NULL ) ;
2001-12-22 15:32:08 +01:00
}
/* force output fourcc to .. */
2002-01-26 21:18:59 +01:00
if ( ( force_fourcc ! = NULL ) & & ( strlen ( force_fourcc ) > = 4 ) )
2001-12-22 15:32:08 +01:00
{
mux_v - > bih - > biCompression = mmioFOURCC ( force_fourcc [ 0 ] , force_fourcc [ 1 ] ,
force_fourcc [ 2 ] , force_fourcc [ 3 ] ) ;
2002-08-07 20:24:25 +02:00
printf ( MSGTR_ForcingOutputFourcc ,
2002-01-26 21:18:59 +01:00
mux_v - > bih - > biCompression , ( char * ) & mux_v - > bih - > biCompression ) ;
2001-10-29 02:11:18 +01:00
}
2002-11-02 01:45:12 +01:00
//if(demuxer->file_format!=DEMUXER_TYPE_AVI) pts_from_bps=0; // it must be 0 for mpeg/asf!
2002-01-27 03:31:06 +01:00
2001-10-31 00:17:35 +01:00
// ============= AUDIO ===============
if ( sh_audio ) {
2002-12-27 23:43:20 +01:00
mux_a = muxer_new_stream ( muxer , MUXER_TYPE_AUDIO ) ;
2001-10-31 00:17:35 +01:00
mux_a - > buffer_size = 0x100000 ; //16384;
mux_a - > buffer = malloc ( mux_a - > buffer_size ) ;
mux_a - > source = sh_audio ;
2001-11-04 00:01:17 +01:00
mux_a - > codec = out_audio_codec ;
2001-10-31 00:17:35 +01:00
switch ( mux_a - > codec ) {
2001-12-08 14:30:06 +01:00
case ACODEC_COPY :
2002-01-27 02:23:23 +01:00
if ( sh_audio - > wf ) {
2001-12-08 14:30:06 +01:00
mux_a - > wf = sh_audio - > wf ;
2002-01-27 03:31:06 +01:00
if ( ! sh_audio - > i_bps ) sh_audio - > i_bps = mux_a - > wf - > nAvgBytesPerSec ;
2002-01-27 02:23:23 +01:00
} else {
2001-12-08 14:30:06 +01:00
mux_a - > wf = malloc ( sizeof ( WAVEFORMATEX ) ) ;
2002-01-27 03:31:06 +01:00
mux_a - > wf - > nBlockAlign = 1 ; //mux_a->h.dwSampleSize;
2002-10-07 01:24:36 +02:00
mux_a - > wf - > wFormatTag = sh_audio - > format ;
2001-12-08 14:30:06 +01:00
mux_a - > wf - > nChannels = sh_audio - > channels ;
mux_a - > wf - > nSamplesPerSec = sh_audio - > samplerate ;
2002-01-27 02:23:23 +01:00
mux_a - > wf - > nAvgBytesPerSec = sh_audio - > i_bps ; //mux_a->h.dwSampleSize*mux_a->wf->nSamplesPerSec;
2001-12-13 18:50:19 +01:00
mux_a - > wf - > wBitsPerSample = 16 ; // FIXME
2001-12-08 14:30:06 +01:00
mux_a - > wf - > cbSize = 0 ; // FIXME for l3codeca.acm
}
2002-01-27 03:31:06 +01:00
if ( sh_audio - > audio . dwScale ) {
mux_a - > h . dwSampleSize = sh_audio - > audio . dwSampleSize ;
mux_a - > h . dwScale = sh_audio - > audio . dwScale ;
mux_a - > h . dwRate = sh_audio - > audio . dwRate ;
2002-08-01 10:39:33 +02:00
// mux_a->h.dwStart=sh_audio->audio.dwStart;
2002-01-27 03:31:06 +01:00
} else {
mux_a - > h . dwSampleSize = mux_a - > wf - > nBlockAlign ;
mux_a - > h . dwScale = mux_a - > h . dwSampleSize ;
mux_a - > h . dwRate = mux_a - > wf - > nAvgBytesPerSec ;
}
2002-11-07 00:54:29 +01:00
printf ( " audiocodec: framecopy (format=%x chans=%d rate=%ld bits=%d bps=%ld sample=%ld) \n " ,
2001-12-08 14:30:06 +01:00
mux_a - > wf - > wFormatTag , mux_a - > wf - > nChannels , mux_a - > wf - > nSamplesPerSec ,
2002-01-27 03:31:06 +01:00
mux_a - > wf - > wBitsPerSample , mux_a - > wf - > nAvgBytesPerSec , mux_a - > h . dwSampleSize ) ;
2001-10-31 00:17:35 +01:00
break ;
2001-10-31 01:25:28 +01:00
case ACODEC_PCM :
printf ( " CBR PCM audio selected \n " ) ;
mux_a - > h . dwSampleSize = 2 * sh_audio - > channels ;
mux_a - > h . dwScale = 1 ;
2002-10-06 00:55:45 +02:00
mux_a - > h . dwRate = force_srate ? force_srate : sh_audio - > samplerate ;
2001-10-31 01:25:28 +01:00
mux_a - > wf = malloc ( sizeof ( WAVEFORMATEX ) ) ;
mux_a - > wf - > nBlockAlign = mux_a - > h . dwSampleSize ;
mux_a - > wf - > wFormatTag = 0x1 ; // PCM
2002-10-06 00:55:45 +02:00
mux_a - > wf - > nChannels = audio_output_channels ? audio_output_channels : sh_audio - > channels ;
mux_a - > wf - > nSamplesPerSec = mux_a - > h . dwRate ;
2001-10-31 01:25:28 +01:00
mux_a - > wf - > nAvgBytesPerSec = mux_a - > h . dwSampleSize * mux_a - > wf - > nSamplesPerSec ;
mux_a - > wf - > wBitsPerSample = 16 ;
mux_a - > wf - > cbSize = 0 ; // FIXME for l3codeca.acm
2002-10-06 00:55:45 +02:00
// setup filter:
if ( ! init_audio_filters ( sh_audio ,
sh_audio - > samplerate ,
sh_audio - > channels , sh_audio - > sample_format , sh_audio - > samplesize ,
mux_a - > wf - > nSamplesPerSec , mux_a - > wf - > nChannels ,
( mux_a - > wf - > wBitsPerSample = = 8 ) ? AFMT_U8 : AFMT_S16_LE ,
mux_a - > wf - > wBitsPerSample / 8 ,
16384 , mux_a - > wf - > nAvgBytesPerSec ) ) {
mp_msg ( MSGT_CPLAYER , MSGL_ERR , " Couldn't find matching filter / ao format! \n " ) ;
}
2001-10-31 01:25:28 +01:00
break ;
2002-10-06 12:49:41 +02:00
# ifdef HAVE_MP3LAME
2001-10-31 00:17:35 +01:00
case ACODEC_VBRMP3 :
2001-12-08 14:30:06 +01:00
printf ( " MP3 audio selected \n " ) ;
2001-10-31 00:17:35 +01:00
mux_a - > h . dwSampleSize = 0 ; // VBR
2002-04-18 19:28:48 +02:00
mux_a - > h . dwRate = force_srate ? force_srate : sh_audio - > samplerate ;
mux_a - > h . dwScale = ( mux_a - > h . dwRate < 32000 ) ? 576 : 1152 ; // samples/frame
2001-11-02 18:43:05 +01:00
if ( sizeof ( MPEGLAYER3WAVEFORMAT ) ! = 30 ) mp_msg ( MSGT_MENCODER , MSGL_WARN , " sizeof(MPEGLAYER3WAVEFORMAT)==%d!=30, maybe broken C compiler? \n " , sizeof ( MPEGLAYER3WAVEFORMAT ) ) ;
mux_a - > wf = malloc ( sizeof ( MPEGLAYER3WAVEFORMAT ) ) ; // should be 30
2001-10-31 00:17:35 +01:00
mux_a - > wf - > wFormatTag = 0x55 ; // MP3
2002-10-06 00:55:45 +02:00
mux_a - > wf - > nChannels = ( lame_param_mode < 0 ) ? sh_audio - > channels :
( ( lame_param_mode = = 3 ) ? 1 : 2 ) ;
mux_a - > wf - > nSamplesPerSec = mux_a - > h . dwRate ;
2001-11-02 18:43:05 +01:00
mux_a - > wf - > nAvgBytesPerSec = 192000 / 8 ; // FIXME!
2002-06-23 19:34:29 +02:00
mux_a - > wf - > nBlockAlign = ( mux_a - > h . dwRate < 32000 ) ? 576 : 1152 ; // required for l3codeca.acm + WMP 6.4
2001-11-02 18:43:05 +01:00
mux_a - > wf - > wBitsPerSample = 0 ; //16;
// from NaNdub: (requires for l3codeca.acm)
mux_a - > wf - > cbSize = 12 ;
( ( MPEGLAYER3WAVEFORMAT * ) ( mux_a - > wf ) ) - > wID = 1 ;
( ( MPEGLAYER3WAVEFORMAT * ) ( mux_a - > wf ) ) - > fdwFlags = 2 ;
2002-04-18 19:28:48 +02:00
( ( MPEGLAYER3WAVEFORMAT * ) ( mux_a - > wf ) ) - > nBlockSize = ( mux_a - > h . dwRate < 32000 ) ? 576 : 1152 ; // ???
2001-11-02 18:43:05 +01:00
( ( MPEGLAYER3WAVEFORMAT * ) ( mux_a - > wf ) ) - > nFramesPerBlock = 1 ;
( ( MPEGLAYER3WAVEFORMAT * ) ( mux_a - > wf ) ) - > nCodecDelay = 0 ;
2002-10-06 00:55:45 +02:00
// setup filter:
if ( ! init_audio_filters ( sh_audio ,
sh_audio - > samplerate ,
sh_audio - > channels , sh_audio - > sample_format , sh_audio - > samplesize ,
mux_a - > wf - > nSamplesPerSec , mux_a - > wf - > nChannels ,
2002-11-03 10:54:49 +01:00
# ifdef WORDS_BIGENDIAN
AFMT_S16_BE , 2 ,
# else
2002-10-06 00:55:45 +02:00
AFMT_S16_LE , 2 ,
2002-11-03 10:54:49 +01:00
# endif
2002-10-06 00:55:45 +02:00
4608 , mux_a - > h . dwRate * mux_a - > wf - > nChannels * 2 ) ) {
mp_msg ( MSGT_CPLAYER , MSGL_ERR , " Couldn't find matching filter / ao format! \n " ) ;
}
2001-10-31 00:17:35 +01:00
break ;
2002-10-06 12:49:41 +02:00
# endif
2001-10-31 00:17:35 +01:00
}
2002-06-23 19:34:29 +02:00
if ( verbose > 1 ) print_wave_header ( mux_a - > wf ) ;
2002-08-01 10:39:33 +02:00
if ( audio_delay ! = 0.0 ) {
mux_a - > h . dwStart = audio_delay * mux_a - > h . dwRate / mux_a - > h . dwScale ;
printf ( " Setting AUDIO DELAY to %5.3f \n " , mux_a - > h . dwStart * mux_a - > h . dwScale / ( float ) mux_a - > h . dwRate ) ;
}
} // if(sh_audio)
2002-08-07 20:24:25 +02:00
printf ( MSGTR_WritingAVIHeader ) ;
2002-12-27 23:43:20 +01:00
muxer_write_header ( muxer , muxer_f ) ;
2001-10-29 02:11:18 +01:00
2002-04-11 04:52:03 +02:00
decoded_frameno = 0 ;
2001-10-29 02:11:18 +01:00
2001-10-31 23:59:56 +01:00
if ( sh_audio )
2001-10-31 01:25:28 +01:00
switch ( mux_a - > codec ) {
2001-12-06 23:27:09 +01:00
# ifdef HAVE_MP3LAME
2001-10-31 01:25:28 +01:00
case ACODEC_VBRMP3 :
lame = lame_init ( ) ;
2001-10-31 17:08:01 +01:00
lame_set_bWriteVbrTag ( lame , 0 ) ;
2002-10-06 00:55:45 +02:00
lame_set_in_samplerate ( lame , mux_a - > wf - > nSamplesPerSec ) ;
//lame_set_in_samplerate(lame,sh_audio->samplerate); // if resampling done by lame
2001-10-31 01:25:28 +01:00
lame_set_num_channels ( lame , mux_a - > wf - > nChannels ) ;
2001-11-02 21:05:36 +01:00
lame_set_out_samplerate ( lame , mux_a - > wf - > nSamplesPerSec ) ;
2002-05-01 16:42:42 +02:00
lame_set_quality ( lame , lame_param_algqual ) ; // 0 = best q
2001-11-02 04:22:33 +01:00
if ( lame_param_vbr ) { // VBR:
lame_set_VBR ( lame , lame_param_vbr ) ; // vbr mode
lame_set_VBR_q ( lame , lame_param_quality + 1 ) ; // 1 = best vbr q 6=~128k
if ( lame_param_br > 0 ) lame_set_VBR_mean_bitrate_kbps ( lame , lame_param_br ) ;
} else { // CBR:
if ( lame_param_br > 0 ) lame_set_brate ( lame , lame_param_br ) ;
}
if ( lame_param_mode > = 0 ) lame_set_mode ( lame , lame_param_mode ) ; // j-st
if ( lame_param_ratio > 0 ) lame_set_compression_ratio ( lame , lame_param_ratio ) ;
2002-04-26 22:19:31 +02:00
if ( lame_param_scale > 0 ) {
printf ( " Setting audio input gain to %f \n " , lame_param_scale ) ;
lame_set_scale ( lame , lame_param_scale ) ;
}
2002-12-21 23:16:49 +01:00
# if HAVE_MP3LAME >= 392
if ( lame_param_preset ! = NULL ) {
printf ( " \n preset=%s \n \n " , lame_param_preset ) ;
lame_presets_set ( lame , lame_param_fast , ( lame_param_vbr = = 0 ) , lame_param_preset ) ;
}
# endif
2001-10-31 01:25:28 +01:00
lame_init_params ( lame ) ;
2002-11-01 18:46:45 +01:00
if ( verbose > 0 ) {
2001-11-02 04:22:33 +01:00
lame_print_config ( lame ) ;
lame_print_internals ( lame ) ;
2001-11-02 03:08:00 +01:00
}
2001-12-06 23:27:09 +01:00
break ;
# endif
2001-10-31 01:25:28 +01:00
}
2001-10-29 02:11:18 +01:00
signal ( SIGINT , exit_sighandler ) ; // Interrupt from keyboard
signal ( SIGQUIT , exit_sighandler ) ; // Quit from keyboard
signal ( SIGTERM , exit_sighandler ) ; // kill
2002-01-27 19:29:33 +01:00
timer_start = GetTimerMS ( ) ;
2002-02-10 01:07:34 +01:00
if ( seek_to_sec ) {
int a , b ; float d ;
if ( sscanf ( seek_to_sec , " %d:%d:%f " , & a , & b , & d ) = = 3 )
d + = 3600 * a + 60 * b ;
else if ( sscanf ( seek_to_sec , " %d:%f " , & a , & d ) = = 2 )
d + = 60 * a ;
else
sscanf ( seek_to_sec , " %f " , & d ) ;
demux_seek ( demuxer , d , 1 ) ;
2002-09-14 12:47:34 +02:00
// there is 2 way to handle the -ss option in 3-pass mode:
// > 1. do the first pass for the whole file, and use -ss for 2nd/3rd pases only
// > 2. do all the 3 passes with the same -ss value
// this line enables behaviour 1. (and kills 2. at the same time):
// if(demuxer2) demux_seek(demuxer2, d, 1);
2002-02-10 01:07:34 +01:00
}
2002-12-27 23:43:20 +01:00
if ( out_file_format = = MUXER_TYPE_MPEG )
{
if ( audio_preload > 0.4 ) {
fprintf ( stderr , " Limiting audio preload to 0.4s \n " ) ;
audio_preload = 0.4 ;
}
if ( audio_density < 4 ) {
fprintf ( stderr , " Increasing audio density to 4 \n " ) ;
2003-01-03 12:51:39 +01:00
audio_density = 4 ;
2002-12-27 23:43:20 +01:00
}
}
2002-04-12 12:40:38 +02:00
if ( tv_param_on = = 1 )
{
fprintf ( stderr , " Forcing audio preload to 0, max pts correction to 0 \n " ) ;
audio_preload = 0.0 ;
default_max_pts_correction = 0 ;
}
2002-06-28 19:13:18 +02:00
play_n_frames = play_n_frames_mf ;
2002-06-13 23:35:10 +02:00
while ( ! at_eof ) {
2001-10-29 02:11:18 +01:00
2001-10-30 22:22:28 +01:00
float frame_time = 0 ;
2001-10-29 02:11:18 +01:00
int blit_frame = 0 ;
float a_pts = 0 ;
float v_pts = 0 ;
2001-10-30 22:55:28 +01:00
unsigned char * start = NULL ;
int in_size ;
2001-11-01 22:47:28 +01:00
int skip_flag = 0 ; // 1=skip -1=duplicate
2001-10-29 02:11:18 +01:00
2002-04-12 12:40:38 +02:00
if ( ( end_at_type = = END_AT_SIZE & & end_at < = ftello ( muxer_f ) ) | |
2002-01-15 01:20:50 +01:00
( end_at_type = = END_AT_TIME & & end_at < sh_video - > timer ) )
break ;
2001-11-03 01:44:02 +01:00
if ( play_n_frames > = 0 ) {
- - play_n_frames ;
if ( play_n_frames < 0 ) break ;
}
2001-10-31 00:17:35 +01:00
if ( sh_audio ) {
// get audio:
2001-10-31 01:25:28 +01:00
while ( mux_a - > timer - audio_preload < mux_v - > timer ) {
2001-11-03 22:00:04 +01:00
int len = 0 ;
2002-04-12 12:40:38 +02:00
ptimer_start = GetTimerMS ( ) ;
2001-10-31 00:17:35 +01:00
if ( mux_a - > h . dwSampleSize ) {
2001-11-01 03:31:23 +01:00
// CBR - copy 0.5 sec of audio
2001-10-31 01:25:28 +01:00
switch ( mux_a - > codec ) {
2001-12-08 14:30:06 +01:00
case ACODEC_COPY : // copy
2002-08-01 10:39:33 +02:00
len = mux_a - > wf - > nAvgBytesPerSec / audio_density ;
2001-10-31 01:25:28 +01:00
len / = mux_a - > h . dwSampleSize ; if ( len < 1 ) len = 1 ;
len * = mux_a - > h . dwSampleSize ;
len = demux_read_data ( sh_audio - > ds , mux_a - > buffer , len ) ;
break ;
case ACODEC_PCM :
2002-08-01 10:39:33 +02:00
len = mux_a - > h . dwSampleSize * ( mux_a - > h . dwRate / audio_density ) ;
2001-10-31 17:08:01 +01:00
len = dec_audio ( sh_audio , mux_a - > buffer , len ) ;
2001-10-31 01:25:28 +01:00
break ;
}
2001-10-31 00:17:35 +01:00
} else {
2001-11-01 03:31:23 +01:00
// VBR - encode/copy an audio frame
switch ( mux_a - > codec ) {
2001-12-08 14:30:06 +01:00
case ACODEC_COPY : // copy
2002-01-26 23:30:02 +01:00
len = ds_get_packet ( sh_audio - > ds , ( unsigned char * * ) & mux_a - > buffer ) ;
// printf("VBR audio framecopy not yet implemented!\n");
2001-11-01 03:31:23 +01:00
break ;
2001-12-06 23:27:09 +01:00
# ifdef HAVE_MP3LAME
2001-11-01 03:31:23 +01:00
case ACODEC_VBRMP3 :
2001-10-31 17:08:01 +01:00
while ( mux_a - > buffer_len < 4 ) {
unsigned char tmp [ 2304 ] ;
int len = dec_audio ( sh_audio , tmp , 2304 ) ;
if ( len < = 0 ) break ; // eof
2002-06-23 19:34:29 +02:00
/* mono encoding, a bit tricky */
if ( mux_a - > wf - > nChannels = = 1 )
{
2002-06-27 21:33:28 +02:00
len = lame_encode_buffer ( lame , ( short * ) tmp , ( short * ) tmp , len / 2 ,
2002-06-23 19:34:29 +02:00
mux_a - > buffer + mux_a - > buffer_len , mux_a - > buffer_size - mux_a - > buffer_len ) ;
}
else
{
len = lame_encode_buffer_interleaved ( lame ,
2002-06-27 21:33:28 +02:00
( short * ) tmp , len / 4 ,
2001-10-31 17:08:01 +01:00
mux_a - > buffer + mux_a - > buffer_len , mux_a - > buffer_size - mux_a - > buffer_len ) ;
2002-06-23 19:34:29 +02:00
}
2001-10-31 17:08:01 +01:00
if ( len < 0 ) break ; // error
mux_a - > buffer_len + = len ;
}
if ( mux_a - > buffer_len < 4 ) break ;
len = mp_decode_mp3_header ( mux_a - > buffer ) ;
2001-11-02 21:05:36 +01:00
//printf("%d\n",len);
2001-10-31 17:08:01 +01:00
if ( len < = 0 ) break ; // bad frame!
2002-04-18 19:28:48 +02:00
// printf("[%d]\n",mp_mp3_get_lsf(mux_a->buffer));
2001-10-31 17:08:01 +01:00
while ( mux_a - > buffer_len < len ) {
unsigned char tmp [ 2304 ] ;
int len = dec_audio ( sh_audio , tmp , 2304 ) ;
if ( len < = 0 ) break ; // eof
2002-06-23 21:09:25 +02:00
/* mono encoding, a bit tricky */
if ( mux_a - > wf - > nChannels = = 1 )
{
2002-06-27 21:33:28 +02:00
len = lame_encode_buffer ( lame , ( short * ) tmp , ( short * ) tmp , len / 2 ,
2002-06-23 21:09:25 +02:00
mux_a - > buffer + mux_a - > buffer_len , mux_a - > buffer_size - mux_a - > buffer_len ) ;
}
else
{
len = lame_encode_buffer_interleaved ( lame ,
2002-06-27 21:33:28 +02:00
( short * ) tmp , len / 4 ,
2001-10-31 17:08:01 +01:00
mux_a - > buffer + mux_a - > buffer_len , mux_a - > buffer_size - mux_a - > buffer_len ) ;
2002-06-23 21:09:25 +02:00
}
2001-10-31 17:08:01 +01:00
if ( len < 0 ) break ; // error
mux_a - > buffer_len + = len ;
}
2001-11-01 03:31:23 +01:00
break ;
2001-12-06 23:27:09 +01:00
# endif
2001-11-01 03:31:23 +01:00
}
2001-10-31 00:17:35 +01:00
}
2001-10-31 01:25:28 +01:00
if ( len < = 0 ) break ; // EOF?
2002-12-27 23:43:20 +01:00
muxer_write_chunk ( muxer , mux_a , muxer_f , len , 0x10 ) ;
2001-11-03 22:09:21 +01:00
if ( ! mux_a - > h . dwSampleSize & & mux_a - > timer > 0 )
2001-12-06 22:50:35 +01:00
mux_a - > wf - > nAvgBytesPerSec = 0.5f + ( double ) mux_a - > size / mux_a - > timer ; // avg bps (VBR)
2001-10-31 17:08:01 +01:00
if ( mux_a - > buffer_len > = len ) {
mux_a - > buffer_len - = len ;
memcpy ( mux_a - > buffer , mux_a - > buffer + len , mux_a - > buffer_len ) ;
}
2002-04-12 12:40:38 +02:00
audiosamples + + ;
audiorate + = ( GetTimerMS ( ) - ptimer_start ) ;
2001-10-31 00:17:35 +01:00
}
}
// get video frame!
2002-04-12 12:40:38 +02:00
2001-10-31 00:17:35 +01:00
in_size = video_read_frame ( sh_video , & frame_time , & start , force_fps ) ;
2002-06-13 23:35:10 +02:00
if ( in_size < 0 ) { at_eof = 1 ; break ; }
2001-12-07 00:59:46 +01:00
sh_video - > timer + = frame_time ; + + decoded_frameno ;
2002-04-12 12:40:38 +02:00
2002-12-28 13:51:05 +01:00
v_timer_corr - = frame_time - ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
2002-04-11 04:52:03 +02:00
if ( demuxer2 ) { // 3-pass encoding, read control file (frameno.avi)
2002-01-26 23:30:02 +01:00
// find our frame:
while ( next_frameno < decoded_frameno ) {
int * start ;
int len = ds_get_packet ( demuxer2 - > video , ( unsigned char * * ) & start ) ;
2002-06-13 23:35:10 +02:00
if ( len < 0 ) { at_eof = 1 ; break ; }
2002-01-26 23:30:02 +01:00
if ( len = = 0 ) - - skip_flag ; else // duplicate
if ( len = = 4 ) next_frameno = start [ 0 ] ;
}
2002-06-13 23:35:10 +02:00
if ( at_eof ) break ;
2002-04-12 12:40:38 +02:00
// if(skip_flag) printf("!!!!!!!!!!!!\n");
2002-01-26 23:30:02 +01:00
skip_flag = next_frameno - decoded_frameno ;
// find next frame:
while ( next_frameno < = decoded_frameno ) {
int * start ;
int len = ds_get_packet ( demuxer2 - > video , ( unsigned char * * ) & start ) ;
2002-06-13 23:35:10 +02:00
if ( len < 0 ) { at_eof = 1 ; break ; }
2002-01-26 23:30:02 +01:00
if ( len = = 0 ) - - skip_flag ; else // duplicate
if ( len = = 4 ) next_frameno = start [ 0 ] ;
}
2002-06-13 23:35:10 +02:00
// if(at_eof) break;
2002-01-26 23:30:02 +01:00
// printf("Current fno=%d requested=%d skip=%d \n",decoded_frameno,fno,skip_flag);
} else {
2001-11-01 22:47:28 +01:00
// check frame duplicate/drop:
2002-07-12 20:03:16 +02:00
//printf("\r### %5.3f ###\n",v_timer_corr);
2002-04-15 04:33:05 +02:00
if ( v_timer_corr > = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate & &
( skip_limit < 0 | | skip_flag < skip_limit ) ) {
2001-11-01 22:47:28 +01:00
v_timer_corr - = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
+ + skip_flag ; // skip
} else
2002-04-15 04:33:05 +02:00
while ( v_timer_corr < = - ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate & &
( skip_limit < 0 | | ( - skip_flag ) < skip_limit ) ) {
2001-11-01 22:47:28 +01:00
v_timer_corr + = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
- - skip_flag ; // dup
}
while ( ( v_pts_corr < = - ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate & & skip_flag > 0 )
| | ( v_pts_corr < = - 2 * ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ) ) {
v_pts_corr + = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
- - skip_flag ; // dup
}
if ( ( v_pts_corr > = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate & & skip_flag < 0 )
| | ( v_pts_corr > = 2 * ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ) )
if ( skip_flag < = 0 ) { // we can't skip more than 1 frame now
v_pts_corr - = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
+ + skip_flag ; // skip
}
2001-10-29 02:11:18 +01:00
2002-01-26 23:30:02 +01:00
} // demuxer2
2002-04-12 12:40:38 +02:00
ptimer_start = GetTimerMS ( ) ;
2001-10-29 02:11:18 +01:00
switch ( mux_v - > codec ) {
2001-12-08 13:21:23 +01:00
case VCODEC_COPY :
2001-10-30 22:55:28 +01:00
mux_v - > buffer = start ;
2002-12-27 23:43:20 +01:00
if ( skip_flag < = 0 ) muxer_write_chunk ( muxer , mux_v , muxer_f , in_size , ( sh_video - > ds - > flags & 1 ) ? 0x10 : 0 ) ;
2001-10-30 22:55:28 +01:00
break ;
2002-04-11 04:52:03 +02:00
case VCODEC_FRAMENO :
2002-06-27 21:33:28 +02:00
mux_v - > buffer = ( unsigned char * ) & decoded_frameno ; // tricky
2002-12-27 23:43:20 +01:00
if ( skip_flag < = 0 ) muxer_write_chunk ( muxer , mux_v , muxer_f , sizeof ( int ) , 0x10 ) ;
2002-02-07 21:22:03 +01:00
break ;
2002-04-11 04:52:03 +02:00
default :
// decode_video will callback down to ve_*.c encoders, through the video filters
blit_frame = decode_video ( sh_video , start , in_size , ( skip_flag > 0 ) ? 1 : 0 ) ;
2002-09-11 01:19:20 +02:00
if ( ! blit_frame ) {
badframes + + ;
if ( skip_flag < = 0 ) {
2002-07-12 20:03:16 +02:00
// unwanted skipping of a frame, what to do?
if ( skip_limit = = 0 ) {
// skipping not allowed -> write empty frame:
2002-12-27 23:43:20 +01:00
muxer_write_chunk ( muxer , mux_v , muxer_f , 0 , 0 ) ;
2002-07-12 20:03:16 +02:00
} else {
// skipping allowed -> skip it and distriubute timer error:
v_timer_corr - = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
}
2002-09-11 01:19:20 +02:00
}
2002-07-12 20:03:16 +02:00
}
2001-10-29 02:11:18 +01:00
}
2001-11-01 22:47:28 +01:00
2002-04-12 12:40:38 +02:00
videosamples + + ;
videorate + = ( GetTimerMS ( ) - ptimer_start ) ;
2001-11-01 22:47:28 +01:00
if ( skip_flag < 0 ) {
2001-11-01 03:31:23 +01:00
// duplicate frame
2002-08-07 20:24:25 +02:00
if ( ! tv_param_on & & ! verbose ) printf ( MSGTR_DuplicateFrames , - skip_flag ) ;
2001-11-01 22:47:28 +01:00
while ( skip_flag < 0 ) {
2002-04-12 12:40:38 +02:00
duplicatedframes + + ;
2002-12-27 23:43:20 +01:00
muxer_write_chunk ( muxer , mux_v , muxer_f , 0 , 0 ) ;
2001-11-01 22:47:28 +01:00
+ + skip_flag ;
}
2001-11-02 21:05:36 +01:00
} else
if ( skip_flag > 0 ) {
2001-11-01 03:31:23 +01:00
// skip frame
2002-08-07 20:24:25 +02:00
if ( ! tv_param_on & & ! verbose ) printf ( MSGTR_SkipFrame ) ;
2002-04-12 12:40:38 +02:00
skippedframes + + ;
2001-11-01 22:47:28 +01:00
- - skip_flag ;
2001-11-01 03:31:23 +01:00
}
2002-01-26 23:30:02 +01:00
if ( sh_audio & & ! demuxer2 ) {
2001-11-01 03:31:23 +01:00
float AV_delay , x ;
// A-V sync!
2002-11-02 01:45:12 +01:00
#if 0
2001-11-01 03:31:23 +01:00
if ( pts_from_bps ) {
unsigned int samples = ( sh_audio - > audio . dwSampleSize ) ?
( ( ds_tell ( d_audio ) - sh_audio - > a_in_buffer_len ) / sh_audio - > audio . dwSampleSize ) :
2002-08-02 19:44:16 +02:00
( d_audio - > block_no ) ; // <- used for VBR audio
2002-01-27 15:35:48 +01:00
// printf("samples=%d \n",samples);
2001-11-01 03:31:23 +01:00
a_pts = samples * ( float ) sh_audio - > audio . dwScale / ( float ) sh_audio - > audio . dwRate ;
delay_corrected = 1 ;
2002-11-02 01:45:12 +01:00
} else
# endif
{
2001-11-01 03:31:23 +01:00
// PTS = (last timestamp) + (bytes after last timestamp)/(bytes per sec)
a_pts = d_audio - > pts ;
if ( ! delay_corrected ) if ( a_pts ) delay_corrected = 1 ;
//printf("*** %5.3f ***\n",a_pts);
a_pts + = ( ds_tell_pts ( d_audio ) - sh_audio - > a_in_buffer_len ) / ( float ) sh_audio - > i_bps ;
}
2003-01-17 00:03:06 +01:00
v_pts = sh_video ? sh_video - > pts : d_video - > pts ;
2001-11-01 03:31:23 +01:00
// av = compensated (with out buffering delay) A-V diff
2001-11-01 22:47:28 +01:00
AV_delay = ( a_pts - v_pts ) ; AV_delay - = mux_a - > timer - ( mux_v - > timer - ( v_timer_corr + v_pts_corr ) ) ;
2001-11-01 03:31:23 +01:00
// compensate input video timer by av:
x = AV_delay * 0.1f ;
if ( x < - max_pts_correction ) x = - max_pts_correction ; else
if ( x > max_pts_correction ) x = max_pts_correction ;
if ( default_max_pts_correction > = 0 )
max_pts_correction = default_max_pts_correction ;
else
max_pts_correction = sh_video - > frametime * 0.10 ; // +-10% of time
// sh_video->timer-=x;
c_total + = x ;
2001-11-01 22:47:28 +01:00
v_pts_corr + = x ;
2001-11-01 03:31:23 +01:00
}
2002-01-27 19:29:33 +01:00
// printf("A:%6.1f V:%6.1f A-V:%7.3f oAV:%7.3f diff:%7.3f ct:%7.3f vpc:%7.3f \r",
// a_pts,v_pts,a_pts-v_pts,
// (float)(mux_a->timer-mux_v->timer),
// AV_delay, c_total, v_pts_corr );
// printf("V:%6.1f \r", d_video->pts );
2001-11-01 03:31:23 +01:00
#if 0
mp_msg ( MSGT_AVSYNC , MSGL_STATUS , " A:%6.1f V:%6.1f A-V:%7.3f ct:%7.3f %3d/%3d %2d%% %2d%% %4.1f%% %d%% \r " ,
a_pts , v_pts , a_pts - v_pts , c_total ,
( int ) sh_video - > num_frames , ( int ) sh_video - > num_frames_decoded ,
( sh_video - > timer > 0.5 ) ? ( int ) ( 100.0 * video_time_usage / ( double ) sh_video - > timer ) : 0 ,
( sh_video - > timer > 0.5 ) ? ( int ) ( 100.0 * vout_time_usage / ( double ) sh_video - > timer ) : 0 ,
( sh_video - > timer > 0.5 ) ? ( 100.0 * audio_time_usage / ( double ) sh_video - > timer ) : 0
, cache_fill_status
) ;
# endif
2002-01-27 19:29:33 +01:00
{ float t = ( GetTimerMS ( ) - timer_start ) * 0.001f ;
float len = ( demuxer - > movi_end - demuxer - > movi_start ) ;
float p = len > 1000 ? ( float ) ( demuxer - > filepos - demuxer - > movi_start ) / len : 0 ;
2002-11-02 01:45:12 +01:00
#if 0
2002-01-27 22:37:46 +01:00
if ( ! len & & sh_audio & & sh_audio - > audio . dwLength > 100 ) {
2002-08-02 19:44:16 +02:00
p = ( sh_audio - > audio . dwSampleSize ? ds_tell ( sh_audio - > ds ) / sh_audio - > audio . dwSampleSize : sh_audio - > ds - > block_no )
2002-01-27 22:37:46 +01:00
/ ( float ) ( sh_audio - > audio . dwLength ) ;
}
2002-11-02 01:45:12 +01:00
# endif
2002-01-27 21:34:31 +01:00
#if 0
mp_msg ( MSGT_AVSYNC , MSGL_STATUS , " %d < %d < %d \r " ,
( int ) demuxer - > movi_start ,
( int ) demuxer - > filepos ,
( int ) demuxer - > movi_end ) ;
# else
2002-11-01 18:46:45 +01:00
if ( verbose > 0 ) {
2002-09-11 01:19:20 +02:00
mp_msg ( MSGT_AVSYNC , MSGL_STATUS , " Pos:%6.1fs %6df (%2d%%) %3dfps Trem:%4dmin %3dmb A-V:%5.3f [%d:%d] A/Vms %d/%d D/B/S %d/%d/%d \r " ,
2002-04-12 12:40:38 +02:00
mux_v - > timer , decoded_frameno , ( int ) ( p * 100 ) ,
2002-08-21 23:31:20 +02:00
( t > 1 ) ? ( int ) ( decoded_frameno / t + 0.5 ) : 0 ,
2002-04-12 12:40:38 +02:00
( p > 0.001 ) ? ( int ) ( ( t / p - t ) / 60 ) : 0 ,
( p > 0.001 ) ? ( int ) ( ftello ( muxer_f ) / p / 1024 / 1024 ) : 0 ,
v_pts_corr ,
( mux_v - > timer > 1 ) ? ( int ) ( mux_v - > size / mux_v - > timer / 125 ) : 0 ,
( mux_a & & mux_a - > timer > 1 ) ? ( int ) ( mux_a - > size / mux_a - > timer / 125 ) : 0 ,
audiorate / audiosamples , videorate / videosamples ,
2002-09-11 01:19:20 +02:00
duplicatedframes , badframes , skippedframes
2002-04-12 12:40:38 +02:00
) ;
} else
2002-01-27 22:46:06 +01:00
mp_msg ( MSGT_AVSYNC , MSGL_STATUS , " Pos:%6.1fs %6df (%2d%%) %3dfps Trem:%4dmin %3dmb A-V:%5.3f [%d:%d] \r " ,
2002-01-27 19:29:33 +01:00
mux_v - > timer , decoded_frameno , ( int ) ( p * 100 ) ,
2002-08-21 23:31:20 +02:00
( t > 1 ) ? ( int ) ( decoded_frameno / t + 0.5 ) : 0 ,
2002-01-27 21:34:31 +01:00
( p > 0.001 ) ? ( int ) ( ( t / p - t ) / 60 ) : 0 ,
2002-12-15 20:08:11 +01:00
( p > 0.001 ) ? ( int ) ( ftello ( muxer_f ) / p / 1024 / 1024 ) : 0 ,
2002-01-27 22:46:06 +01:00
v_pts_corr ,
( mux_v - > timer > 1 ) ? ( int ) ( mux_v - > size / mux_v - > timer / 125 ) : 0 ,
2002-01-31 01:38:53 +01:00
( mux_a & & mux_a - > timer > 1 ) ? ( int ) ( mux_a - > size / mux_a - > timer / 125 ) : 0
2002-01-27 19:29:33 +01:00
) ;
2002-01-27 21:34:31 +01:00
# endif
2002-01-27 19:29:33 +01:00
}
2001-11-01 03:31:23 +01:00
fflush ( stdout ) ;
2002-04-17 23:51:18 +02:00
# ifdef USE_SUB
// find sub
2003-01-17 00:03:06 +01:00
if ( subtitles & & sh_video - > pts > 0 ) {
float pts = sh_video - > pts ;
2002-04-17 23:51:18 +02:00
if ( sub_fps = = 0 ) sub_fps = sh_video - > fps ;
if ( pts > sub_last_pts | | pts < sub_last_pts - 1.0 ) {
find_sub ( subtitles , sub_uses_time ? ( 100 * ( pts + sub_delay ) ) : ( ( pts + sub_delay ) * sub_fps ) ) ; // FIXME! frame counter...
sub_last_pts = pts ;
}
}
# endif
# ifdef USE_DVDREAD
// DVD sub:
2002-07-08 23:44:51 +02:00
if ( vo_spudec | | vobsub_writer ) {
2002-04-17 23:51:18 +02:00
unsigned char * packet = NULL ;
int len ;
while ( ( len = ds_get_packet_sub ( d_dvdsub , & packet ) ) > 0 ) {
2003-01-17 00:03:06 +01:00
mp_msg ( MSGT_MENCODER , MSGL_V , " \r DVD sub: len=%d v_pts=%5.3f s_pts=%5.3f \n " , len , sh_video - > pts , d_dvdsub - > pts ) ;
2002-07-08 23:44:51 +02:00
if ( vo_spudec )
2002-04-17 23:51:18 +02:00
spudec_assemble ( vo_spudec , packet , len , 90000 * d_dvdsub - > pts ) ;
2002-07-08 23:44:51 +02:00
if ( vobsub_writer )
2003-01-17 00:03:06 +01:00
vobsub_out_output ( vobsub_writer , packet , len , mux_v - > timer + d_dvdsub - > pts - sh_video - > pts ) ;
2002-04-17 23:51:18 +02:00
}
2002-07-08 23:44:51 +02:00
if ( vo_spudec ) {
2003-01-17 00:03:06 +01:00
spudec_heartbeat ( vo_spudec , 90000 * sh_video - > pts ) ;
2002-04-18 00:17:32 +02:00
vo_osd_changed ( OSDTYPE_SPU ) ;
2002-07-08 23:44:51 +02:00
}
2002-04-17 23:51:18 +02:00
}
# endif
2001-10-29 02:11:18 +01:00
2002-06-08 00:40:06 +02:00
if ( ferror ( muxer_f ) ) {
2002-08-07 20:24:25 +02:00
mp_msg ( MSGT_MENCODER , MSGL_FATAL , MSGTR_ErrorWritingFile , out_filename ) ;
2002-06-08 00:40:06 +02:00
mencoder_exit ( 1 , NULL ) ;
}
2001-10-29 02:11:18 +01:00
2002-06-13 23:35:10 +02:00
} // while(!at_eof)
2001-10-29 02:11:18 +01:00
2001-12-06 23:27:09 +01:00
# ifdef HAVE_MP3LAME
// fixup CBR mp3 audio header:
2001-12-06 22:50:35 +01:00
if ( sh_audio & & mux_a - > codec = = ACODEC_VBRMP3 & & ! lame_param_vbr ) {
mux_a - > h . dwSampleSize = 1 ;
2002-04-18 16:23:07 +02:00
( ( MPEGLAYER3WAVEFORMAT * ) ( mux_a - > wf ) ) - > nBlockSize =
( mux_a - > size + ( mux_a - > h . dwLength > > 1 ) ) / mux_a - > h . dwLength ;
mux_a - > h . dwLength = mux_a - > size ;
2001-12-06 22:50:35 +01:00
mux_a - > h . dwRate = mux_a - > wf - > nAvgBytesPerSec ;
mux_a - > h . dwScale = 1 ;
2002-04-18 16:23:07 +02:00
mux_a - > wf - > nBlockAlign = 1 ;
2002-11-07 00:54:29 +01:00
printf ( " \n \n CBR audio: %ld bytes/sec, %d bytes/block \n " ,
2002-04-18 16:23:07 +02:00
mux_a - > h . dwRate , ( ( MPEGLAYER3WAVEFORMAT * ) ( mux_a - > wf ) ) - > nBlockSize ) ;
2001-12-06 22:50:35 +01:00
}
2001-12-06 23:27:09 +01:00
# endif
2001-12-06 22:50:35 +01:00
2002-08-07 20:24:25 +02:00
printf ( MSGTR_WritingAVIIndex ) ;
2002-12-27 23:43:20 +01:00
muxer_write_index ( muxer , muxer_f ) ;
2002-04-12 12:40:38 +02:00
muxer_f_size = ftello ( muxer_f ) ;
2002-08-07 20:24:25 +02:00
printf ( MSGTR_FixupAVIHeader ) ;
2001-10-29 02:11:18 +01:00
fseek ( muxer_f , 0 , SEEK_SET ) ;
2002-12-27 23:43:20 +01:00
muxer_write_header ( muxer , muxer_f ) ; // update header
2002-06-08 00:40:06 +02:00
if ( ferror ( muxer_f ) | | fclose ( muxer_f ) ! = 0 ) {
2002-08-07 20:24:25 +02:00
mp_msg ( MSGT_MENCODER , MSGL_FATAL , MSGTR_ErrorWritingFile , out_filename ) ;
2002-06-08 00:40:06 +02:00
mencoder_exit ( 1 , NULL ) ;
}
2002-07-08 23:44:51 +02:00
if ( vobsub_writer )
vobsub_out_close ( vobsub_writer ) ;
2002-01-27 01:43:57 +01:00
if ( out_video_codec = = VCODEC_FRAMENO & & mux_v - > timer > 100 ) {
2002-08-07 20:24:25 +02:00
printf ( MSGTR_RecommendedVideoBitrate , " 650MB " , ( int ) ( ( 650 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
printf ( MSGTR_RecommendedVideoBitrate , " 700MB " , ( int ) ( ( 700 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
printf ( MSGTR_RecommendedVideoBitrate , " 800MB " , ( int ) ( ( 800 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
2002-09-22 15:37:11 +02:00
printf ( MSGTR_RecommendedVideoBitrate , " 2 x 650MB " , ( int ) ( ( 2 * 650 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
printf ( MSGTR_RecommendedVideoBitrate , " 2 x 700MB " , ( int ) ( ( 2 * 700 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
printf ( MSGTR_RecommendedVideoBitrate , " 2 x 800MB " , ( int ) ( ( 2 * 800 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
2002-01-27 01:43:57 +01:00
}
2002-08-07 20:24:25 +02:00
printf ( MSGTR_VideoStreamResult ,
2002-04-12 12:40:38 +02:00
( float ) ( mux_v - > size / mux_v - > timer * 8.0f / 1000.0f ) , ( int ) ( mux_v - > size / mux_v - > timer ) , ( int ) mux_v - > size , ( float ) mux_v - > timer , decoded_frameno ) ;
2001-12-07 00:59:46 +01:00
if ( sh_audio )
2002-08-07 20:24:25 +02:00
printf ( MSGTR_AudioStreamResult ,
2002-04-12 12:40:38 +02:00
( float ) ( mux_a - > size / mux_a - > timer * 8.0f / 1000.0f ) , ( int ) ( mux_a - > size / mux_a - > timer ) , ( int ) mux_a - > size , ( float ) mux_a - > timer ) ;
2001-12-07 00:59:46 +01:00
2002-09-25 22:27:34 +02:00
if ( sh_video ) { uninit_video ( sh_video ) ; sh_video = NULL ; }
if ( demuxer ) free_demuxer ( demuxer ) ;
2001-11-02 02:25:13 +01:00
if ( stream ) free_stream ( stream ) ; // kill cache thread
2001-12-04 21:35:31 +01:00
return interrupted ;
2001-10-29 02:11:18 +01:00
}
2002-01-15 01:20:50 +01:00
static int parse_end_at ( struct config * conf , const char * param )
{
end_at_type = END_AT_NONE ;
/* End at size parsing */
{
char unit [ 4 ] ;
end_at_type = END_AT_SIZE ;
2002-12-14 18:56:35 +01:00
if ( sscanf ( param , " %lf%3s " , & end_at , unit ) = = 2 ) {
2002-01-15 01:20:50 +01:00
if ( ! strcasecmp ( unit , " b " ) )
;
else if ( ! strcasecmp ( unit , " kb " ) )
end_at * = 1024 ;
else if ( ! strcasecmp ( unit , " mb " ) )
end_at * = 1024 * 1024 ;
else
end_at_type = END_AT_NONE ;
}
else
end_at_type = END_AT_NONE ;
}
/* End at time parsing. This has to be last because of
* sscanf ( " %f " , . . . ) below */
if ( end_at_type = = END_AT_NONE )
{
int a , b ; float d ;
end_at_type = END_AT_TIME ;
if ( sscanf ( param , " %d:%d:%f " , & a , & b , & d ) = = 3 )
end_at = 3600 * a + 60 * b + d ;
else if ( sscanf ( param , " %d:%f " , & a , & d ) = = 2 )
end_at = 60 * a + d ;
else if ( sscanf ( param , " %f " , & d ) = = 1 )
end_at = d ;
else
end_at_type = END_AT_NONE ;
}
if ( end_at_type = = END_AT_NONE )
return ERR_FUNC_ERR ;
return 1 ;
}
2002-01-31 01:38:53 +01:00
2002-09-20 20:54:22 +02:00
#if 0
2002-01-31 01:38:53 +01:00
/* Flip the image in src and store the result in dst. src and dst may overlap.
width is the size of each line in bytes . */
static uint8_t * flip_upside_down ( uint8_t * dst , const uint8_t * src , int width ,
int height )
{
uint8_t * tmp = malloc ( width ) ;
int i ;
for ( i = 0 ; i < height / 2 ; i + + ) {
memcpy ( tmp , & src [ i * width ] , width ) ;
memcpy ( & dst [ i * width ] , & src [ ( height - i ) * width ] , width ) ;
memcpy ( & dst [ ( height - i ) * width ] , tmp , width ) ;
}
free ( tmp ) ;
return dst ;
}
2002-09-20 20:54:22 +02:00
# endif
2002-12-21 23:16:49 +01:00
# if HAVE_MP3LAME >= 392
/* lame_presets_set
taken out of presets_set in lame - 3.93 .1 / frontend / parse . c and modified */
static int lame_presets_set ( lame_t gfp , int fast , int cbr , const char * preset_name )
{
int mono = 0 ;
if ( strcmp ( preset_name , " help " ) = = 0 ) {
fprintf ( stdout , " LAME version %s (%s) \n \n " , get_lame_version ( ) , get_lame_url ( ) ) ;
lame_presets_longinfo_dm ( stdout ) ;
return - 1 ;
}
//aliases for compatibility with old presets
if ( strcmp ( preset_name , " phone " ) = = 0 ) {
preset_name = " 16 " ;
mono = 1 ;
}
if ( ( strcmp ( preset_name , " phon+ " ) = = 0 ) | |
( strcmp ( preset_name , " lw " ) = = 0 ) | |
( strcmp ( preset_name , " mw-eu " ) = = 0 ) | |
( strcmp ( preset_name , " sw " ) = = 0 ) ) {
preset_name = " 24 " ;
mono = 1 ;
}
if ( strcmp ( preset_name , " mw-us " ) = = 0 ) {
preset_name = " 40 " ;
mono = 1 ;
}
if ( strcmp ( preset_name , " voice " ) = = 0 ) {
preset_name = " 56 " ;
mono = 1 ;
}
if ( strcmp ( preset_name , " fm " ) = = 0 ) {
preset_name = " 112 " ;
}
if ( ( strcmp ( preset_name , " radio " ) = = 0 ) | |
( strcmp ( preset_name , " tape " ) = = 0 ) ) {
preset_name = " 112 " ;
}
if ( strcmp ( preset_name , " hifi " ) = = 0 ) {
preset_name = " 160 " ;
}
if ( strcmp ( preset_name , " cd " ) = = 0 ) {
preset_name = " 192 " ;
}
if ( strcmp ( preset_name , " studio " ) = = 0 ) {
preset_name = " 256 " ;
}
# if HAVE_MP3LAME >= 393
if ( strcmp ( preset_name , " medium " ) = = 0 ) {
if ( fast > 0 )
lame_set_preset ( gfp , MEDIUM_FAST ) ;
else
lame_set_preset ( gfp , MEDIUM ) ;
return 0 ;
}
# endif
if ( strcmp ( preset_name , " standard " ) = = 0 ) {
if ( fast > 0 )
lame_set_preset ( gfp , STANDARD_FAST ) ;
else
lame_set_preset ( gfp , STANDARD ) ;
return 0 ;
}
else if ( strcmp ( preset_name , " extreme " ) = = 0 ) {
if ( fast > 0 )
lame_set_preset ( gfp , EXTREME_FAST ) ;
else
lame_set_preset ( gfp , EXTREME ) ;
return 0 ;
}
else if ( ( ( strcmp ( preset_name , " insane " ) = = 0 ) | |
( strcmp ( preset_name , " 320 " ) = = 0 ) ) & & ( fast < 1 ) ) {
lame_set_preset ( gfp , INSANE ) ;
return 0 ;
}
// Generic ABR Preset
if ( ( ( atoi ( preset_name ) ) > 0 ) & & ( fast < 1 ) ) {
if ( ( atoi ( preset_name ) ) > = 8 & & ( atoi ( preset_name ) ) < = 320 ) {
lame_set_preset ( gfp , atoi ( preset_name ) ) ;
if ( cbr = = 1 )
lame_set_VBR ( gfp , vbr_off ) ;
if ( mono = = 1 ) {
lame_set_mode ( gfp , MONO ) ;
}
return 0 ;
}
else {
fprintf ( stderr , " LAME version %s (%s) \n \n " , get_lame_version ( ) , get_lame_url ( ) ) ;
fprintf ( stderr , " Error: The bitrate specified is out of the valid range for this preset \n "
" \n "
" When using this mode you must enter a value between \" 8 \" and \" 320 \" \n "
" \n "
" For further information try: \" -lameopts preset=help \" \n "
) ;
return - 1 ;
}
}
fprintf ( stderr , " LAME version %s (%s) \n \n " , get_lame_version ( ) , get_lame_url ( ) ) ;
fprintf ( stderr , " Error: You did not enter a valid profile and/or options with preset \n "
" \n "
" Available profiles are: \n "
" \n "
" <fast> standard \n "
" <fast> extreme \n "
" insane \n "
" <cbr> (ABR Mode) - The ABR Mode is implied. To use it, \n "
" simply specify a bitrate. For example: \n "
" \" preset=185 \" activates this \n "
" preset and uses 185 as an average kbps. \n "
" \n "
" Some examples: \n "
" \n "
" \" -lameopts fast:preset=standard \" \n "
" or \" -lameopts cbr:preset=192 \" \n "
" or \" -lameopts preset=172 \" \n "
" or \" -lameopts preset=extreme \" \n "
" \n "
" For further information try: \" -lameopts preset=help \" \n "
) ;
mencoder_exit ( 1 , " error parsing cmdline " ) ;
}
# endif
# if HAVE_MP3LAME >= 392
/* lame_presets_longinfo_dm
taken out of presets_longinfo_dm in lame - 3.93 .1 / frontend / parse . c and modified */
static void lame_presets_longinfo_dm ( FILE * msgfp )
{
fprintf ( msgfp ,
" \n "
" The preset switches are designed to provide the highest possible quality. \n "
" \n "
" They have for the most part been subject to and tuned via rigorous double blind \n "
" listening tests to verify and achieve this objective. \n "
" \n "
" These are continually updated to coincide with the latest developments that \n "
" occur and as a result should provide you with nearly the best quality \n "
" currently possible from LAME. \n "
" \n "
" To activate these presets: \n "
" \n "
" For VBR modes (generally highest quality): \n "
" \n "
" \" preset=standard \" This preset should generally be transparent \n "
" to most people on most music and is already \n "
" quite high in quality. \n "
" \n "
" \" preset=extreme \" If you have extremely good hearing and similar \n "
" equipment, this preset will generally provide \n "
" slightly higher quality than the \" standard \" \n "
" mode. \n "
" \n "
" For CBR 320kbps (highest quality possible from the preset switches): \n "
" \n "
" \" preset=insane \" This preset will usually be overkill for most \n "
" people and most situations, but if you must \n "
" have the absolute highest quality with no \n "
" regard to filesize, this is the way to go. \n "
" \n "
" For ABR modes (high quality per given bitrate but not as high as VBR): \n "
" \n "
" \" preset=<kbps> \" Using this preset will usually give you good \n "
" quality at a specified bitrate. Depending on the \n "
" bitrate entered, this preset will determine the \n "
" optimal settings for that particular situation. \n "
" While this approach works, it is not nearly as \n "
" flexible as VBR, and usually will not attain the \n "
" same level of quality as VBR at higher bitrates. \n "
" \n "
" The following options are also available for the corresponding profiles: \n "
" \n "
" <fast> standard \n "
" <fast> extreme \n "
" insane \n "
" <cbr> (ABR Mode) - The ABR Mode is implied. To use it, \n "
" simply specify a bitrate. For example: \n "
" \" preset=185 \" activates this \n "
" preset and uses 185 as an average kbps. \n "
" \n "
" \" fast \" - Enables the new fast VBR for a particular profile. The \n "
" disadvantage to the speed switch is that often times the \n "
" bitrate will be slightly higher than with the normal mode \n "
" and quality may be slightly lower also. \n "
" Warning: with the current version fast presets might result in too \n "
" high bitrate compared to regular presets. \n "
" \n "
" \" cbr \" - If you use the ABR mode (read above) with a significant \n "
" bitrate such as 80, 96, 112, 128, 160, 192, 224, 256, 320, \n "
" you can use the \" cbr \" option to force CBR mode encoding \n "
" instead of the standard abr mode. ABR does provide higher \n "
" quality but CBR may be useful in situations such as when \n "
" streaming an mp3 over the internet may be important. \n "
" \n "
" For example: \n "
" \n "
" \" -lameopts fast:preset=standard \" \n "
" or \" -lameopts cbr:preset=192 \" \n "
" or \" -lameopts preset=172 \" \n "
" or \" -lameopts preset=extreme \" \n "
" \n "
" \n "
" A few aliases are available for ABR mode: \n "
" phone => 16kbps/mono phon+/lw/mw-eu/sw => 24kbps/mono \n "
" mw-us => 40kbps/mono voice => 56kbps/mono \n "
" fm/radio/tape => 112kbps hifi => 160kbps \n "
" cd => 192kbps studio => 256kbps " ) ;
mencoder_exit ( 0 , NULL ) ;
}
# endif