@ -91,6 +91,7 @@ const int program_birth_year = 2000;
/* select an input stream for an output stream */
typedef struct StreamMap {
int disabled ; /** 1 is this mapping is disabled by a negative map */
int file_index ;
int stream_index ;
int sync_file_index ;
@ -2953,27 +2954,82 @@ static int opt_codec_tag(const char *opt, const char *arg)
static int opt_map ( const char * opt , const char * arg )
{
StreamMap * m ;
char * p ;
StreamMap * m = NULL ;
int i , negative = 0 , file_idx ;
int sync_file_idx = - 1 , sync_stream_idx ;
char * p , * sync ;
char * map ;
if ( * arg = = ' - ' ) {
negative = 1 ;
arg + + ;
}
map = av_strdup ( arg ) ;
/* parse sync stream first, just pick first matching stream */
if ( sync = strchr ( map , ' , ' ) ) {
* sync = 0 ;
sync_file_idx = strtol ( sync + 1 , & sync , 0 ) ;
if ( sync_file_idx > = nb_input_files | | sync_file_idx < 0 ) {
av_log ( NULL , AV_LOG_ERROR , " Invalid sync file index: %d. \n " , sync_file_idx ) ;
exit_program ( 1 ) ;
}
if ( * sync )
sync + + ;
for ( i = 0 ; i < input_files [ sync_file_idx ] . ctx - > nb_streams ; i + + )
if ( check_stream_specifier ( input_files [ sync_file_idx ] . ctx ,
input_files [ sync_file_idx ] . ctx - > streams [ i ] , sync ) = = 1 ) {
sync_stream_idx = i ;
break ;
}
if ( i = = input_files [ sync_file_idx ] . ctx - > nb_streams ) {
av_log ( NULL , AV_LOG_ERROR , " Sync stream specification in map %s does not "
" match any streams. \n " , arg ) ;
exit_program ( 1 ) ;
}
}
stream_maps = grow_array ( stream_maps , sizeof ( * stream_maps ) , & nb_stream_maps , nb_stream_maps + 1 ) ;
m = & stream_maps [ nb_stream_maps - 1 ] ;
m - > file_index = strtol ( arg , & p , 0 ) ;
if ( * p )
p + + ;
file_idx = strtol ( map , & p , 0 ) ;
if ( file_idx > = nb_input_files | | file_idx < 0 ) {
av_log ( NULL , AV_LOG_ERROR , " Invalid input file index: %d. \n " , file_idx ) ;
exit_program ( 1 ) ;
}
if ( negative )
/* disable some already defined maps */
for ( i = 0 ; i < nb_stream_maps ; i + + ) {
m = & stream_maps [ i ] ;
if ( check_stream_specifier ( input_files [ m - > file_index ] . ctx ,
input_files [ m - > file_index ] . ctx - > streams [ m - > stream_index ] ,
* p = = ' : ' ? p + 1 : p ) > 0 )
m - > disabled = 1 ;
}
else
for ( i = 0 ; i < input_files [ file_idx ] . ctx - > nb_streams ; i + + ) {
if ( check_stream_specifier ( input_files [ file_idx ] . ctx , input_files [ file_idx ] . ctx - > streams [ i ] ,
* p = = ' : ' ? p + 1 : p ) < = 0 )
continue ;
stream_maps = grow_array ( stream_maps , sizeof ( * stream_maps ) , & nb_stream_maps , nb_stream_maps + 1 ) ;
m = & stream_maps [ nb_stream_maps - 1 ] ;
m - > stream_index = strtol ( p , & p , 0 ) ;
if ( * p ) {
p + + ;
m - > sync_file_index = strtol ( p , & p , 0 ) ;
if ( * p )
p + + ;
m - > sync_stream_index = strtol ( p , & p , 0 ) ;
} else {
m - > sync_file_index = m - > file_index ;
m - > sync_stream_index = m - > stream_index ;
m - > file_index = file_idx ;
m - > stream_index = i ;
if ( sync_file_idx > = 0 ) {
m - > sync_file_index = sync_file_idx ;
m - > sync_stream_index = sync_stream_idx ;
} else {
m - > sync_file_index = file_idx ;
m - > sync_stream_index = i ;
}
}
if ( ! m ) {
av_log ( NULL , AV_LOG_ERROR , " Stream map '%s' matches no streams. \n " , arg ) ;
exit_program ( 1 ) ;
}
av_freep ( & map ) ;
return 0 ;
}
@ -3710,21 +3766,9 @@ static int opt_output_file(const char *opt, const char *filename)
} else {
for ( i = 0 ; i < nb_stream_maps ; i + + ) {
StreamMap * map = & stream_maps [ i ] ;
int fi = map - > file_index ;
int si = map - > stream_index ;
if ( fi < 0 | | fi > = nb_input_files | |
si < 0 | | si > = input_files [ fi ] . ctx - > nb_streams ) {
av_log ( NULL , AV_LOG_ERROR , " Input stream #%d.%d does not exist. \n " , fi , si ) ;
exit_program ( 1 ) ;
}
fi = map - > sync_file_index ;
si = map - > sync_stream_index ;
if ( fi < 0 | | fi > = nb_input_files | |
si < 0 | | si > = input_files [ fi ] . ctx - > nb_streams ) {
av_log ( NULL , AV_LOG_ERROR , " Sync stream #%d.%d does not exist. \n " , fi , si ) ;
exit_program ( 1 ) ;
}
if ( map - > disabled )
continue ;
ist = & input_streams [ input_files [ map - > file_index ] . ist_index + map - > stream_index ] ;
switch ( ist - > st - > codec - > codec_type ) {