void LSMASHVideoSource::get_video_track( const char *source, uint32_t track_number, int threads, IScriptEnvironment *env ) { uint32_t number_of_tracks = open_file( source, env ); if( track_number && track_number > number_of_tracks ) env->ThrowError( "LSMASHVideoSource: the number of tracks equals %I32u.", number_of_tracks ); /* L-SMASH */ uint32_t i; lsmash_media_parameters_t media_param; if( track_number == 0 ) { /* Get the first video track. */ for( i = 1; i <= number_of_tracks; i++ ) { vdh.track_ID = lsmash_get_track_ID( vdh.root, i ); if( vdh.track_ID == 0 ) env->ThrowError( "LSMASHVideoSource: failed to find video track." ); lsmash_initialize_media_parameters( &media_param ); if( lsmash_get_media_parameters( vdh.root, vdh.track_ID, &media_param ) ) env->ThrowError( "LSMASHVideoSource: failed to get media parameters." ); if( media_param.handler_type == ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK ) break; } if( i > number_of_tracks ) env->ThrowError( "LSMASHVideoSource: failed to find video track." ); } else { /* Get the desired video track. */ vdh.track_ID = lsmash_get_track_ID( vdh.root, track_number ); if( vdh.track_ID == 0 ) env->ThrowError( "LSMASHVideoSource: failed to find video track." ); lsmash_initialize_media_parameters( &media_param ); if( lsmash_get_media_parameters( vdh.root, vdh.track_ID, &media_param ) ) env->ThrowError( "LSMASHVideoSource: failed to get media parameters." ); if( media_param.handler_type != ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK ) env->ThrowError( "LSMASHVideoSource: the track you specified is not a video track." ); } if( lsmash_construct_timeline( vdh.root, vdh.track_ID ) ) env->ThrowError( "LSMASHVideoSource: failed to get construct timeline." ); if( get_summaries( vdh.root, vdh.track_ID, &vdh.config ) ) env->ThrowError( "LSMASHVideoSource: failed to get summaries." ); vi.num_frames = lsmash_get_sample_count_in_media_timeline( vdh.root, vdh.track_ID ); setup_timestamp_info( &vdh, &vi, media_param.timescale, env ); /* libavformat */ for( i = 0; i < format_ctx->nb_streams && format_ctx->streams[i]->codec->codec_type != AVMEDIA_TYPE_VIDEO; i++ ); if( i == format_ctx->nb_streams ) env->ThrowError( "LSMASHVideoSource: failed to find stream by libavformat." ); /* libavcodec */ AVStream *stream = format_ctx->streams[i]; AVCodecContext *ctx = stream->codec; vdh.config.ctx = ctx; AVCodec *codec = avcodec_find_decoder( ctx->codec_id ); if( !codec ) env->ThrowError( "LSMASHVideoSource: failed to find %s decoder.", codec->name ); ctx->thread_count = threads; if( avcodec_open2( ctx, codec, NULL ) < 0 ) env->ThrowError( "LSMASHVideoSource: failed to avcodec_open2." ); }
/***************************************************************************** * Fetchers *****************************************************************************/ static uint32_t libavsmash_video_fetch_sample_count ( libavsmash_video_decode_handler_t *vdhp ) { if( !vdhp ) return 0; vdhp->sample_count = lsmash_get_sample_count_in_media_timeline( vdhp->root, vdhp->track_id ); return vdhp->sample_count; }
/***************************************************************************** * Fetchers *****************************************************************************/ static uint32_t libavsmash_audio_fetch_sample_count ( libavsmash_audio_decode_handler_t *adhp ) { if( !adhp ) return 0; adhp->frame_count = lsmash_get_sample_count_in_media_timeline( adhp->root, adhp->track_id ); return adhp->frame_count; }
void LSMASHAudioSource::get_audio_track( const char *source, uint32_t track_number, bool skip_priming, IScriptEnvironment *env ) { uint32_t number_of_tracks = open_file( source, env ); if( track_number && track_number > number_of_tracks ) env->ThrowError( "LSMASHAudioSource: the number of tracks equals %I32u.", number_of_tracks ); /* L-SMASH */ uint32_t i; lsmash_media_parameters_t media_param; if( track_number == 0 ) { /* Get the first audio track. */ for( i = 1; i <= number_of_tracks; i++ ) { adh.track_ID = lsmash_get_track_ID( adh.root, i ); if( adh.track_ID == 0 ) env->ThrowError( "LSMASHAudioSource: failed to find audio track." ); lsmash_initialize_media_parameters( &media_param ); if( lsmash_get_media_parameters( adh.root, adh.track_ID, &media_param ) ) env->ThrowError( "LSMASHAudioSource: failed to get media parameters." ); if( media_param.handler_type == ISOM_MEDIA_HANDLER_TYPE_AUDIO_TRACK ) break; } if( i > number_of_tracks ) env->ThrowError( "LSMASHAudioSource: failed to find audio track." ); } else { /* Get the desired audio track. */ adh.track_ID = lsmash_get_track_ID( adh.root, track_number ); if( adh.track_ID == 0 ) env->ThrowError( "LSMASHAudioSource: failed to find audio track." ); lsmash_initialize_media_parameters( &media_param ); if( lsmash_get_media_parameters( adh.root, adh.track_ID, &media_param ) ) env->ThrowError( "LSMASHAudioSource: failed to get media parameters." ); if( media_param.handler_type != ISOM_MEDIA_HANDLER_TYPE_AUDIO_TRACK ) env->ThrowError( "LSMASHAudioSource: the track you specified is not an audio track." ); } if( lsmash_construct_timeline( adh.root, adh.track_ID ) ) env->ThrowError( "LSMASHAudioSource: failed to get construct timeline." ); if( get_summaries( adh.root, adh.track_ID, &adh.config ) ) env->ThrowError( "LSMASHAudioSource: failed to get summaries." ); adh.frame_count = lsmash_get_sample_count_in_media_timeline( adh.root, adh.track_ID ); vi.num_audio_samples = lsmash_get_media_duration_from_media_timeline( adh.root, adh.track_ID ); if( skip_priming ) { uint32_t itunes_metadata_count = lsmash_count_itunes_metadata( adh.root ); for( i = 1; i <= itunes_metadata_count; i++ ) { lsmash_itunes_metadata_t metadata; if( lsmash_get_itunes_metadata( adh.root, i, &metadata ) < 0 ) continue; if( metadata.item != ITUNES_METADATA_ITEM_CUSTOM || (metadata.type != ITUNES_METADATA_TYPE_STRING && metadata.type != ITUNES_METADATA_TYPE_BINARY) || !metadata.meaning || !metadata.name || memcmp( "com.apple.iTunes", metadata.meaning, strlen( metadata.meaning ) ) || memcmp( "iTunSMPB", metadata.name, strlen( metadata.name ) ) ) { lsmash_cleanup_itunes_metadata( &metadata ); continue; } char *value = NULL; if( metadata.type == ITUNES_METADATA_TYPE_STRING ) { int length = strlen( metadata.value.string ); if( length >= 116 ) value = duplicate_as_string( metadata.value.string, length ); } else /* metadata.type == ITUNES_METADATA_TYPE_BINARY */ { if( metadata.value.binary.size >= 116 ) value = duplicate_as_string( metadata.value.binary.data, metadata.value.binary.size ); } lsmash_cleanup_itunes_metadata( &metadata ); if( !value ) continue; uint32_t dummy[9]; uint32_t priming_samples; uint32_t padding; uint64_t duration; if( 12 != sscanf( value, " %I32x %I32x %I32x %I64x %I32x %I32x %I32x %I32x %I32x %I32x %I32x %I32x", &dummy[0], &priming_samples, &padding, &duration, &dummy[1], &dummy[2], &dummy[3], &dummy[4], &dummy[5], &dummy[6], &dummy[7], &dummy[8] ) ) { delete [] value; continue; } delete [] value; adh.implicit_preroll = 1; aoh.skip_decoded_samples = priming_samples; vi.num_audio_samples = duration + priming_samples; break; } if( aoh.skip_decoded_samples == 0 ) { uint32_t ctd_shift; if( lsmash_get_composition_to_decode_shift_from_media_timeline( adh.root, adh.track_ID, &ctd_shift ) ) env->ThrowError( "LSMASHAudioSource: failed to get the timeline shift." ); aoh.skip_decoded_samples = ctd_shift + get_start_time( adh.root, adh.track_ID ); } } /* libavformat */ for( i = 0; i < format_ctx->nb_streams && format_ctx->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO; i++ ); if( i == format_ctx->nb_streams ) env->ThrowError( "LSMASHAudioSource: failed to find stream by libavformat." ); /* libavcodec */ AVStream *stream = format_ctx->streams[i]; AVCodecContext *ctx = stream->codec; adh.config.ctx = ctx; AVCodec *codec = avcodec_find_decoder( ctx->codec_id ); if( !codec ) env->ThrowError( "LSMASHAudioSource: failed to find %s decoder.", codec->name ); ctx->thread_count = 0; if( avcodec_open2( ctx, codec, NULL ) < 0 ) env->ThrowError( "LSMASHAudioSource: failed to avcodec_open2." ); }