2010-01-30 23:24:23 +00:00
/*
* This file is part of MPlayer .
*
* MPlayer is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* MPlayer is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with MPlayer ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2001-12-08 12:21:23 +00:00
# define VCODEC_COPY 0
2001-12-06 23:59:46 +00:00
# define VCODEC_FRAMENO 1
2002-04-11 02:52:03 +00:00
// real codecs:
2001-12-15 17:12:20 +00:00
# define VCODEC_LIBAVCODEC 4
2002-02-07 20:22:03 +00:00
# define VCODEC_VFW 7
2002-04-12 21:50:38 +00:00
# define VCODEC_LIBDV 8
2002-09-21 12:41:29 +00:00
# define VCODEC_XVID 9
2002-12-16 01:49:39 +00:00
# define VCODEC_QTVIDEO 10
2003-03-03 11:03:19 +00:00
# define VCODEC_NUV 11
2004-02-17 12:43:07 +00:00
# define VCODEC_RAW 12
2004-08-27 20:43:05 +00:00
# define VCODEC_X264 13
2001-12-06 23:59:46 +00:00
2001-12-08 13:30:06 +00:00
# define ACODEC_COPY 0
2001-10-31 00:25:28 +00:00
# define ACODEC_PCM 1
# define ACODEC_VBRMP3 2
2002-01-27 00:43:57 +00:00
# define ACODEC_NULL 3
2003-11-03 16:35:40 +00:00
# define ACODEC_LAVC 4
2004-09-21 19:50:54 +00:00
# define ACODEC_TOOLAME 5
2005-04-25 07:07:57 +00:00
# define ACODEC_FAAC 6
2005-05-07 14:50:14 +00:00
# define ACODEC_TWOLAME 7
2001-10-29 01:11:18 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <signal.h>
2004-04-30 20:05:54 +00:00
# include "config.h"
2003-03-31 17:32:46 +00:00
# ifdef __MINGW32__
2005-07-22 17:11:39 +00:00
# define SIGHUP 1
2003-03-31 17:32:46 +00:00
# define SIGQUIT 3
2005-07-22 17:11:39 +00:00
# define SIGPIPE 13
2003-03-31 17:32:46 +00:00
# endif
2008-10-13 16:23:55 +00:00
# if defined(__MINGW32__) || defined(__CYGWIN__)
2004-04-30 16:56:00 +00:00
# include <windows.h>
# endif
2002-04-12 10:40:38 +00:00
# include <sys/time.h>
2001-10-29 01:11:18 +00:00
2002-09-29 19:26:40 +00:00
# include "mp_msg.h"
2009-10-31 21:03:48 +00:00
# include "av_log.h"
2001-10-29 01:11:18 +00:00
# include "codec-cfg.h"
2002-11-12 01:56:42 +00:00
# include "m_option.h"
# include "m_config.h"
# include "parser-mecmd.h"
2008-03-04 21:02:42 +00:00
# include "parser-cfg.h"
2010-02-23 20:16:30 +00:00
# include "mp_fifo.h"
2010-03-20 23:38:27 +00:00
# include "path.h"
2010-03-17 09:12:51 +00:00
2006-07-31 17:39:17 +00:00
# include "stream/stream.h"
2010-02-18 00:18:50 +00:00
# include "libmpdemux/aviprint.h"
2002-09-29 19:26:40 +00:00
# include "libmpdemux/demuxer.h"
# include "libmpdemux/stheader.h"
# include "libmpdemux/mp3_hdr.h"
2002-12-27 22:43:20 +00:00
# include "libmpdemux/muxer.h"
2001-10-29 01:11:18 +00:00
2010-02-23 20:16:30 +00:00
# include "input/input.h"
2001-10-29 01:11:18 +00:00
# include "libvo/video_out.h"
2004-12-27 17:30:15 +00:00
# include "libaf/af_format.h"
2002-10-05 22:55:45 +00:00
2002-09-22 00:43:14 +00:00
# include "libmpcodecs/mp_image.h"
2002-04-13 19:14:34 +00:00
# include "libmpcodecs/dec_audio.h"
# include "libmpcodecs/dec_video.h"
2002-06-27 19:33:28 +00:00
# include "libmpcodecs/vf.h"
2007-09-10 10:57:40 +00:00
# include "libmpcodecs/vd.h"
2001-10-30 21:55:28 +00:00
2002-09-22 00:43:14 +00:00
// for MPEGLAYER3WAVEFORMAT:
2004-04-28 10:18:33 +00:00
# include "libmpdemux/ms_hdr.h"
2002-09-22 00:43:14 +00:00
2001-12-01 01:29:25 +00:00
# include <inttypes.h>
2002-09-29 19:26:40 +00:00
# include "libvo/fastmemcpy.h"
2001-12-08 13:30:06 +00:00
2003-02-09 20:18:23 +00:00
# include "osdep/timer.h"
2002-09-22 02:33:28 +00:00
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_DVDREAD
2006-07-31 17:39:17 +00:00
# include "stream/stream_dvd.h"
2006-06-11 21:29:00 +00:00
# endif
2007-08-07 21:49:17 +00:00
# include "stream/stream_dvdnav.h"
2008-02-25 15:46:36 +00:00
# include "libavcodec/avcodec.h"
2004-09-21 19:50:54 +00:00
2005-04-22 06:59:59 +00:00
# include "libmpcodecs/ae.h"
2008-03-31 03:19:29 +00:00
# include "options.h"
2008-04-16 04:11:12 +00:00
# include "defaultopts.h"
2008-03-31 03:19:29 +00:00
MPOpts opts ;
2008-06-23 22:53:58 +00:00
struct osd_state * osd ;
2008-03-31 03:19:29 +00:00
2009-01-14 00:51:24 +00:00
const int under_mencoder = 1 ;
2002-04-07 02:12:15 +00:00
int vo_doublebuffering = 0 ;
int vo_directrendering = 0 ;
2003-12-08 09:32:40 +00:00
int forced_subs_only = 0 ;
2002-01-27 18:39:53 +00:00
2001-10-29 01:11:18 +00:00
//--------------------------
// cache2:
2002-10-23 22:07:29 +00:00
int stream_cache_size = - 1 ;
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_STREAM_CACHE
2001-10-29 01:11:18 +00:00
extern int cache_fill_status ;
2004-07-16 20:31:17 +00:00
float stream_cache_min_percent = 20.0 ;
2005-07-31 00:26:07 +00:00
float stream_cache_seek_min_percent = 50.0 ;
2001-10-29 01:11:18 +00:00
# else
# define cache_fill_status 0
# endif
2002-03-29 03:17:57 +00:00
int vobsub_id = - 1 ;
static char * spudec_ifo = NULL ;
2001-11-02 01:25:13 +00:00
2002-09-29 19:26:40 +00:00
static char * * audio_codec_list = NULL ; // override audio codec
static char * * video_codec_list = NULL ; // override video codec
2009-07-06 23:26:13 +00:00
static char * * audio_fm_list = NULL ; // override audio codec family
static char * * video_fm_list = NULL ; // override video codec family
2005-08-05 19:57:47 +00:00
extern char * demuxer_name ; // override demuxer
extern char * audio_demuxer_name ; // override audio demuxer
extern char * sub_demuxer_name ; // override sub demuxer
2001-10-29 01:11:18 +00:00
2002-09-29 19:26:40 +00:00
static int out_audio_codec = - 1 ;
static int out_video_codec = - 1 ;
2002-02-10 00:07:34 +00:00
2002-12-27 22:43:20 +00:00
int out_file_format = MUXER_TYPE_AVI ; // default to AVI
2004-01-29 12:01:26 +00:00
int quiet = 0 ;
2001-10-29 01:11:18 +00:00
double video_time_usage = 0 ;
double vout_time_usage = 0 ;
2002-02-24 11:23:48 +00:00
double max_video_time_usage = 0 ;
double max_vout_time_usage = 0 ;
2002-02-24 15:54:13 +00:00
double cur_video_time_usage = 0 ;
double cur_vout_time_usage = 0 ;
2002-02-24 17:10:06 +00:00
int benchmark = 0 ;
2001-10-29 01:11:18 +00:00
2009-02-10 15:34:44 +00:00
# include "osdep/priority.h"
2005-04-02 18:29:16 +00:00
2001-11-01 02:31:23 +00: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 19:26:40 +00:00
static float audio_preload = 0.5 ;
2005-07-17 19:25:33 +00:00
static float audio_delay_fix = 0.0 ;
2005-07-17 19:40:05 +00:00
static float audio_delay = 0.0 ;
2006-02-20 09:36:10 +00:00
static int ignore_start = 0 ;
2002-09-29 19:26:40 +00:00
static int audio_density = 2 ;
2002-08-01 08:39:33 +00:00
2008-02-14 14:50:34 +00:00
double force_fps = 0 ;
static double force_ofps = 0 ; // set to 24 for inverse telecine
2002-04-15 02:33:05 +00:00
static int skip_limit = - 1 ;
2001-10-29 01:11:18 +00:00
2002-09-29 19:26:40 +00:00
static int force_srate = 0 ;
2002-10-06 11:23:02 +00:00
static int audio_output_format = 0 ;
2001-11-02 01:25:13 +00:00
2002-07-08 21:44:51 +00:00
char * vobsub_out = NULL ;
unsigned int vobsub_out_index = 0 ;
char * vobsub_out_id = NULL ;
2005-12-15 17:57:18 +00:00
char * out_filename = NULL ;
2001-11-02 03:22:33 +00:00
2001-12-22 14:32:08 +00:00
char * force_fourcc = NULL ;
2005-07-02 19:00:13 +00:00
int force_audiofmttag = - 1 ;
2001-12-22 14:32:08 +00:00
2002-04-11 02:52:03 +00:00
char * passtmpfile = " divx2pass.log " ;
2001-11-03 00:44:02 +00:00
static int play_n_frames = - 1 ;
2002-06-28 17:13:18 +00:00
static int play_n_frames_mf = - 1 ;
2001-11-03 00:44:02 +00:00
2002-04-17 21:51:18 +00:00
# include "libvo/font_load.h"
# include "libvo/sub.h"
// sub:
char * font_name = NULL ;
2007-05-20 16:10:45 +00:00
char * sub_font_name = NULL ;
2003-12-08 13:30:30 +00:00
extern int font_fontconfig ;
2002-04-17 21:51:18 +00:00
float font_factor = 0.75 ;
2003-04-07 16:04:02 +00:00
char * * sub_name = NULL ;
2002-04-17 21:51:18 +00:00
float sub_delay = 0 ;
float sub_fps = 0 ;
int sub_auto = 0 ;
2002-07-25 03:37:28 +00:00
int subcc_enabled = 0 ;
2002-12-05 00:03:35 +00:00
int suboverlap_enabled = 1 ;
2002-04-17 21:51:18 +00:00
2003-01-24 01:04:50 +00:00
int auto_expand = 1 ;
2004-04-28 04:02:46 +00:00
int encode_duplicates = 1 ;
2003-01-24 01:04:50 +00:00
2002-08-29 20:50:49 +00: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 ;
2007-02-17 20:58:55 +00:00
// Needed by libmpcodecs vf_vo.c
2008-04-03 03:25:41 +00:00
int vo_config ( struct vo * vo , uint32_t width , uint32_t height ,
uint32_t d_width , uint32_t d_height , uint32_t flags ,
char * title , uint32_t format ) { abort ( ) ; }
int vo_control ( struct vo * vo , uint32_t request , void * data ) { abort ( ) ; }
2009-12-02 10:50:56 +00:00
void vo_seek_reset ( struct vo * vo ) { abort ( ) ; }
2009-09-18 13:27:55 +00:00
int vo_draw_image ( struct vo * vo , struct mp_image * mpi , double pts ) { abort ( ) ; }
2008-04-03 03:25:41 +00:00
int vo_draw_frame ( struct vo * vo , uint8_t * src [ ] ) { abort ( ) ; }
int vo_draw_slice ( struct vo * vo , uint8_t * src [ ] , int stride [ ] , int w , int h , int x , int y ) { abort ( ) ; }
2008-06-23 22:53:58 +00:00
void vo_draw_osd ( struct vo * vo , struct osd_state * osd ) { abort ( ) ; }
2009-11-15 02:39:22 +00:00
void vo_flip_page ( struct vo * vo , uint32_t pts_us , int duration ) { abort ( ) ; }
2008-04-03 03:25:41 +00:00
void vo_check_events ( struct vo * vo ) { abort ( ) ; }
2007-08-25 04:28:08 +00:00
// Needed by getch2
2008-04-29 12:12:19 +00:00
struct mp_fifo ;
void mplayer_put_key ( struct mp_fifo * fifo , int code )
2007-08-25 04:28:08 +00:00
{
}
2002-04-17 21:51:18 +00:00
2009-07-25 04:24:39 +00:00
# include "ass_mp.h"
2007-02-17 21:04:46 +00:00
char * current_module ;
# include "mpcommon.h"
2006-07-07 18:26:51 +00:00
2009-09-23 21:48:48 +00:00
// Needed by mpcommon.c
2009-10-06 01:28:59 +00:00
void set_osd_subtitle ( struct MPContext * mpctx , subtitle * subs ) {
2009-09-23 21:48:48 +00:00
vo_sub = subs ;
vo_osd_changed ( OSDTYPE_SUBTITLE ) ;
}
2001-11-02 01:25:13 +00:00
//-------------------------- config stuff:
2002-01-14 23:38:49 +00:00
m_config_t * mconfig ;
2003-08-13 16:29:32 +00:00
static int cfg_inc_verbose ( m_option_t * conf ) { + + verbose ; return 0 ; }
2001-11-02 01:25:13 +00:00
2003-08-13 16:29:32 +00:00
static int cfg_include ( m_option_t * conf , char * filename ) {
2002-01-14 23:38:49 +00:00
return m_config_parse_config_file ( mconfig , filename ) ;
2001-11-02 01:25:13 +00:00
}
2007-02-24 07:11:57 +00:00
static double seek_to_sec ;
2002-02-10 00:07:34 +00:00
static off_t seek_to_byte = 0 ;
2006-09-25 16:47:56 +00:00
static m_time_size_t end_at = { . type = END_AT_NONE , . pos = 0 } ;
2005-09-19 19:23:38 +00:00
static char * frameno_filename = NULL ;
2005-07-17 19:25:58 +00:00
typedef struct {
unsigned char * start ;
int in_size ;
float frame_time ;
int already_read ;
} s_frame_data ;
2005-03-19 20:55:51 +00:00
# include "edl.h"
static edl_record_ptr edl_records = NULL ; ///< EDL entries memory area
static edl_record_ptr next_edl_record = NULL ; ///< only for traversing edl_records
static short edl_muted ; ///< Stores whether EDL is currently in muted mode.
static short edl_seeking ; ///< When non-zero, stream is seekable.
static short edl_seek_type ; ///< When non-zero, frames are discarded instead of seeking.
2001-11-02 01:25:13 +00:00
# include "cfg-mencoder.h"
2002-01-11 16:06:45 +00:00
# include "spudec.h"
2002-03-29 03:17:57 +00:00
# include "vobsub.h"
2002-01-11 16:06:45 +00:00
2005-05-22 15:34:23 +00:00
# include "libao2/audio_out.h"
2002-02-17 13:50:26 +00:00
/* FIXME */
2006-07-09 17:45:36 +00:00
static void mencoder_exit ( int level , const char * how )
2002-02-17 13:50:26 +00:00
{
if ( how )
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " \n Exiting... (%s) \n " , how ) ;
2002-02-17 13:50:26 +00:00
else
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " \n Exiting... \n " ) ;
2002-02-17 13:50:26 +00:00
exit ( level ) ;
}
2006-07-03 23:18:06 +00:00
static void parse_cfgfiles ( m_config_t * conf )
2002-02-02 23:39:53 +00:00
{
char * conffile ;
2008-04-14 11:21:29 +00:00
if ( ! disable_system_conf & &
m_config_parse_config_file ( conf , MPLAYER_CONFDIR " /mencoder.conf " ) < 0 )
2009-07-06 23:26:13 +00:00
mencoder_exit ( 1 , _ ( " config file error " ) ) ;
2008-04-14 11:05:52 +00:00
2008-04-14 11:21:29 +00:00
if ( ! disable_user_conf ) {
2008-04-14 11:24:24 +00:00
if ( ( conffile = get_path ( " mencoder.conf " ) ) = = NULL ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_ERR , " get_path( \" config \" ) problem \n " ) ;
2008-04-14 11:24:24 +00:00
} else {
if ( m_config_parse_config_file ( conf , conffile ) < 0 )
2009-07-06 22:15:02 +00:00
mencoder_exit ( 1 , _ ( " config file error " ) ) ;
2008-04-14 11:24:24 +00:00
free ( conffile ) ;
}
2008-04-14 11:21:29 +00:00
}
2002-02-02 23:39:53 +00:00
}
2002-04-12 10:40:38 +00:00
2001-10-31 16:08:01 +00:00
//---------------------------------------------------------------------------
2002-09-29 19:26:40 +00:00
static int dec_audio ( sh_audio_t * sh_audio , unsigned char * buffer , int total ) {
2001-10-31 16:08:01 +00:00
int size = 0 ;
2002-06-13 21:35:10 +00:00
int at_eof = 0 ;
while ( size < total & & ! at_eof ) {
2001-10-31 16:08:01 +00:00
int len = total - size ;
2007-11-01 06:52:19 +00:00
if ( decode_audio ( sh_audio , len ) < 0 ) at_eof = 1 ;
2002-10-05 22:55:45 +00:00
if ( len > sh_audio - > a_out_buffer_len ) len = sh_audio - > a_out_buffer_len ;
2007-06-05 14:27:54 +00:00
fast_memcpy ( buffer + size , sh_audio - > a_out_buffer , len ) ;
2002-10-05 22:55:45 +00:00
sh_audio - > a_out_buffer_len - = len ; size + = len ;
if ( sh_audio - > a_out_buffer_len > 0 )
2007-06-05 14:27:54 +00:00
fast_memcpy ( sh_audio - > a_out_buffer , & sh_audio - > a_out_buffer [ len ] , sh_audio - > a_out_buffer_len ) ;
2001-10-31 16:08:01 +00:00
}
return size ;
}
//---------------------------------------------------------------------------
2001-10-29 01:11:18 +00:00
2008-04-03 16:57:16 +00:00
static volatile int at_eof = 0 ;
static volatile int interrupted = 0 ;
2001-10-29 01:11:18 +00:00
static void exit_sighandler ( int x ) {
2002-06-13 21:35:10 +00:00
at_eof = 1 ;
2004-01-29 12:01:26 +00:00
interrupted = 2 ; /* 1 means error */
2001-10-29 01:11:18 +00:00
}
2002-12-27 22:43:20 +00:00
static muxer_t * muxer = NULL ;
2002-04-11 02:52:03 +00:00
2010-03-24 20:43:41 +00:00
static void add_subtitles ( char * filename , float fps , int silent )
2010-03-05 23:13:08 +00:00
{
sub_data * subd ;
# ifdef CONFIG_ASS
2010-03-10 01:18:42 +00:00
ASS_Track * asst = 0 ;
2010-03-05 23:13:08 +00:00
# endif
if ( ! filename ) return ;
subd = sub_read_file ( filename , fps ) ;
# ifdef CONFIG_ASS
2010-03-10 01:18:42 +00:00
if ( opts . ass_enabled )
2010-03-05 23:13:08 +00:00
# ifdef CONFIG_ICONV
asst = ass_read_file ( ass_library , filename , sub_cp ) ;
# else
asst = ass_read_file ( ass_library , filename , 0 ) ;
# endif
2010-03-10 01:18:42 +00:00
if ( opts . ass_enabled & & subd & & ! asst )
2010-03-05 23:13:08 +00:00
asst = ass_read_subdata ( ass_library , subd , fps ) ;
if ( ! asst & & ! subd & & ! silent )
# else
if ( ! subd & & ! silent )
# endif
2010-03-10 01:18:42 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_ERR , " Cannot load subtitles: %s \n " ,
filename_recode ( filename ) ) ;
2010-03-05 23:13:08 +00:00
# ifdef CONFIG_ASS
if ( ! asst & & ! subd ) return ;
ass_track = asst ;
# else
if ( ! subd ) return ;
# endif
mp_msg ( MSGT_IDENTIFY , MSGL_INFO , " ID_FILE_SUB_FILENAME=%s \n " ,
filename_recode ( filename ) ) ;
subdata = subd ;
}
2010-03-16 12:24:18 +00:00
/* This function returns the absolute time for which MEncoder will switch files
* or move in the file so audio can be cut correctly . - 1 if there is no limit . */
2010-03-16 12:14:57 +00:00
static float stop_time ( demuxer_t * demuxer , muxer_stream_t * mux_v )
{
float timeleft = - 1 ;
if ( play_n_frames > = 0 ) timeleft = mux_v - > timer + play_n_frames * ( double ) ( mux_v - > h . dwScale ) / mux_v - > h . dwRate ;
if ( end_at . type = = END_AT_TIME & & ( timeleft > end_at . pos | | timeleft = = - 1 ) ) timeleft = end_at . pos ;
if ( next_edl_record & & demuxer & & demuxer - > video ) { // everything is OK to be checked
float tmp = mux_v - > timer + next_edl_record - > start_sec - demuxer - > video - > pts ;
if ( timeleft = = - 1 | | timeleft > tmp ) {
// There's less time in EDL than what we already know
if ( next_edl_record - > action = = EDL_SKIP & & edl_seeking ) {
timeleft = tmp ;
} else if ( next_edl_record - > action = = EDL_MUTE ) {
//timeleft = next_edl_record->start_sec - demuxer->video->pts;
// For the moment (and probably forever) EDL mute doesn't work in MEncoder
}
}
}
return timeleft ;
}
2010-03-16 12:24:18 +00:00
/// Returns a_pts
2010-03-16 12:14:57 +00:00
static float calc_a_pts ( demux_stream_t * d_audio )
{
sh_audio_t * sh_audio = d_audio ? d_audio - > sh : NULL ;
float a_pts = 0. ;
if ( sh_audio )
a_pts = d_audio - > pts + ( ds_tell_pts ( d_audio ) - sh_audio - > a_in_buffer_len ) / ( float ) sh_audio - > i_bps ;
return a_pts ;
}
2010-03-16 12:24:18 +00:00
/** \brief Seeks audio forward to pts by dumping audio packets
* \ return The current audio pts . */
2010-03-16 12:14:57 +00:00
static float forward_audio ( float pts , demux_stream_t * d_audio , muxer_stream_t * mux_a )
{
sh_audio_t * sh_audio = d_audio ? d_audio - > sh : NULL ;
int samplesize , avg ;
float a_pts = calc_a_pts ( d_audio ) ;
if ( ! sh_audio ) return a_pts ;
if ( sh_audio - > audio . dwScale ) samplesize = sh_audio - > audio . dwSampleSize ;
else samplesize = ( sh_audio - > wf ? sh_audio - > wf - > nBlockAlign : 1 ) ;
avg = ( sh_audio - > wf ? sh_audio - > wf - > nAvgBytesPerSec : sh_audio - > i_bps ) ;
// after a demux_seek, a_pts will be zero until you read some audio.
// carefully checking if a_pts is truely correct by reading tiniest amount of data possible.
if ( pts > a_pts & & a_pts = = 0.0 & & samplesize ) {
if ( demux_read_data ( sh_audio - > ds , mux_a - > buffer , samplesize ) < = 0 ) return a_pts ; // EOF
a_pts = calc_a_pts ( d_audio ) ;
}
while ( pts > a_pts ) {
int len ;
if ( samplesize ) {
len = avg * ( pts - a_pts > 0.5 ? 0.5 : pts - a_pts ) ;
len / = samplesize ; if ( len < 1 ) len = 1 ;
len * = samplesize ;
len = demux_read_data ( sh_audio - > ds , mux_a - > buffer , len ) ;
} else {
unsigned char * crap ;
len = ds_get_packet ( sh_audio - > ds , & crap ) ;
}
if ( len < = 0 ) break ; // EOF of audio.
a_pts = calc_a_pts ( d_audio ) ;
}
return a_pts ;
}
2010-03-16 12:24:18 +00:00
/** \brief Seeks slowly by dumping frames.
* \ return 1 for success , 2 for EOF . */
2010-03-16 12:14:57 +00:00
static int slowseek ( float end_pts , demux_stream_t * d_video ,
demux_stream_t * d_audio , muxer_stream_t * mux_a ,
s_frame_data * frame_data , int framecopy , int print_info )
{
sh_video_t * sh_video = d_video - > sh ;
vf_instance_t * vfilter = sh_video ? sh_video - > vfilter : NULL ;
int done = 0 ;
while ( ! interrupted ) {
float a_pts = 0. ;
if ( ! frame_data - > already_read ) { // when called after fixdelay, a frame is already read
frame_data - > in_size = video_read_frame ( sh_video , & frame_data - > frame_time , & frame_data - > start , force_fps ) ;
if ( frame_data - > in_size < 0 ) return 2 ;
sh_video - > timer + = frame_data - > frame_time ;
}
frame_data - > already_read = 0 ;
a_pts = forward_audio ( sh_video - > pts - frame_data - > frame_time + audio_delay , d_audio , mux_a ) ;
if ( done ) {
// wait for keyframe in case of -ovc copy
if ( ! framecopy | | ( sh_video - > ds - > flags & 1 ) ) {
frame_data - > already_read = 1 ;
return 1 ;
}
}
if ( sh_video - > pts > = end_pts ) done = 1 ;
if ( vfilter ) {
2010-04-26 14:00:52 +00:00
sh_video - > vfilter - > control ( sh_video - > vfilter , VFCTRL_SET_OSD_OBJ ,
osd ) ;
2010-03-16 12:14:57 +00:00
int softskip = ( vfilter - > control ( vfilter , VFCTRL_SKIP_NEXT_FRAME , 0 ) = = CONTROL_TRUE ) ;
void * decoded_frame = decode_video ( sh_video , frame_data - > start , frame_data - > in_size , ! softskip , MP_NOPTS_VALUE ) ;
if ( decoded_frame )
2010-04-26 14:00:52 +00:00
if ( filter_video ( sh_video , decoded_frame , MP_NOPTS_VALUE ) ) {
struct vf_instance * vf = sh_video - > vfilter ;
vf - > control ( vf , VFCTRL_DRAW_EOSD , NULL ) ;
vf - > control ( vf , VFCTRL_DRAW_OSD , osd ) ;
}
2010-03-16 12:14:57 +00:00
}
2010-04-26 14:00:52 +00:00
if ( print_info ) mp_tmsg ( MSGT_MENCODER , MSGL_STATUS ,
" EDL SKIP: Start: %.2f End: %.2f Current: V: %.2f A: %.2f \r " ,
2010-03-16 12:14:57 +00:00
next_edl_record - > start_sec , next_edl_record - > stop_sec ,
sh_video - > pts , a_pts ) ;
}
if ( interrupted ) return 2 ;
return 1 ;
}
2010-03-16 12:24:18 +00:00
/// Deletes audio or video as told by -delay to sync
2010-03-16 12:14:57 +00:00
static void fixdelay ( demux_stream_t * d_video , demux_stream_t * d_audio ,
muxer_stream_t * mux_a , s_frame_data * frame_data ,
int framecopy )
{
// TODO: Find a way to encode silence instead of deleting video
sh_video_t * sh_video = d_video - > sh ;
float a_pts ;
// demux_seek has a weirdness that sh_video->pts is meaningless,
// until a single frame is read... Same for audio actually too.
// Reading one frame, and keeping it.
frame_data - > in_size = video_read_frame ( sh_video , & frame_data - > frame_time , & frame_data - > start , force_fps ) ;
if ( frame_data - > in_size < 0 ) return ;
sh_video - > timer + = frame_data - > frame_time ;
frame_data - > already_read = 1 ;
a_pts = forward_audio ( sh_video - > pts - frame_data - > frame_time + audio_delay , d_audio , mux_a ) ;
if ( audio_delay > 0 ) return ;
else if ( sh_video - > pts - frame_data - > frame_time + audio_delay > = a_pts ) return ;
slowseek ( a_pts - audio_delay , d_video , d_audio , mux_a , frame_data , framecopy , 0 ) ;
}
2010-03-16 12:24:18 +00:00
/** \brief Seeks for EDL
* \ return 1 for success , 0 for failure , 2 for EOF . */
2010-03-16 12:14:57 +00:00
static int edl_seek ( edl_record_ptr next_edl_record , demuxer_t * demuxer ,
demux_stream_t * d_audio , muxer_stream_t * mux_a ,
s_frame_data * frame_data , int framecopy )
{
sh_video_t * sh_video = demuxer - > video ? demuxer - > video - > sh : NULL ;
if ( ! sh_video ) return 0 ;
if ( sh_video - > pts > = next_edl_record - > stop_sec ) return 1 ; // nothing to do...
if ( ! edl_seek_type ) {
if ( demux_seek ( demuxer , next_edl_record - > stop_sec - sh_video - > pts , audio_delay , 0 ) ) {
sh_video - > pts = demuxer - > video - > pts ;
//if (vo_vobsub) vobsub_seek(vo_vobsub,sh_video->pts);
2010-04-26 14:00:52 +00:00
resync_video_stream ( sh_video ) ;
2010-03-16 12:14:57 +00:00
//if(vo_spudec) spudec_reset(vo_spudec);
if ( audio_delay ! = 0.0 ) fixdelay ( demuxer - > video , d_audio , mux_a , frame_data , framecopy ) ;
return 1 ;
}
// non-seekable stream.
return 0 ;
}
// slow seek, read every frame.
return slowseek ( next_edl_record - > stop_sec , demuxer - > video , d_audio , mux_a , frame_data , framecopy , 1 ) ;
}
2002-08-31 15:04:18 +00:00
int main ( int argc , char * argv [ ] ) {
2001-10-29 01:11:18 +00:00
stream_t * stream = NULL ;
2006-12-18 21:03:59 +00:00
stream_t * ostream = NULL ;
2001-10-29 01:11:18 +00:00
demuxer_t * demuxer = NULL ;
2002-01-26 22:30:02 +00:00
stream_t * stream2 = NULL ;
demuxer_t * demuxer2 = NULL ;
2001-10-29 01:11:18 +00: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 ;
2004-04-17 16:46:41 +00:00
int i = DEMUXER_TYPE_UNKNOWN ;
2002-07-08 21:44:51 +00:00
void * vobsub_writer = NULL ;
2005-07-17 19:25:58 +00:00
s_frame_data frame_data = { . start = NULL , . in_size = 0 , . frame_time = 0. , . already_read = 0 } ;
2001-10-29 01:11:18 +00:00
2002-04-12 10:40:38 +00: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-10 23:19:20 +00:00
uint32_t badframes = 0 ;
2002-04-12 10:40:38 +00:00
2002-12-27 22:43:20 +00:00
muxer_stream_t * mux_a = NULL ;
muxer_stream_t * mux_v = NULL ;
2002-04-12 10:40:38 +00:00
off_t muxer_f_size = 0 ;
2001-10-29 01:11:18 +00:00
2001-11-01 21:47:28 +00:00
double v_pts_corr = 0 ;
double v_timer_corr = 0 ;
2001-11-01 02:31:23 +00:00
2002-11-12 01:56:42 +00:00
m_entry_t * filelist = NULL ;
2001-11-02 01:25:13 +00:00
char * filename = NULL ;
2001-12-06 23:59:46 +00:00
int decoded_frameno = 0 ;
2002-01-26 22:30:02 +00:00
int next_frameno = - 1 ;
2005-02-25 02:32:29 +00:00
int curfile = 0 ;
2005-12-07 09:56:44 +00:00
int new_srate = 0 ;
2001-12-06 23:59:46 +00:00
2005-12-07 09:56:44 +00:00
unsigned int timer_start = 0 ;
2005-05-22 15:34:23 +00:00
ao_data_t ao_data = { 0 , 0 , 0 , 0 , OUTBURST , - 1 , 0 } ;
2002-01-27 18:29:33 +00:00
2005-04-22 06:59:59 +00:00
audio_encoding_params_t aparams ;
audio_encoder_t * aencoder = NULL ;
2002-03-20 15:38:13 +00:00
mp_msg_init ( ) ;
2009-10-31 21:03:48 +00:00
set_av_log_callback ( ) ;
2007-04-25 13:47:06 +00:00
2008-04-13 19:18:51 +00:00
// Create the config context and register the options
2008-04-16 04:11:12 +00:00
set_default_mencoder_options ( & opts ) ;
2008-04-26 07:44:59 +00:00
mconfig = m_config_new ( & opts , cfg_include ) ;
2008-04-13 19:18:51 +00:00
m_config_register_options ( mconfig , mencoder_opts ) ;
2010-06-14 17:17:04 +00:00
m_config_register_options ( mconfig , common_opts ) ;
2008-04-13 19:18:51 +00:00
// Preparse the command line
m_config_preparse_command_line ( mconfig , argc , argv ) ;
2007-04-25 13:47:06 +00:00
2009-01-25 20:35:58 +00:00
print_version ( " MEncoder " ) ;
2005-10-16 19:14:09 +00:00
2008-10-13 16:23:55 +00:00
# if (defined(__MINGW32__) || defined(__CYGWIN__)) && defined(CONFIG_WIN32DLL)
2005-10-16 19:14:09 +00:00
set_path_env ( ) ;
2008-10-13 16:23:55 +00:00
# endif
2009-07-06 23:26:13 +00:00
2003-12-02 23:40:05 +00:00
InitTimer ( ) ;
2002-04-28 17:48:45 +00:00
// check codec.conf
2004-01-08 18:02:31 +00:00
if ( ! codecs_file | | ! parse_codec_cfg ( codecs_file ) ) {
if ( ! parse_codec_cfg ( get_path ( " codecs.conf " ) ) ) {
if ( ! parse_codec_cfg ( MPLAYER_CONFDIR " /codecs.conf " ) ) {
if ( ! parse_codec_cfg ( NULL ) ) {
mencoder_exit ( 1 , NULL ) ;
}
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_V , " Using built-in default codecs.conf. \n " ) ;
2002-12-15 23:45:19 +00:00
}
2002-04-28 17:48:45 +00:00
}
}
2002-11-12 01:56:42 +00:00
parse_cfgfiles ( mconfig ) ;
filelist = m_config_parse_me_command_line ( mconfig , argc , argv ) ;
2009-07-06 22:15:02 +00:00
if ( ! filelist ) mencoder_exit ( 1 , _ ( " error parsing command line " ) ) ;
2001-11-02 01:25:13 +00:00
2005-12-15 17:57:18 +00:00
{
char * extension ;
2009-07-06 23:26:13 +00:00
2009-07-06 22:15:02 +00:00
if ( ! out_filename ) mencoder_exit ( 1 , _ ( " No output file specified, please see the -o option. " ) ) ;
2005-12-15 17:57:18 +00:00
extension = strrchr ( out_filename , ' . ' ) ;
if ( extension ! = NULL & & strlen ( extension ) > 3 & & strlen ( extension ) < 6 )
{
extension + + ;
2009-07-06 23:26:13 +00:00
2005-12-15 17:57:18 +00:00
switch ( out_file_format )
{
case MUXER_TYPE_AVI :
if ( strcasecmp ( extension , " avi " ) )
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " \n WARNING: OUTPUT FILE FORMAT IS _AVI_. See -of help. \n " ) ;
2005-12-15 17:57:18 +00:00
break ;
case MUXER_TYPE_MPEG :
if ( strcasecmp ( extension , " mpg " ) & &
strcasecmp ( extension , " mpeg " ) & &
2009-07-06 23:26:13 +00:00
strcasecmp ( extension , " vob " ) )
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " \n WARNING: OUTPUT FILE FORMAT IS _MPEG_. See -of help. \n " ) ;
2005-12-15 17:57:18 +00:00
break ;
}
}
2009-07-06 23:26:13 +00:00
}
2006-11-28 18:29:24 +00:00
/* Display what configure line was used */
mp_msg ( MSGT_MENCODER , MSGL_V , " Configuration: " CONFIGURATION " \n " ) ;
2005-12-15 17:57:18 +00:00
2009-07-06 22:15:02 +00:00
# define FormatNotRecognized _("============ Sorry, this file format is not recognized / supported =============\n"\
" === If this file is an AVI, ASF or MPEG stream, please contact the author! === \n " )
2005-12-15 17:57:18 +00:00
2005-09-19 19:23:38 +00:00
if ( frameno_filename ) {
stream2 = open_stream ( frameno_filename , 0 , & i ) ;
if ( stream2 ) {
2008-04-16 01:23:38 +00:00
demuxer2 = demux_open ( & opts , stream2 , DEMUXER_TYPE_AVI , - 1 , - 1 , - 2 , NULL ) ;
2009-07-06 22:15:02 +00:00
if ( demuxer2 ) mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Using pass3 control file: %s \n " , frameno_filename ) ;
else mp_tmsg ( MSGT_DEMUXER , MSGL_ERR , FormatNotRecognized ) ;
2005-09-19 19:23:38 +00:00
}
}
2009-02-10 15:34:44 +00:00
# ifdef CONFIG_PRIORITY
set_priority ( ) ;
2009-07-06 23:26:13 +00:00
# endif
2005-04-02 18:29:16 +00:00
2010-03-15 08:30:06 +00:00
if ( codec_path )
2010-03-21 08:34:09 +00:00
set_codec_path ( codec_path ) ;
2010-03-15 08:30:06 +00:00
2002-06-02 15:25:52 +00:00
// check font
2008-08-07 10:36:07 +00:00
# ifdef CONFIG_FREETYPE
2002-08-28 20:52:02 +00:00
init_freetype ( ) ;
2003-12-08 12:14:32 +00:00
# endif
2008-08-07 10:36:07 +00:00
# ifdef CONFIG_FONTCONFIG
2007-12-12 10:00:34 +00:00
if ( font_fontconfig < = 0 )
2003-12-08 12:14:32 +00:00
{
# endif
2008-08-07 08:58:07 +00:00
# ifdef CONFIG_BITMAP_FONT
2002-06-02 15:25:52 +00:00
if ( font_name ) {
vo_font = read_font_desc ( font_name , font_factor , verbose > 1 ) ;
2009-07-06 22:15:02 +00:00
if ( ! vo_font ) mp_tmsg ( MSGT_CPLAYER , MSGL_ERR , " Cannot load bitmap font: %s \n " , font_name ) ;
2002-06-02 15:25:52 +00:00
} else {
// try default:
vo_font = read_font_desc ( get_path ( " font/font.desc " ) , font_factor , verbose > 1 ) ;
if ( ! vo_font )
2008-05-03 15:44:55 +00:00
vo_font = read_font_desc ( MPLAYER_DATADIR " /font/font.desc " , font_factor , verbose > 1 ) ;
2002-06-02 15:25:52 +00:00
}
2006-08-24 16:25:56 +00:00
# endif
2008-08-07 10:36:07 +00:00
# ifdef CONFIG_FONTCONFIG
2003-12-08 12:14:32 +00:00
}
2002-06-02 15:25:52 +00:00
# endif
2008-06-23 22:53:58 +00:00
osd = osd_create ( ) ;
2002-06-02 15:25:52 +00:00
2005-10-20 05:54:51 +00:00
/* HACK, for some weird reason, push() has to be called twice,
otherwise options are not saved correctly */
2005-10-13 20:27:48 +00:00
m_config_push ( mconfig ) ;
2005-02-25 02:32:29 +00:00
play_next_file :
m_config_push ( mconfig ) ;
m_entry_set_options ( mconfig , & filelist [ curfile ] ) ;
filename = filelist [ curfile ] . name ;
2009-07-06 23:26:13 +00:00
2010-03-05 23:13:08 +00:00
# ifdef CONFIG_ASS
ass_library = ass_init ( ) ;
# endif
2005-02-12 15:11:02 +00:00
if ( ! filename ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_FATAL , " \n Filename missing. \n \n " ) ;
2005-02-12 15:11:02 +00:00
mencoder_exit ( 1 , NULL ) ;
}
2003-03-30 17:07:31 +00:00
stream = open_stream ( filename , 0 , & file_format ) ;
2001-10-29 01:11:18 +00:00
if ( ! stream ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_FATAL , " Cannot open file/device. \n " ) ;
2002-02-17 13:50:26 +00:00
mencoder_exit ( 1 , NULL ) ;
2001-10-29 01:11:18 +00:00
}
2010-03-07 16:33:01 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_INFO , " success: format: %d data: 0x%X - 0x%x \n " , file_format , ( int ) ( stream - > start_pos ) , ( int ) ( stream - > end_pos ) ) ;
2001-10-29 01:11:18 +00:00
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_DVDREAD
2002-03-31 22:01:54 +00:00
if ( stream - > type = = STREAMTYPE_DVD ) {
2010-05-21 20:57:29 +00:00
if ( opts . audio_lang & & opts . audio_id = = - 1 ) opts . audio_id = dvd_aid_from_lang ( stream , opts . audio_lang ) ;
if ( opts . sub_lang & & opts . sub_id = = - 1 ) opts . sub_id = dvd_sid_from_lang ( stream , opts . sub_lang ) ;
2002-03-31 22:01:54 +00:00
}
2007-07-15 20:32:19 +00:00
# endif
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_DVDNAV
2007-07-15 20:32:19 +00:00
if ( stream - > type = = STREAMTYPE_DVDNAV ) {
2010-05-21 20:57:29 +00:00
if ( opts . audio_lang & & opts . audio_id = = - 1 ) opts . audio_id = mp_dvdnav_aid_from_lang ( stream , opts . audio_lang ) ;
if ( opts . sub_lang & & opts . sub_id = = - 1 ) opts . sub_id = mp_dvdnav_sid_from_lang ( stream , opts . sub_lang ) ;
2007-07-15 20:32:19 +00:00
}
2002-03-31 22:01:54 +00:00
# endif
2002-04-15 00:36:21 +00:00
stream - > start_pos + = seek_to_byte ;
2001-10-29 01:11:18 +00:00
2002-10-23 22:07:29 +00:00
if ( stream_cache_size > 0 ) stream_enable_cache ( stream , stream_cache_size * 1024 , 0 , 0 ) ;
2002-04-15 00:36:21 +00:00
2008-04-23 04:01:31 +00:00
if ( demuxer2 ) opts . audio_id = - 2 ; /* do NOT read audio packets... */
2002-01-26 16:32:06 +00:00
2008-04-23 04:41:17 +00:00
demuxer = demux_open ( & opts , stream , file_format , opts . audio_id , opts . video_id , opts . sub_id , filename ) ;
2001-10-29 01:11:18 +00:00
if ( ! demuxer ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_DEMUXER , MSGL_FATAL , FormatNotRecognized ) ;
mp_tmsg ( MSGT_DEMUXER , MSGL_FATAL , " Cannot open demuxer. \n " ) ;
2002-02-17 13:50:26 +00:00
mencoder_exit ( 1 , NULL ) ;
2001-10-29 01:11:18 +00:00
}
2008-02-29 17:25:50 +00:00
2009-11-13 14:36:38 +00:00
if ( ts_prog ) {
demux_program_t prog = { . progid = ts_prog } ;
if ( demux_control ( demuxer , DEMUXER_CTRL_IDENTIFY_PROGRAM , & prog ) ! = DEMUXER_CTRL_NOTIMPL ) {
2009-11-16 04:54:22 +00:00
opts . audio_id = prog . aid ; // switching is handled by select_audio below
opts . video_id = prog . vid ;
demuxer_switch_video ( demuxer , opts . video_id ) ;
2009-11-13 14:36:38 +00:00
}
}
2010-05-21 20:57:29 +00:00
select_audio ( demuxer , opts . audio_id , opts . audio_lang ) ;
2009-07-06 23:26:13 +00:00
2010-05-21 20:57:29 +00:00
if ( opts . sub_id < - 1 & & opts . sub_lang )
opts . sub_id = demuxer_sub_track_by_lang ( demuxer , opts . sub_lang ) ;
2008-02-29 17:25:44 +00:00
2009-10-06 01:28:59 +00:00
if ( opts . sub_id < - 1 )
2008-04-23 04:41:17 +00:00
opts . sub_id = demuxer_default_sub_track ( demuxer ) ;
2008-03-30 16:55:46 +00:00
2008-02-29 17:25:44 +00:00
for ( i = 0 ; i < MAX_S_STREAMS ; i + + ) {
sh_sub_t * sh = demuxer - > s_streams [ i ] ;
2008-04-23 04:41:17 +00:00
if ( sh & & sh - > sid = = opts . sub_id ) {
2008-02-29 17:25:44 +00:00
demuxer - > sub - > id = i ;
demuxer - > sub - > sh = sh ;
break ;
}
}
2010-04-24 17:09:31 +00:00
if ( opts . chapterrange [ 0 ] > 1 ) {
2009-04-01 16:55:26 +00:00
double pts ;
2010-04-24 17:09:31 +00:00
if ( demuxer_seek_chapter ( demuxer , opts . chapterrange [ 0 ] - 1 , & pts , NULL ) > = 0 & & pts > - 1.0 )
2008-02-28 19:41:40 +00:00
seek_to_sec = pts ;
2008-02-11 22:03:34 +00:00
}
2001-10-29 01:11:18 +00:00
2002-01-26 22:30:02 +00:00
d_audio = demuxer2 ? demuxer2 - > audio : demuxer - > audio ;
2001-10-29 01:11:18 +00:00
d_video = demuxer - > video ;
d_dvdsub = demuxer - > sub ;
sh_audio = d_audio - > sh ;
sh_video = d_video - > sh ;
2003-11-23 19:30:05 +00:00
if ( ! sh_video )
{
2009-07-06 23:26:13 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_FATAL , " Video stream is mandatory! \n " ) ;
2003-11-23 19:30:05 +00:00
mencoder_exit ( 1 , NULL ) ;
}
2001-10-29 01:11:18 +00:00
if ( ! video_read_properties ( sh_video ) ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_FATAL , " Video: Cannot read properties. \n " ) ;
2002-02-17 13:50:26 +00:00
mencoder_exit ( 1 , NULL ) ;
2001-10-29 01:11:18 +00:00
}
2010-03-07 16:33:01 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " [V] filefmt:%d fourcc:0x%X size:%dx%d fps:%5.3f ftime:=%6.4f \n " ,
2001-10-29 01:11:18 +00:00
demuxer - > file_format , sh_video - > format , sh_video - > disp_w , sh_video - > disp_h ,
sh_video - > fps , sh_video - > frametime
) ;
2002-03-18 01:51:47 +00:00
2002-12-04 23:37:17 +00:00
if ( force_fps ) {
sh_video - > fps = force_fps ;
sh_video - > frametime = 1.0f / sh_video - > fps ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Input fps will be interpreted as %5.3f instead. \n " , sh_video - > fps ) ;
2002-12-04 23:37:17 +00:00
}
2002-08-05 13:41:32 +00:00
if ( sh_audio & & out_audio_codec < 0 ) {
2008-04-23 04:01:31 +00:00
if ( opts . audio_id = = - 2 )
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_ERR , " This demuxer doesn't support -nosound yet. \n " ) ;
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " \n No audio encoder (-oac) selected. Select one (see -oac help) or use -nosound. \n " ) ;
2002-08-05 13:41:32 +00:00
mencoder_exit ( 1 , NULL ) ;
}
if ( sh_video & & out_video_codec < 0 ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " \n No video encoder (-ovc) selected. Select one (see -ovc help). \n " ) ;
2002-08-05 13:41:32 +00:00
mencoder_exit ( 1 , NULL ) ;
}
2008-04-21 03:55:23 +00:00
if ( sh_audio & & ( out_audio_codec | | seek_to_sec | | ! sh_audio - > wf | | opts . playback_speed ! = 1.0 ) ) {
2001-10-30 23:17:35 +00:00
// Go through the codec.conf and find the best codec...
2002-09-25 23:45:34 +00:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
2002-09-28 02:23:20 +00:00
if ( ! init_best_audio_codec ( sh_audio , audio_codec_list , audio_fm_list ) ) {
2002-09-25 23:45:34 +00:00
sh_audio = d_audio - > sh = NULL ; // failed to init :(
2001-10-30 23:17:35 +00:00
}
2002-09-25 23:45:34 +00:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
2001-10-30 23:17:35 +00:00
}
2005-03-15 04:10:57 +00:00
if ( sh_audio ) {
new_srate = sh_audio - > samplerate ;
2008-04-21 03:55:23 +00:00
if ( opts . playback_speed ! = 1.0 ) {
new_srate * = opts . playback_speed ;
2005-03-15 04:10:57 +00:00
// limits are taken from libaf/af_resample.c
if ( new_srate < 8000 ) new_srate = 8000 ;
if ( new_srate > 192000 ) new_srate = 192000 ;
2008-04-21 03:55:23 +00:00
opts . playback_speed = ( float ) new_srate / ( float ) sh_audio - > samplerate ;
2005-03-15 04:10:57 +00:00
}
}
2001-10-29 01:11:18 +00:00
// set up video encoder:
2005-02-25 02:32:29 +00:00
if ( ! curfile ) { // curfile is non zero when a second file is opened
2002-07-08 21:44:51 +00:00
if ( vobsub_out ) {
unsigned int palette [ 16 ] , width , height ;
unsigned char tmp [ 3 ] = { 0 , 0 , 0 } ;
2008-04-23 04:41:17 +00:00
if ( spudec_ifo & & vobsub_parse_ifo ( NULL , spudec_ifo , palette , & width , & height , 1 , opts . sub_id , tmp ) > = 0 )
2002-07-08 21:44:51 +00:00
vobsub_writer = vobsub_out_open ( vobsub_out , palette , sh_video - > disp_w , sh_video - > disp_h ,
2002-09-01 14:30:55 +00:00
vobsub_out_id ? vobsub_out_id : ( char * ) tmp , vobsub_out_index ) ;
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_DVDREAD
2002-07-08 21:44:51 +00:00
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 )
2008-04-23 04:41:17 +00:00
if ( dvd - > subtitles [ i ] . id = = opts . sub_id ) {
2002-07-08 21:44:51 +00:00
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 03:17:57 +00:00
if ( spudec_ifo ) {
unsigned int palette [ 16 ] , width , height ;
2002-07-08 21:44:51 +00:00
if ( vobsub_parse_ifo ( NULL , spudec_ifo , palette , & width , & height , 1 , - 1 , NULL ) > = 0 )
2008-10-27 22:51:22 +00:00
vo_spudec = spudec_new_scaled ( palette , sh_video - > disp_w , sh_video - > disp_h , NULL , 0 ) ;
2002-03-29 03:17:57 +00:00
}
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_DVDREAD
2002-03-29 15:12:41 +00:00
if ( vo_spudec = = NULL ) {
2002-02-06 22:55:47 +00:00
vo_spudec = spudec_new_scaled ( stream - > type = = STREAMTYPE_DVD ? ( ( dvd_priv_t * ) ( stream - > priv ) ) - > cur_pgc - > palette : NULL ,
2008-10-27 22:51:22 +00:00
sh_video - > disp_w , sh_video - > disp_h , NULL , 0 ) ;
2002-03-29 03:17:57 +00:00
}
2002-01-11 16:06:45 +00:00
# endif
2009-03-30 17:05:39 +00:00
if ( vo_spudec )
spudec_set_forced_subs_only ( vo_spudec , forced_subs_only ) ;
2002-07-08 21:44:51 +00:00
}
2002-01-11 16:06:45 +00:00
2006-12-18 21:03:59 +00:00
ostream = open_output_stream ( out_filename , 0 ) ;
if ( ! ostream ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " Cannot open output file '%s'. \n " , out_filename ) ;
2002-02-17 13:50:26 +00:00
mencoder_exit ( 1 , NULL ) ;
2001-11-13 23:43:33 +00:00
}
2006-12-18 21:03:59 +00:00
muxer = muxer_new_muxer ( out_file_format , ostream ) ;
2005-12-02 19:41:25 +00:00
if ( ! muxer ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " Cannot initialize muxer. " ) ;
2005-12-02 19:41:25 +00:00
mencoder_exit ( 1 , NULL ) ;
}
2006-03-19 17:28:13 +00:00
#if 0
//disabled: it horrybly distorts filtered sound
2006-02-11 21:29:03 +00:00
if ( out_file_format = = MUXER_TYPE_MPEG ) audio_preload = 0 ;
2006-03-19 17:28:13 +00:00
# endif
2001-10-30 23:17:35 +00:00
2006-02-19 09:34:37 +00:00
muxer - > audio_delay_fix = audio_delay_fix ;
2001-10-30 23:17:35 +00:00
// ============= VIDEO ===============
2002-12-27 22:43:20 +00:00
mux_v = muxer_new_stream ( muxer , MUXER_TYPE_VIDEO ) ;
2001-10-29 01:11:18 +00:00
2002-02-07 20:22:03 +00:00
mux_v - > buffer_size = 0x200000 ; // 2MB
2001-10-29 01:11:18 +00:00
mux_v - > buffer = malloc ( mux_v - > buffer_size ) ;
mux_v - > source = sh_video ;
mux_v - > h . dwSampleSize = 0 ; // VBR
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_LIBAVCODEC
2004-02-10 14:12:26 +00:00
{
2008-04-21 03:55:23 +00:00
double fps = force_ofps ? force_ofps : sh_video - > fps * opts . playback_speed ;
2008-02-14 17:38:52 +00:00
AVRational q = av_d2q ( fps , fps * 1001 + 2 ) ;
2004-02-10 14:12:26 +00:00
mux_v - > h . dwScale = q . den ;
mux_v - > h . dwRate = q . num ;
}
# else
2001-10-29 01:11:18 +00:00
mux_v - > h . dwScale = 10000 ;
2008-04-21 03:55:23 +00:00
mux_v - > h . dwRate = mux_v - > h . dwScale * ( force_ofps ? force_ofps : sh_video - > fps * opts . playback_speed ) ;
2004-02-10 14:12:26 +00:00
# endif
2001-10-29 01:11:18 +00:00
2001-11-03 23:01:17 +00:00
mux_v - > codec = out_video_codec ;
2001-10-30 21:55:28 +00:00
2002-04-11 02:52:03 +00:00
mux_v - > bih = NULL ;
2005-02-25 02:32:29 +00:00
}
2002-04-11 02:52:03 +00:00
sh_video - > codec = NULL ;
sh_video - > vfilter = NULL ; // fixme!
2001-10-29 01:11:18 +00:00
switch ( mux_v - > codec ) {
2001-12-08 12:21:23 +00:00
case VCODEC_COPY :
2005-02-25 02:32:29 +00:00
if ( ! curfile ) {
if ( sh_video - > bih ) {
mux_v - > bih = malloc ( sh_video - > bih - > biSize ) ;
2007-06-05 15:09:49 +00:00
memcpy ( mux_v - > bih , sh_video - > bih , sh_video - > bih - > biSize ) ;
2005-02-25 02:32:29 +00:00
}
2001-12-08 12:21:23 +00:00
else
{
2004-06-08 16:43:24 +00:00
mux_v - > bih = calloc ( 1 , sizeof ( BITMAPINFOHEADER ) ) ;
2001-12-08 12:21:23 +00:00
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 ) ;
}
2005-02-25 02:32:29 +00:00
}
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " videocodec: framecopy (%dx%d %dbpp fourcc=%x) \n " ,
2001-12-08 12:21:23 +00:00
mux_v - > bih - > biWidth , mux_v - > bih - > biHeight ,
mux_v - > bih - > biBitCount , mux_v - > bih - > biCompression ) ;
2005-02-25 02:32:29 +00:00
if ( curfile ) {
if ( sh_video - > bih ) {
if ( ( mux_v - > bih - > biSize ! = sh_video - > bih - > biSize ) | |
memcmp ( mux_v - > bih , sh_video - > bih , sh_video - > bih - > biSize ) )
{
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " videocodec: framecopy (%dx%d %dbpp fourcc=%x) \n " ,
2005-02-25 02:32:29 +00:00
sh_video - > bih - > biWidth , sh_video - > bih - > biHeight ,
sh_video - > bih - > biBitCount , sh_video - > bih - > biCompression ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " \n All video files must have identical fps, resolution, and codec for -ovc copy. \n " ) ;
2005-02-25 02:32:29 +00:00
mencoder_exit ( 1 , NULL ) ;
}
}
else {
if ( ( mux_v - > bih - > biWidth ! = sh_video - > disp_w ) | |
( mux_v - > bih - > biHeight ! = sh_video - > disp_h ) | |
( mux_v - > bih - > biCompression ! = sh_video - > format ) ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " videocodec: framecopy (%dx%d %dbpp fourcc=%x) \n " ,
2005-02-25 02:32:29 +00:00
sh_video - > disp_w , sh_video - > disp_w , 24 , sh_video - > format ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " \n All video files must have identical fps, resolution, and codec for -ovc copy. \n " ) ;
2005-02-25 02:32:29 +00:00
mencoder_exit ( 1 , NULL ) ;
}
}
}
2001-10-29 01:11:18 +00:00
break ;
2001-12-06 23:59:46 +00:00
case VCODEC_FRAMENO :
2005-02-25 02:32:29 +00:00
if ( ! curfile ) {
2004-06-08 16:43:24 +00:00
mux_v - > bih = calloc ( 1 , sizeof ( BITMAPINFOHEADER ) ) ;
2001-12-06 23:59:46 +00:00
mux_v - > bih - > biSize = sizeof ( BITMAPINFOHEADER ) ;
2002-09-29 19:26:40 +00:00
mux_v - > bih - > biWidth = sh_video - > disp_w ;
mux_v - > bih - > biHeight = sh_video - > disp_h ;
2001-12-06 23:59:46 +00: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 ) ;
2005-02-25 02:32:29 +00:00
}
2001-12-06 23:59:46 +00:00
break ;
2005-03-01 20:21:58 +00:00
default : {
static vf_instance_t * ve = NULL ;
if ( ! ve ) {
2002-04-11 02:52:03 +00:00
switch ( mux_v - > codec ) {
case VCODEC_LIBAVCODEC :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " lavc " , ( char * ) mux_v ) ; break ;
2004-02-17 12:43:07 +00:00
case VCODEC_RAW :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " raw " , ( char * ) mux_v ) ; break ;
2002-04-11 02:52:03 +00:00
case VCODEC_VFW :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " vfw " , ( char * ) mux_v ) ; break ;
2002-04-12 21:50:38 +00:00
case VCODEC_LIBDV :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " libdv " , ( char * ) mux_v ) ; break ;
2002-09-21 12:41:29 +00:00
case VCODEC_XVID :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " xvid " , ( char * ) mux_v ) ; break ;
2002-12-16 01:49:39 +00:00
case VCODEC_QTVIDEO :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " qtvideo " , ( char * ) mux_v ) ; break ;
2009-07-06 23:26:13 +00:00
case VCODEC_NUV :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " nuv " , ( char * ) mux_v ) ; break ;
2004-08-27 20:43:05 +00:00
case VCODEC_X264 :
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_encoder ( & opts , NULL , " x264 " , ( char * ) mux_v ) ; break ;
2002-01-26 20:18:59 +00:00
}
2002-04-11 02:52:03 +00:00
if ( ! mux_v - > bih | | ! sh_video - > vfilter ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " Failed to open the encoder. \n " ) ;
2002-04-11 02:52:03 +00:00
mencoder_exit ( 1 , NULL ) ;
2002-01-26 20:18:59 +00:00
}
2005-03-01 20:21:58 +00:00
ve = sh_video - > vfilter ;
} else sh_video - > vfilter = ve ;
2002-04-17 21:51:18 +00:00
// append 'expand' filter, it fixes stride problems and renders osd:
2010-03-05 23:13:08 +00:00
# ifdef CONFIG_ASS
2010-03-10 01:18:42 +00:00
if ( auto_expand & & ! opts . ass_enabled ) { /* we do not want both */
2010-03-05 23:13:08 +00:00
# else
2003-03-15 18:50:58 +00:00
if ( auto_expand ) {
2010-03-05 23:13:08 +00:00
# endif
2003-03-15 18:50:58 +00:00
char * vf_args [ ] = { " osd " , " 1 " , NULL } ;
2008-04-16 04:06:44 +00:00
sh_video - > vfilter = vf_open_filter ( & opts , sh_video - > vfilter , " expand " , vf_args ) ;
2003-03-15 18:50:58 +00:00
}
2010-03-05 23:13:08 +00:00
# ifdef CONFIG_ASS
2010-03-10 01:18:42 +00:00
if ( opts . ass_enabled ) {
2010-03-05 23:13:08 +00:00
int i ;
int insert = 1 ;
2010-03-10 01:18:42 +00:00
if ( opts . vf_settings )
for ( i = 0 ; opts . vf_settings [ i ] . name ; + + i )
if ( strcmp ( opts . vf_settings [ i ] . name , " ass " ) = = 0 ) {
2010-03-05 23:13:08 +00:00
insert = 0 ;
break ;
}
if ( insert ) {
extern vf_info_t vf_info_ass ;
vf_info_t * libass_vfs [ ] = { & vf_info_ass , NULL } ;
char * vf_arg [ ] = { " auto " , " 1 " , NULL } ;
2010-03-10 01:18:42 +00:00
vf_instance_t * vf_ass = vf_open_plugin ( & opts , libass_vfs , sh_video - > vfilter , " ass " , vf_arg ) ;
2010-03-05 23:13:08 +00:00
if ( vf_ass )
sh_video - > vfilter = ( void * ) vf_ass ;
else
mp_msg ( MSGT_CPLAYER , MSGL_ERR , " ASS: cannot add video filter \n " ) ;
}
if ( ass_library ) {
for ( i = 0 ; i < demuxer - > num_attachments ; + + i ) {
demux_attachment_t * att = demuxer - > attachments + i ;
2010-06-01 20:49:22 +00:00
if ( use_embedded_fonts & & attachment_is_font ( att ) )
2010-03-05 23:13:08 +00:00
ass_add_font ( ass_library , att - > name , att - > data , att - > data_size ) ;
}
}
}
# endif
2008-04-25 10:58:12 +00:00
sh_video - > vfilter = append_filters ( sh_video - > vfilter , opts . vf_settings ) ;
2002-04-11 02:52:03 +00:00
2010-03-05 23:13:08 +00:00
# ifdef CONFIG_ASS
2010-03-10 01:18:42 +00:00
if ( opts . ass_enabled )
2010-03-05 23:13:08 +00:00
( ( vf_instance_t * ) sh_video - > vfilter ) - > control ( sh_video - > vfilter , VFCTRL_INIT_EOSD , ass_library ) ;
# endif
// 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
if ( sub_name & & sub_name [ 0 ] ) {
for ( i = 0 ; sub_name [ i ] ! = NULL ; + + i )
add_subtitles ( sub_name [ i ] , sh_video - > fps , 0 ) ;
} else
if ( sub_auto & & filename ) { // auto load sub file ...
char * * tmp = NULL ;
int i = 0 ;
char * psub = get_path ( " sub/ " ) ;
tmp = sub_filenames ( ( psub ? psub : " " ) , filename ) ;
free ( psub ) ;
while ( tmp [ i ] )
{
add_subtitles ( tmp [ i ] , sh_video - > fps , 0 ) ;
free ( tmp [ i + + ] ) ;
}
free ( tmp ) ;
}
2002-09-25 23:45:34 +00:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
2002-09-26 01:31:18 +00:00
init_best_video_codec ( sh_video , video_codec_list , video_fm_list ) ;
2002-09-25 23:45:34 +00:00
mp_msg ( MSGT_CPLAYER , MSGL_INFO , " ========================================================================== \n " ) ;
2008-02-14 14:23:55 +00:00
if ( ! sh_video - > initialized ) mencoder_exit ( 1 , NULL ) ;
2005-03-01 20:21:58 +00:00
}
2001-12-22 14:32:08 +00:00
}
2005-02-25 02:32:29 +00:00
if ( ! curfile ) {
2001-12-22 14:32:08 +00:00
/* force output fourcc to .. */
2002-01-26 20:18:59 +00:00
if ( ( force_fourcc ! = NULL ) & & ( strlen ( force_fourcc ) > = 4 ) )
2001-12-22 14:32:08 +00:00
{
mux_v - > bih - > biCompression = mmioFOURCC ( force_fourcc [ 0 ] , force_fourcc [ 1 ] ,
force_fourcc [ 2 ] , force_fourcc [ 3 ] ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Forcing output FourCC to %x [%.4s]. \n " ,
2002-01-26 20:18:59 +00:00
mux_v - > bih - > biCompression , ( char * ) & mux_v - > bih - > biCompression ) ;
2001-10-29 01:11:18 +00:00
}
2006-02-20 09:36:10 +00:00
if ( ! ignore_start )
2006-02-19 09:34:37 +00:00
muxer - > audio_delay_fix - = sh_video - > stream_delay ;
2002-11-02 00:45:12 +00:00
//if(demuxer->file_format!=DEMUXER_TYPE_AVI) pts_from_bps=0; // it must be 0 for mpeg/asf!
2002-01-27 02:31:06 +00:00
2001-10-30 23:17:35 +00:00
// ============= AUDIO ===============
if ( sh_audio ) {
2005-07-02 19:00:13 +00:00
if ( force_audiofmttag ! = - 1 ) {
sh_audio - > format = force_audiofmttag ;
if ( sh_audio - > wf ) {
sh_audio - > wf - > wFormatTag = sh_audio - > format ;
}
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Forcing output audio format tag to 0x%x. \n " ,
2005-07-02 19:00:13 +00:00
force_audiofmttag ) ;
}
2002-12-27 22:43:20 +00:00
mux_a = muxer_new_stream ( muxer , MUXER_TYPE_AUDIO ) ;
2001-10-30 23:17:35 +00:00
mux_a - > buffer_size = 0x100000 ; //16384;
mux_a - > buffer = malloc ( mux_a - > buffer_size ) ;
2004-02-18 13:33:16 +00:00
if ( ! mux_a - > buffer )
2009-07-06 22:15:02 +00:00
mencoder_exit ( 1 , _ ( " Memory allocation failed. \n " ) ) ;
2001-10-30 23:17:35 +00:00
mux_a - > source = sh_audio ;
2001-11-03 23:01:17 +00:00
mux_a - > codec = out_audio_codec ;
2001-10-30 23:17:35 +00:00
2005-06-24 10:50:53 +00:00
ao_data . samplerate = force_srate ;
ao_data . channels = 0 ;
ao_data . format = audio_output_format ;
2007-11-01 06:52:28 +00:00
if ( ! init_audio_filters ( sh_audio ,
2005-05-22 15:34:23 +00:00
// input:
new_srate ,
// output:
& ao_data . samplerate , & ao_data . channels , & ao_data . format ) ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_ERR , " Error at audio filter chain pre-init! \n " ) ;
2005-05-22 15:34:23 +00:00
mencoder_exit ( 1 , NULL ) ;
}
aparams . channels = ao_data . channels ;
2005-06-24 10:50:53 +00:00
aparams . sample_rate = ao_data . samplerate ;
2005-04-22 06:59:59 +00:00
aparams . audio_preload = 1000 * audio_preload ;
if ( mux_a - > codec ! = ACODEC_COPY ) {
aencoder = new_audio_encoder ( mux_a , & aparams ) ;
if ( ! aencoder )
mencoder_exit ( 1 , NULL ) ;
2009-07-06 23:26:13 +00:00
if ( ! init_audio_filters ( sh_audio ,
2007-11-01 06:52:28 +00:00
new_srate ,
& aparams . sample_rate , & aparams . channels , & aencoder - > input_format ) ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_FATAL , " Couldn't find matching filter/ao format! \n " ) ;
2005-04-22 06:59:59 +00:00
mencoder_exit ( 1 , NULL ) ;
}
}
2009-07-06 22:15:02 +00:00
# define NoSpeedWithFrameCopy _("WARNING: -speed is not guaranteed to work correctly with -oac copy!\n"\
" Your encode might be broken! \n " )
2001-10-30 23:17:35 +00:00
switch ( mux_a - > codec ) {
2001-12-08 13:30:06 +00:00
case ACODEC_COPY :
2009-07-06 22:15:02 +00:00
if ( opts . playback_speed ! = 1.0 ) mp_tmsg ( MSGT_CPLAYER , MSGL_WARN , NoSpeedWithFrameCopy ) ;
2005-07-02 19:00:13 +00:00
if ( sh_audio - > format > = 0x10000 ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_ERR , " Audio format 0x%x is incompatible with '-oac copy', please try '-oac pcm' instead or use '-fafmttag' to override it. \n " , sh_audio - > format ) ;
2005-07-02 19:00:13 +00:00
mencoder_exit ( 1 , NULL ) ;
}
2002-01-27 01:23:23 +00:00
if ( sh_audio - > wf ) {
2005-02-25 02:32:29 +00:00
mux_a - > wf = malloc ( sizeof ( WAVEFORMATEX ) + sh_audio - > wf - > cbSize ) ;
2007-06-05 15:09:49 +00:00
memcpy ( mux_a - > wf , sh_audio - > wf , sizeof ( WAVEFORMATEX ) + sh_audio - > wf - > cbSize ) ;
2002-01-27 02:31:06 +00:00
if ( ! sh_audio - > i_bps ) sh_audio - > i_bps = mux_a - > wf - > nAvgBytesPerSec ;
2002-01-27 01:23:23 +00:00
} else {
2001-12-08 13:30:06 +00:00
mux_a - > wf = malloc ( sizeof ( WAVEFORMATEX ) ) ;
2002-01-27 02:31:06 +00:00
mux_a - > wf - > nBlockAlign = 1 ; //mux_a->h.dwSampleSize;
2002-10-06 23:24:36 +00:00
mux_a - > wf - > wFormatTag = sh_audio - > format ;
2001-12-08 13:30:06 +00:00
mux_a - > wf - > nChannels = sh_audio - > channels ;
mux_a - > wf - > nSamplesPerSec = sh_audio - > samplerate ;
2002-01-27 01:23:23 +00:00
mux_a - > wf - > nAvgBytesPerSec = sh_audio - > i_bps ; //mux_a->h.dwSampleSize*mux_a->wf->nSamplesPerSec;
2001-12-13 17:50:19 +00:00
mux_a - > wf - > wBitsPerSample = 16 ; // FIXME
2001-12-08 13:30:06 +00:00
mux_a - > wf - > cbSize = 0 ; // FIXME for l3codeca.acm
}
2002-01-27 02:31:06 +00: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 ;
} 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 ;
}
2008-04-21 03:55:23 +00:00
mux_a - > h . dwRate * = opts . playback_speed ;
mux_a - > wf - > nSamplesPerSec * = opts . playback_speed ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " audiocodec: framecopy (format=%x chans=%d rate=%d bits=%d B/s=%d sample-%d) \n " ,
2006-01-12 20:04:36 +00:00
mux_a - > wf - > wFormatTag , mux_a - > wf - > nChannels , mux_a - > wf - > nSamplesPerSec ,
mux_a - > wf - > wBitsPerSample , mux_a - > wf - > nAvgBytesPerSec , mux_a - > h . dwSampleSize ) ;
2001-10-30 23:17:35 +00:00
break ;
}
2006-03-27 17:25:41 +00:00
if ( mp_msg_test ( MSGT_MENCODER , MSGL_DBG2 ) ) print_wave_header ( mux_a - > wf , MSGL_DBG2 ) ;
2002-06-23 17:34:29 +00:00
2006-02-20 09:36:10 +00:00
if ( ! ignore_start )
2006-02-19 09:34:37 +00:00
muxer - > audio_delay_fix + = sh_audio - > stream_delay ;
2002-08-01 08:39:33 +00:00
} // if(sh_audio)
2002-04-11 02:52:03 +00:00
decoded_frameno = 0 ;
2001-10-29 01:11:18 +00:00
signal ( SIGINT , exit_sighandler ) ; // Interrupt from keyboard
signal ( SIGQUIT , exit_sighandler ) ; // Quit from keyboard
signal ( SIGTERM , exit_sighandler ) ; // kill
2005-07-18 19:59:03 +00:00
signal ( SIGHUP , exit_sighandler ) ; // broken terminal line
signal ( SIGPIPE , exit_sighandler ) ; // broken pipe
2001-10-29 01:11:18 +00:00
2002-01-27 18:29:33 +00:00
timer_start = GetTimerMS ( ) ;
2005-02-25 02:32:29 +00:00
} // if (!curfile) // if this was the first file.
2005-10-13 19:30:07 +00:00
else {
2005-10-13 20:54:21 +00:00
if ( ! mux_a ! = ! sh_audio ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " \n Cannot mix video-only files with audio and video files. Try -nosound. \n " ) ;
2005-10-13 20:54:21 +00:00
mencoder_exit ( 1 , NULL ) ;
2005-04-22 06:59:59 +00:00
}
2005-10-13 20:54:21 +00:00
if ( sh_audio & & mux_a - > codec = = ACODEC_COPY ) {
2009-07-06 22:15:02 +00:00
if ( opts . playback_speed ! = 1.0 ) mp_tmsg ( MSGT_CPLAYER , MSGL_WARN , NoSpeedWithFrameCopy ) ;
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " audiocodec: framecopy (format=%x chans=%d rate=%d bits=%d B/s=%d sample-%d) \n " ,
2006-01-12 20:04:36 +00:00
mux_a - > wf - > wFormatTag , mux_a - > wf - > nChannels , mux_a - > wf - > nSamplesPerSec ,
mux_a - > wf - > wBitsPerSample , mux_a - > wf - > nAvgBytesPerSec , mux_a - > h . dwSampleSize ) ;
2005-10-13 20:54:21 +00:00
if ( sh_audio - > wf ) {
if ( ( mux_a - > wf - > wFormatTag ! = sh_audio - > wf - > wFormatTag ) | |
( mux_a - > wf - > nChannels ! = sh_audio - > wf - > nChannels ) | |
2008-04-21 03:55:23 +00:00
( mux_a - > wf - > nSamplesPerSec ! = sh_audio - > wf - > nSamplesPerSec * opts . playback_speed ) )
2005-10-13 20:54:21 +00:00
{
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " audiocodec: framecopy (format=%x chans=%d rate=%d bits=%d B/s=%d sample-%d) \n " ,
2008-04-21 03:55:23 +00:00
sh_audio - > wf - > wFormatTag , sh_audio - > wf - > nChannels , ( int ) ( sh_audio - > wf - > nSamplesPerSec * opts . playback_speed ) ,
2006-01-12 20:04:36 +00:00
sh_audio - > wf - > wBitsPerSample , sh_audio - > wf - > nAvgBytesPerSec , 0 ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " \n All files must have identical audio codec and format for -oac copy. \n " ) ;
2005-10-13 20:54:21 +00:00
mencoder_exit ( 1 , NULL ) ;
2005-02-25 02:32:29 +00:00
}
2005-10-13 20:54:21 +00:00
} else {
if ( ( mux_a - > wf - > wFormatTag ! = sh_audio - > format ) | |
( mux_a - > wf - > nChannels ! = sh_audio - > channels ) | |
2008-04-21 03:55:23 +00:00
( mux_a - > wf - > nSamplesPerSec ! = sh_audio - > samplerate * opts . playback_speed ) )
2005-10-13 20:54:21 +00:00
{
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " audiocodec: framecopy (format=%x chans=%d rate=%d bits=%d B/s=%d sample-%d) \n " ,
2008-04-21 03:55:23 +00:00
sh_audio - > wf - > wFormatTag , sh_audio - > wf - > nChannels , ( int ) ( sh_audio - > wf - > nSamplesPerSec * opts . playback_speed ) ,
2006-01-12 20:04:36 +00:00
sh_audio - > wf - > wBitsPerSample , sh_audio - > wf - > nAvgBytesPerSec , 0 ) ;
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " \n All files must have identical audio codec and format for -oac copy. \n " ) ;
2005-10-13 20:54:21 +00:00
mencoder_exit ( 1 , NULL ) ;
2005-02-25 02:32:29 +00:00
}
2005-10-13 20:54:21 +00:00
}
} else if ( sh_audio ) {
int out_srate = mux_a - > wf - > nSamplesPerSec ;
int out_channels = mux_a - > wf - > nChannels ;
int out_format = aencoder - > input_format ;
2007-11-01 06:52:28 +00:00
if ( ! init_audio_filters ( sh_audio , new_srate ,
& out_srate , & out_channels ,
& out_format ) ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_CPLAYER , MSGL_FATAL , " Couldn't find matching filter/ao format! \n " ) ;
2005-10-13 20:54:21 +00:00
mencoder_exit ( 1 , NULL ) ;
}
mux_a - > wf - > nSamplesPerSec = out_srate ;
mux_a - > wf - > nChannels = out_channels ;
2005-07-22 21:27:54 +00:00
}
2005-02-25 02:32:29 +00:00
}
2002-02-10 00:07:34 +00:00
if ( seek_to_sec ) {
2007-02-24 07:11:57 +00:00
demux_seek ( demuxer , seek_to_sec , audio_delay , 1 ) ;
2002-09-14 10:47:34 +00: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):
2006-02-17 01:57:41 +00:00
// if(demuxer2) demux_seek(demuxer2, d, audio_delay, 1);
2002-02-10 00:07:34 +00:00
}
2002-12-27 22:43:20 +00:00
if ( out_file_format = = MUXER_TYPE_MPEG )
{
if ( audio_preload > 0.4 ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " Limiting audio preload to 0.4s. \n " ) ;
2002-12-27 22:43:20 +00:00
audio_preload = 0.4 ;
}
if ( audio_density < 4 ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " Increasing audio density to 4. \n " ) ;
2003-01-03 11:51:39 +00:00
audio_density = 4 ;
2002-12-27 22:43:20 +00:00
}
}
2009-07-06 23:26:13 +00:00
if ( file_format = = DEMUXER_TYPE_TV )
2002-04-12 10:40:38 +00:00
{
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " Forcing audio preload to 0, max pts correction to 0. \n " ) ;
2002-04-12 10:40:38 +00:00
audio_preload = 0.0 ;
default_max_pts_correction = 0 ;
}
2002-06-28 17:13:18 +00:00
play_n_frames = play_n_frames_mf ;
2006-09-25 16:47:56 +00:00
if ( curfile & & end_at . type = = END_AT_TIME ) end_at . pos + = mux_v - > timer ;
2002-06-28 17:13:18 +00:00
2005-03-23 23:29:54 +00:00
if ( edl_records ) free_edl ( edl_records ) ;
next_edl_record = edl_records = NULL ;
edl_muted = 0 ;
edl_seeking = 1 ;
2005-03-19 20:55:51 +00:00
if ( edl_filename ) {
next_edl_record = edl_records = edl_parse_file ( ) ;
}
2005-07-17 19:40:05 +00:00
if ( sh_audio & & audio_delay ! = 0. ) fixdelay ( d_video , d_audio , mux_a , & frame_data , mux_v - > codec = = VCODEC_COPY ) ;
2002-06-13 21:35:10 +00:00
while ( ! at_eof ) {
2001-10-29 01:11:18 +00:00
int blit_frame = 0 ;
float a_pts = 0 ;
float v_pts = 0 ;
2001-11-01 21:47:28 +00:00
int skip_flag = 0 ; // 1=skip -1=duplicate
2001-10-29 01:11:18 +00:00
2006-12-18 21:03:59 +00:00
if ( ( end_at . type = = END_AT_SIZE & & end_at . pos < = stream_tell ( muxer - > stream ) ) | |
2006-09-25 16:47:56 +00:00
( end_at . type = = END_AT_TIME & & end_at . pos < mux_v - > timer ) )
2002-01-15 00:20:50 +00:00
break ;
2001-11-03 00:44:02 +00:00
if ( play_n_frames > = 0 ) {
- - play_n_frames ;
if ( play_n_frames < 0 ) break ;
}
2010-04-24 17:09:31 +00:00
if ( opts . chapterrange [ 1 ] > 0 ) {
2008-02-11 22:03:34 +00:00
int cur_chapter = demuxer_get_current_chapter ( demuxer ) ;
2010-04-24 17:09:31 +00:00
if ( cur_chapter ! = - 1 & & cur_chapter + 1 > opts . chapterrange [ 1 ] )
2008-02-11 22:03:34 +00:00
break ;
}
2001-11-03 00:44:02 +00:00
2005-03-19 20:55:51 +00:00
goto_redo_edl :
if ( next_edl_record & & sh_video & & sh_video - > pts > = next_edl_record - > start_sec ) {
if ( next_edl_record - > action = = EDL_SKIP & & edl_seeking ) {
float last_pos = d_video - > pts ;
int result ;
mp_msg ( MSGT_CPLAYER , MSGL_DBG4 , " EDL_SKIP: start [%f], stop [%f], length [%f] \n " ,
next_edl_record - > start_sec , next_edl_record - > stop_sec , next_edl_record - > length_sec ) ;
2005-07-17 19:25:58 +00:00
result = edl_seek ( next_edl_record , demuxer , d_audio , mux_a , & frame_data , mux_v - > codec = = VCODEC_COPY ) ;
2005-03-19 20:55:51 +00:00
2005-06-27 19:10:11 +00:00
if ( result = = 2 ) { at_eof = 1 ; break ; } // EOF
2005-03-19 20:55:51 +00:00
else if ( result = = 0 ) edl_seeking = 0 ; // no seeking
else { // sucess
edl_muted = 0 ;
if ( last_pos > = sh_video - > pts ) {
// backwards seek detected!! Forget about this EDL skip altogether.
next_edl_record = next_edl_record - > next ;
}
else for ( next_edl_record = edl_records ; next_edl_record ; next_edl_record = next_edl_record - > next ) {
/* note the use of stop_sec,
meaning if by some magical way we landed in the MIDDLE of a censored area ,
in the next loop it will jump out of it .
*/
if ( next_edl_record - > stop_sec > sh_video - > pts ) break ; // we got to the right place.
if ( next_edl_record - > action = = EDL_MUTE ) edl_muted = ! edl_muted ; // toggle mute each time.
}
/* for a pedantic EDL, that doesn't show even a single
frame from the " censored " area , uncomment next line . */
goto goto_redo_edl ;
}
} else if ( next_edl_record - > action = = EDL_MUTE ) {
edl_muted = ! edl_muted ; // This variable does nothing for now.
mp_msg ( MSGT_CPLAYER , MSGL_DBG4 , " EDL_MUTE: [%f] \n " , next_edl_record - > start_sec ) ;
next_edl_record = next_edl_record - > next ;
}
}
2001-10-30 23:17:35 +00:00
if ( sh_audio ) {
// get audio:
2001-10-31 00:25:28 +00:00
while ( mux_a - > timer - audio_preload < mux_v - > timer ) {
2005-04-22 06:59:59 +00:00
float tottime ;
2001-11-03 21:00:04 +00:00
int len = 0 ;
2002-04-12 10:40:38 +00:00
ptimer_start = GetTimerMS ( ) ;
2005-04-22 06:59:59 +00:00
// CBR - copy 0.5 sec of audio
// or until the end of video:
tottime = stop_time ( demuxer , mux_v ) ;
if ( tottime ! = - 1 ) {
tottime - = mux_a - > timer ;
if ( tottime > 1. / audio_density ) tottime = 1. / audio_density ;
2003-11-03 16:35:40 +00:00
}
2005-04-22 06:59:59 +00:00
else tottime = 1. / audio_density ;
2005-06-27 19:10:11 +00:00
// let's not output more audio than necessary
if ( tottime < = 0 ) break ;
2004-09-21 19:50:54 +00:00
2005-04-22 06:59:59 +00:00
if ( aencoder )
{
if ( mux_a - > h . dwSampleSize ) /* CBR */
{
if ( aencoder - > set_decoded_len )
{
len = mux_a - > h . dwSampleSize * ( int ) ( mux_a - > h . dwRate * tottime ) ;
aencoder - > set_decoded_len ( aencoder , len ) ;
}
else
len = aencoder - > decode_buffer_size ;
len = dec_audio ( sh_audio , aencoder - > decode_buffer , len ) ;
2009-07-06 23:26:13 +00:00
mux_a - > buffer_len + = aencoder - > encode ( aencoder , mux_a - > buffer + mux_a - > buffer_len ,
2005-12-07 10:07:27 +00:00
aencoder - > decode_buffer , len , mux_a - > buffer_size - mux_a - > buffer_len ) ;
2005-04-22 06:59:59 +00:00
if ( mux_a - > buffer_len < mux_a - > wf - > nBlockAlign )
len = 0 ;
2009-07-06 23:26:13 +00:00
else
2005-04-22 06:59:59 +00:00
len = mux_a - > wf - > nBlockAlign * ( mux_a - > buffer_len / mux_a - > wf - > nBlockAlign ) ;
2004-09-21 19:50:54 +00:00
}
2005-04-22 06:59:59 +00:00
else /* VBR */
{
int sz = 0 ;
while ( 1 )
{
len = 0 ;
if ( ! sz )
sz = aencoder - > get_frame_size ( aencoder ) ;
if ( sz > 0 & & mux_a - > buffer_len > = sz )
{
len = sz ;
break ;
}
len = dec_audio ( sh_audio , aencoder - > decode_buffer , aencoder - > decode_buffer_size ) ;
if ( len < = 0 )
{
len = 0 ;
break ;
}
2005-12-07 10:07:27 +00:00
len = aencoder - > encode ( aencoder , mux_a - > buffer + mux_a - > buffer_len , aencoder - > decode_buffer , len , mux_a - > buffer_size - mux_a - > buffer_len ) ;
2005-04-22 06:59:59 +00:00
mux_a - > buffer_len + = len ;
}
2004-09-21 19:50:54 +00:00
}
if ( mux_v - > timer = = 0 ) mux_a - > h . dwInitialFrames + + ;
}
2005-04-22 06:59:59 +00:00
else {
2001-10-30 23:17:35 +00:00
if ( mux_a - > h . dwSampleSize ) {
2001-10-31 00:25:28 +00:00
switch ( mux_a - > codec ) {
2001-12-08 13:30:06 +00:00
case ACODEC_COPY : // copy
2005-02-25 02:32:29 +00:00
len = mux_a - > wf - > nAvgBytesPerSec * tottime ;
2001-10-31 00:25:28 +00: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 ;
}
2001-10-30 23:17:35 +00:00
} else {
2001-11-01 02:31:23 +00:00
// VBR - encode/copy an audio frame
switch ( mux_a - > codec ) {
2001-12-08 13:30:06 +00:00
case ACODEC_COPY : // copy
2002-01-26 22:30:02 +00:00
len = ds_get_packet ( sh_audio - > ds , ( unsigned char * * ) & mux_a - > buffer ) ;
2001-11-01 02:31:23 +00:00
break ;
2001-10-31 16:08:01 +00:00
}
2001-11-01 02:31:23 +00:00
}
2001-10-30 23:17:35 +00:00
}
2001-10-31 00:25:28 +00:00
if ( len < = 0 ) break ; // EOF?
2010-02-28 07:45:23 +00:00
muxer_write_chunk ( mux_a , len , AVIIF_KEYFRAME , MP_NOPTS_VALUE , MP_NOPTS_VALUE ) ;
2001-11-03 21:09:21 +00:00
if ( ! mux_a - > h . dwSampleSize & & mux_a - > timer > 0 )
2001-12-06 21:50:35 +00:00
mux_a - > wf - > nAvgBytesPerSec = 0.5f + ( double ) mux_a - > size / mux_a - > timer ; // avg bps (VBR)
2001-10-31 16:08:01 +00:00
if ( mux_a - > buffer_len > = len ) {
mux_a - > buffer_len - = len ;
2007-06-05 14:27:54 +00:00
fast_memcpy ( mux_a - > buffer , mux_a - > buffer + len , mux_a - > buffer_len ) ;
2001-10-31 16:08:01 +00:00
}
2002-04-12 10:40:38 +00:00
audiosamples + + ;
audiorate + = ( GetTimerMS ( ) - ptimer_start ) ;
2009-07-06 23:26:13 +00:00
2001-10-30 23:17:35 +00:00
}
}
// get video frame!
2002-04-12 10:40:38 +00:00
2005-07-17 19:25:58 +00:00
if ( ! frame_data . already_read ) {
frame_data . in_size = video_read_frame ( sh_video , & frame_data . frame_time , & frame_data . start , force_fps ) ;
sh_video - > timer + = frame_data . frame_time ;
}
2008-04-21 03:55:23 +00:00
frame_data . frame_time / = opts . playback_speed ;
2005-07-17 19:25:58 +00:00
if ( frame_data . in_size < 0 ) { at_eof = 1 ; break ; }
+ + decoded_frameno ;
2002-04-12 10:40:38 +00:00
2005-07-17 19:25:58 +00:00
v_timer_corr - = frame_data . frame_time - ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
2002-12-28 12:51:05 +00:00
2002-04-11 02:52:03 +00:00
if ( demuxer2 ) { // 3-pass encoding, read control file (frameno.avi)
2002-01-26 22:30:02 +00:00
// find our frame:
while ( next_frameno < decoded_frameno ) {
int * start ;
int len = ds_get_packet ( demuxer2 - > video , ( unsigned char * * ) & start ) ;
2002-06-13 21:35:10 +00:00
if ( len < 0 ) { at_eof = 1 ; break ; }
2002-01-26 22:30:02 +00:00
if ( len = = 0 ) - - skip_flag ; else // duplicate
if ( len = = 4 ) next_frameno = start [ 0 ] ;
}
2002-06-13 21:35:10 +00:00
if ( at_eof ) break ;
2002-01-26 22:30:02 +00: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 21:35:10 +00:00
if ( len < 0 ) { at_eof = 1 ; break ; }
2002-01-26 22:30:02 +00:00
if ( len = = 0 ) - - skip_flag ; else // duplicate
if ( len = = 4 ) next_frameno = start [ 0 ] ;
}
} else {
2001-11-01 21:47:28 +00:00
// check frame duplicate/drop:
2006-02-19 04:31:14 +00:00
float mux_frametime = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
2002-07-12 18:03:16 +00:00
2006-02-19 04:31:14 +00:00
if ( v_timer_corr > = mux_frametime & & ( skip_limit < 0 | | skip_flag < skip_limit ) ) {
v_timer_corr - = mux_frametime ;
2001-11-01 21:47:28 +00:00
+ + skip_flag ; // skip
2006-02-19 04:31:14 +00:00
}
while ( v_timer_corr < = - mux_frametime & & ( skip_limit < 0 | | - skip_flag < skip_limit ) ) {
v_timer_corr + = mux_frametime ;
2001-11-01 21:47:28 +00:00
- - skip_flag ; // dup
}
2006-02-19 04:31:14 +00:00
// either v_pts_corr is big, more than 2 times framerate, then we follow its advice,
// or, it cancels out v_timer_corr, in which case be happy and do nothing.
while ( ( v_pts_corr < = - mux_frametime & & skip_flag > 0 ) | | ( v_pts_corr < = - 2 * mux_frametime ) ) {
v_pts_corr + = mux_frametime ;
2001-11-01 21:47:28 +00:00
- - skip_flag ; // dup
}
2006-02-19 04:31:14 +00:00
if ( ( v_pts_corr > = mux_frametime & & skip_flag < 0 ) | | ( v_pts_corr > = 2 * mux_frametime ) ) {
if ( skip_flag < = 0 ) { // we can't skip more than 1 frame now
v_pts_corr - = mux_frametime ;
2001-11-01 21:47:28 +00:00
+ + skip_flag ; // skip
}
2006-02-19 04:31:14 +00:00
}
2001-10-29 01:11:18 +00:00
2002-01-26 22:30:02 +00:00
} // demuxer2
2002-04-12 10:40:38 +00:00
ptimer_start = GetTimerMS ( ) ;
2001-10-29 01:11:18 +00:00
switch ( mux_v - > codec ) {
2001-12-08 12:21:23 +00:00
case VCODEC_COPY :
2005-07-17 19:25:58 +00:00
mux_v - > buffer = frame_data . start ;
2010-02-28 07:45:23 +00:00
if ( skip_flag < = 0 ) muxer_write_chunk ( mux_v , frame_data . in_size , ( sh_video - > ds - > flags & 1 ) ? AVIIF_KEYFRAME : 0 , MP_NOPTS_VALUE , MP_NOPTS_VALUE ) ;
2001-10-30 21:55:28 +00:00
break ;
2002-04-11 02:52:03 +00:00
case VCODEC_FRAMENO :
2002-06-27 19:33:28 +00:00
mux_v - > buffer = ( unsigned char * ) & decoded_frameno ; // tricky
2010-02-28 07:45:23 +00:00
if ( skip_flag < = 0 ) muxer_write_chunk ( mux_v , sizeof ( int ) , AVIIF_KEYFRAME , MP_NOPTS_VALUE , MP_NOPTS_VALUE ) ;
2002-02-07 20:22:03 +00:00
break ;
2002-04-11 02:52:03 +00:00
default :
// decode_video will callback down to ve_*.c encoders, through the video filters
2008-06-23 22:53:58 +00:00
sh_video - > vfilter - > control ( sh_video - > vfilter , VFCTRL_SET_OSD_OBJ , osd ) ;
2006-11-14 12:29:20 +00:00
{ void * decoded_frame = decode_video ( sh_video , frame_data . start , frame_data . in_size ,
2008-06-23 23:03:19 +00:00
skip_flag > 0 & & ( ! sh_video - > vfilter | | sh_video - > vfilter - > control ( sh_video - > vfilter , VFCTRL_SKIP_NEXT_FRAME , 0 ) ! = CONTROL_TRUE ) , MP_NOPTS_VALUE ) ;
2009-01-14 23:07:12 +00:00
blit_frame = decoded_frame & & filter_video ( sh_video , decoded_frame , MP_NOPTS_VALUE ) ;
if ( blit_frame ) {
struct vf_instance * vf = sh_video - > vfilter ;
vf - > control ( vf , VFCTRL_DRAW_EOSD , NULL ) ;
vf - > control ( vf , VFCTRL_DRAW_OSD , osd ) ;
}
}
2009-07-06 23:26:13 +00:00
2008-02-14 14:23:55 +00:00
if ( sh_video - > vf_initialized < 0 ) mencoder_exit ( 1 , NULL ) ;
2009-07-06 23:26:13 +00:00
2002-09-10 23:19:20 +00:00
if ( ! blit_frame ) {
2005-07-03 10:09:09 +00:00
if ( play_n_frames > = 0 )
play_n_frames + + ;
2002-09-10 23:19:20 +00:00
badframes + + ;
if ( skip_flag < = 0 ) {
2002-07-12 18:03:16 +00:00
// unwanted skipping of a frame, what to do?
honor decoder's/filter's decision to remove frames when using -noskip.
this may go against the original intention of the vf layer, but it's
how all the filters that drop frames have been written to work, so
it's now the de-facto standard.
without this patch, -noskip will result in tons of duplicate frames
(either soft or hard duplicates) and a/v desync whenever decimation,
ivtc, etc. is used. even with this patch -noskip is still a bad idea
for most of these purposes, but it will work reliably with filmdint,
framestep, and some other filters with fixed in:out ratios as long as
the right -ofps value is used. without this patch, there is no hope of
-noskip working with frame-dropping filters.
(this patch was previously committed erroneously as part of another
change, then reversed. it is now being committed again.)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@16830 b3059339-0415-0410-9bf9-f77b7e298cf2
2005-10-23 07:37:55 +00:00
v_timer_corr - = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
#if 0
2005-10-23 15:05:11 +00:00
// Old code apparently made under the assumption that !blit_frame means
// decoding failed due to corruption or something.. but duplication and
// skipping of frames should be entirely disabled when skip_limit==0,
// and must be in order for many filters to work with -noskip.
// Eventually this entire block should probably be removed.
2002-07-12 18:03:16 +00:00
if ( skip_limit = = 0 ) {
// skipping not allowed -> write empty frame:
2008-06-23 23:03:19 +00:00
if ( ! encode_duplicates | | ! sh_video - > vfilter | | sh_video - > vfilter - > control ( sh_video - > vfilter , VFCTRL_DUPLICATE_FRAME , 0 ) ! = CONTROL_TRUE )
2006-01-26 19:32:07 +00:00
muxer_write_chunk ( mux_v , 0 , 0 , MP_NOPTS_VALUE , MP_NOPTS_VALUE ) ;
2002-07-12 18:03:16 +00:00
} else {
// skipping allowed -> skip it and distriubute timer error:
v_timer_corr - = ( float ) mux_v - > h . dwScale / mux_v - > h . dwRate ;
}
honor decoder's/filter's decision to remove frames when using -noskip.
this may go against the original intention of the vf layer, but it's
how all the filters that drop frames have been written to work, so
it's now the de-facto standard.
without this patch, -noskip will result in tons of duplicate frames
(either soft or hard duplicates) and a/v desync whenever decimation,
ivtc, etc. is used. even with this patch -noskip is still a bad idea
for most of these purposes, but it will work reliably with filmdint,
framestep, and some other filters with fixed in:out ratios as long as
the right -ofps value is used. without this patch, there is no hope of
-noskip working with frame-dropping filters.
(this patch was previously committed erroneously as part of another
change, then reversed. it is now being committed again.)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@16830 b3059339-0415-0410-9bf9-f77b7e298cf2
2005-10-23 07:37:55 +00:00
# endif
2002-09-10 23:19:20 +00:00
}
2002-07-12 18:03:16 +00:00
}
2001-10-29 01:11:18 +00:00
}
2001-11-01 21:47:28 +00:00
2002-04-12 10:40:38 +00:00
videosamples + + ;
videorate + = ( GetTimerMS ( ) - ptimer_start ) ;
2001-11-01 21:47:28 +00:00
if ( skip_flag < 0 ) {
2001-11-01 02:31:23 +00:00
// duplicate frame
2009-07-06 22:15:02 +00:00
if ( ! quiet ) mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " \n %d duplicate frame(s)! \n " , - skip_flag ) ;
2001-11-01 21:47:28 +00:00
while ( skip_flag < 0 ) {
2002-04-12 10:40:38 +00:00
duplicatedframes + + ;
2008-06-23 23:03:19 +00:00
if ( ! encode_duplicates | | ! sh_video - > vfilter | | sh_video - > vfilter - > control ( sh_video - > vfilter , VFCTRL_DUPLICATE_FRAME , 0 ) ! = CONTROL_TRUE )
2006-01-26 19:32:07 +00:00
muxer_write_chunk ( mux_v , 0 , 0 , MP_NOPTS_VALUE , MP_NOPTS_VALUE ) ;
2001-11-01 21:47:28 +00:00
+ + skip_flag ;
}
2001-11-02 20:05:36 +00:00
} else
if ( skip_flag > 0 ) {
2001-11-01 02:31:23 +00:00
// skip frame
2009-07-06 22:15:02 +00:00
if ( ! quiet ) mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " \n Skipping frame! \n " ) ;
2002-04-12 10:40:38 +00:00
skippedframes + + ;
2001-11-01 21:47:28 +00:00
- - skip_flag ;
2001-11-01 02:31:23 +00:00
}
2002-01-26 22:30:02 +00:00
if ( sh_audio & & ! demuxer2 ) {
2001-11-01 02:31:23 +00:00
float AV_delay , x ;
// A-V sync!
2002-11-02 00:45:12 +00:00
#if 0
2001-11-01 02:31:23 +00: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 17:44:16 +00:00
( d_audio - > block_no ) ; // <- used for VBR audio
2001-11-01 02:31:23 +00:00
a_pts = samples * ( float ) sh_audio - > audio . dwScale / ( float ) sh_audio - > audio . dwRate ;
delay_corrected = 1 ;
2009-07-06 23:26:13 +00:00
} else
2002-11-02 00:45:12 +00:00
# endif
{
2001-11-01 02:31:23 +00: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 ;
a_pts + = ( ds_tell_pts ( d_audio ) - sh_audio - > a_in_buffer_len ) / ( float ) sh_audio - > i_bps ;
}
2003-01-16 23:03:06 +00:00
v_pts = sh_video ? sh_video - > pts : d_video - > pts ;
2001-11-01 02:31:23 +00:00
// av = compensated (with out buffering delay) A-V diff
2005-03-15 04:10:57 +00:00
AV_delay = ( a_pts - v_pts ) ;
2005-07-17 19:40:05 +00:00
AV_delay - = audio_delay ;
2008-04-21 03:55:23 +00:00
AV_delay / = opts . playback_speed ;
2005-03-15 04:10:57 +00:00
AV_delay - = mux_a - > timer - ( mux_v - > timer - ( v_timer_corr + v_pts_corr ) ) ;
2006-02-21 09:39:22 +00:00
// adjust for encoder delays
AV_delay - = ( float ) mux_a - > encoder_delay * mux_a - > h . dwScale / mux_a - > h . dwRate ;
AV_delay + = ( float ) mux_v - > encoder_delay * mux_v - > h . dwScale / mux_v - > h . dwRate ;
2001-11-01 02:31:23 +00: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 )
2008-04-21 03:55:23 +00:00
max_pts_correction = default_max_pts_correction * opts . playback_speed ;
2001-11-01 02:31:23 +00:00
else
2008-04-21 03:55:23 +00:00
max_pts_correction = sh_video - > frametime * 0.10 * opts . playback_speed ; // +-10% of time
2001-11-01 02:31:23 +00:00
// sh_video->timer-=x;
c_total + = x ;
2001-11-01 21:47:28 +00:00
v_pts_corr + = x ;
2001-11-01 02:31:23 +00:00
}
2002-01-27 18:29:33 +00:00
{ float t = ( GetTimerMS ( ) - timer_start ) * 0.001f ;
float len = ( demuxer - > movi_end - demuxer - > movi_start ) ;
2009-08-17 05:55:40 +00:00
off_t pos = demuxer - > filepos > = 0 ? demuxer - > filepos : stream_tell ( demuxer - > stream ) ;
float p = len > 1000 ? ( float ) ( pos - demuxer - > movi_start ) / len :
2005-10-30 09:11:40 +00:00
( demuxer_get_percent_pos ( demuxer ) / 100.0 ) ;
2002-11-02 00:45:12 +00:00
#if 0
2002-01-27 21:37:46 +00:00
if ( ! len & & sh_audio & & sh_audio - > audio . dwLength > 100 ) {
2002-08-02 17:44:16 +00:00
p = ( sh_audio - > audio . dwSampleSize ? ds_tell ( sh_audio - > ds ) / sh_audio - > audio . dwSampleSize : sh_audio - > ds - > block_no )
2002-01-27 21:37:46 +00:00
/ ( float ) ( sh_audio - > audio . dwLength ) ;
}
2002-11-02 00:45:12 +00:00
# endif
2004-01-29 12:01:26 +00:00
if ( ! quiet ) {
2007-06-05 16:13:00 +00:00
if ( mp_msg_test ( MSGT_STATUSLINE , MSGL_V ) ) {
mp_msg ( MSGT_STATUSLINE , 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 10:40:38 +00:00
mux_v - > timer , decoded_frameno , ( int ) ( p * 100 ) ,
2002-08-21 21:31:20 +00:00
( t > 1 ) ? ( int ) ( decoded_frameno / t + 0.5 ) : 0 ,
2009-07-06 23:26:13 +00:00
( p > 0.001 ) ? ( int ) ( ( t / p - t ) / 60 ) : 0 ,
2006-12-18 21:03:59 +00:00
( p > 0.001 ) ? ( int ) ( stream_tell ( muxer - > stream ) / p / 1024 / 1024 ) : 0 ,
2002-04-12 10:40:38 +00:00
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-10 23:19:20 +00:00
duplicatedframes , badframes , skippedframes
2002-04-12 10:40:38 +00:00
) ;
} else
2007-06-05 16:13:00 +00:00
mp_msg ( MSGT_STATUSLINE , MSGL_STATUS , " Pos:%6.1fs %6df (%2d%%) %5.2ffps Trem:%4dmin %3dmb A-V:%5.3f [%d:%d] \r " ,
2002-01-27 18:29:33 +00:00
mux_v - > timer , decoded_frameno , ( int ) ( p * 100 ) ,
2005-11-17 19:17:53 +00:00
( t > 1 ) ? ( float ) ( decoded_frameno / t ) : 0 ,
2009-07-06 23:26:13 +00:00
( p > 0.001 ) ? ( int ) ( ( t / p - t ) / 60 ) : 0 ,
2006-12-18 21:03:59 +00:00
( p > 0.001 ) ? ( int ) ( stream_tell ( muxer - > stream ) / p / 1024 / 1024 ) : 0 ,
2002-01-27 21:46:06 +00:00
v_pts_corr ,
( mux_v - > timer > 1 ) ? ( int ) ( mux_v - > size / mux_v - > timer / 125 ) : 0 ,
2002-01-31 00:38:53 +00:00
( mux_a & & mux_a - > timer > 1 ) ? ( int ) ( mux_a - > size / mux_a - > timer / 125 ) : 0
2002-01-27 18:29:33 +00:00
) ;
2004-01-29 12:01:26 +00:00
}
2002-01-27 18:29:33 +00:00
}
2001-11-01 02:31:23 +00:00
fflush ( stdout ) ;
2008-07-30 12:01:30 +00:00
# ifdef CONFIG_DVDREAD
2002-04-17 21:51:18 +00:00
// DVD sub:
2007-02-17 21:04:46 +00:00
if ( vobsub_writer ) {
2002-04-17 21:51:18 +00:00
unsigned char * packet = NULL ;
int len ;
while ( ( len = ds_get_packet_sub ( d_dvdsub , & packet ) ) > 0 ) {
2003-01-16 23:03:06 +00: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 ) ;
vobsub_out_output ( vobsub_writer , packet , len , mux_v - > timer + d_dvdsub - > pts - sh_video - > pts ) ;
2002-04-17 21:51:18 +00:00
}
}
2007-02-17 21:04:46 +00:00
else
2002-04-17 21:51:18 +00:00
# endif
2009-10-06 01:28:59 +00:00
update_subtitles ( NULL , & opts , sh_video , sh_video - > pts , 0 , d_dvdsub , 0 ) ;
2001-10-29 01:11:18 +00:00
2005-07-17 19:25:58 +00:00
frame_data = ( s_frame_data ) { . start = NULL , . in_size = 0 , . frame_time = 0. , . already_read = 0 } ;
2006-12-18 21:03:59 +00:00
#if 0
2002-06-07 22:40:06 +00:00
if ( ferror ( muxer_f ) ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " %s: Error writing file. \n " , out_filename ) ;
2002-06-07 22:40:06 +00:00
mencoder_exit ( 1 , NULL ) ;
}
2006-12-18 21:03:59 +00:00
# endif
2001-10-29 01:11:18 +00:00
2002-06-13 21:35:10 +00:00
} // while(!at_eof)
2001-10-29 01:11:18 +00:00
2005-02-25 02:32:29 +00:00
if ( ! interrupted & & filelist [ + + curfile ] . name ! = 0 ) {
2006-08-14 17:27:15 +00:00
if ( sh_video & & sh_video - > vfilter ) { // Before uniniting sh_video and the filter chain, break apart the VE.
vf_instance_t * ve ; // this will be the filter right before the ve.
for ( ve = sh_video - > vfilter ; ve - > next & & ve - > next - > next ; ve = ve - > next ) ;
if ( ve - > next ) ve - > next = NULL ; // I'm telling the last filter, before the VE, there is nothing after it
else sh_video - > vfilter = NULL ; // There is no chain except the VE.
2005-03-13 21:38:20 +00:00
}
2005-03-01 20:21:58 +00:00
2006-02-24 15:43:20 +00:00
if ( sh_audio ) { uninit_audio ( sh_audio ) ; sh_audio = NULL ; }
2005-02-25 02:32:29 +00:00
if ( sh_video ) { uninit_video ( sh_video ) ; sh_video = NULL ; }
if ( demuxer ) free_demuxer ( demuxer ) ;
if ( stream ) free_stream ( stream ) ; // kill cache thread
2006-08-14 17:27:15 +00:00
2005-02-27 18:22:23 +00:00
at_eof = 0 ;
2006-08-14 17:27:15 +00:00
2005-02-25 02:32:29 +00:00
m_config_pop ( mconfig ) ;
goto play_next_file ;
}
2005-03-01 20:21:58 +00:00
/* Emit the remaining frames in the video system */
/*TODO emit frmaes delayed by decoder lag*/
if ( sh_video & & sh_video - > vfilter ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " \n Flushing video frames. \n " ) ;
2008-06-23 23:03:19 +00:00
if ( ! sh_video - > vfilter - > fmt . have_configured )
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_WARN , " Filters have not been configured! Empty file? \n " ) ;
2006-08-14 16:15:21 +00:00
else
2008-06-23 23:03:19 +00:00
sh_video - > vfilter - > control ( sh_video - > vfilter ,
2005-03-01 20:21:58 +00:00
VFCTRL_FLUSH_FRAMES , 0 ) ;
}
2005-04-22 06:59:59 +00:00
if ( aencoder )
if ( aencoder - > fixup )
aencoder - > fixup ( aencoder ) ;
2001-12-06 21:50:35 +00:00
2003-10-22 17:04:39 +00:00
if ( muxer - > cont_write_index ) muxer_write_index ( muxer ) ;
2006-12-18 21:03:59 +00:00
muxer_f_size = stream_tell ( muxer - > stream ) ;
stream_seek ( muxer - > stream , 0 ) ;
2003-10-22 17:04:39 +00:00
if ( muxer - > cont_write_header ) muxer_write_header ( muxer ) ; // update header
2006-12-18 21:03:59 +00:00
#if 0
2002-06-07 22:40:06 +00:00
if ( ferror ( muxer_f ) | | fclose ( muxer_f ) ! = 0 ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_FATAL , " %s: Error writing file. \n " , out_filename ) ;
2002-06-07 22:40:06 +00:00
mencoder_exit ( 1 , NULL ) ;
}
2006-12-18 21:03:59 +00:00
# endif
2002-07-08 21:44:51 +00:00
if ( vobsub_writer )
vobsub_out_close ( vobsub_writer ) ;
2002-01-27 00:43:57 +00:00
if ( out_video_codec = = VCODEC_FRAMENO & & mux_v - > timer > 100 ) {
2009-07-06 22:15:02 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Recommended video bitrate for %s CD: %d \n " , " 650MB " , ( int ) ( ( 650 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Recommended video bitrate for %s CD: %d \n " , " 700MB " , ( int ) ( ( 700 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Recommended video bitrate for %s CD: %d \n " , " 800MB " , ( int ) ( ( 800 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Recommended video bitrate for %s CD: %d \n " , " 2 x 650MB " , ( int ) ( ( 2 * 650 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Recommended video bitrate for %s CD: %d \n " , " 2 x 700MB " , ( int ) ( ( 2 * 700 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " Recommended video bitrate for %s CD: %d \n " , " 2 x 800MB " , ( int ) ( ( 2 * 800 * 1024 * 1024 - muxer_f_size ) / mux_v - > timer / 125 ) ) ;
2002-01-27 00:43:57 +00:00
}
2010-03-07 16:33:01 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " \n Video stream: %8.3f kbit/s (%d B/s) size: % " PRIu64 " bytes %5.3f secs %d frames \n " ,
2006-04-26 20:24:03 +00:00
( float ) ( mux_v - > size / mux_v - > timer * 8.0f / 1000.0f ) , ( int ) ( mux_v - > size / mux_v - > timer ) , ( uint64_t ) mux_v - > size , ( float ) mux_v - > timer , decoded_frameno ) ;
2001-12-06 23:59:46 +00:00
if ( sh_audio )
2010-03-07 16:33:01 +00:00
mp_tmsg ( MSGT_MENCODER , MSGL_INFO , " \n Audio stream: %8.3f kbit/s (%d B/s) size: % " PRIu64 " bytes %5.3f secs \n " ,
2006-04-26 20:24:03 +00:00
( float ) ( mux_a - > size / mux_a - > timer * 8.0f / 1000.0f ) , ( int ) ( mux_a - > size / mux_a - > timer ) , ( uint64_t ) mux_a - > size , ( float ) mux_a - > timer ) ;
2001-12-06 23:59:46 +00:00
2006-02-24 15:43:20 +00:00
if ( sh_audio ) { uninit_audio ( sh_audio ) ; sh_audio = NULL ; }
2002-09-25 20:27:34 +00:00
if ( sh_video ) { uninit_video ( sh_video ) ; sh_video = NULL ; }
if ( demuxer ) free_demuxer ( demuxer ) ;
2001-11-02 01:25:13 +00:00
if ( stream ) free_stream ( stream ) ; // kill cache thread
2001-12-04 20:35:31 +00:00
return interrupted ;
2001-10-29 01:11:18 +00:00
}