static int transcode_video_encoder_open( sout_stream_t *p_stream, sout_stream_id_t *id ) { sout_stream_sys_t *p_sys = p_stream->p_sys; msg_Dbg( p_stream, "destination (after video filters) %ix%i", id->p_encoder->fmt_in.video.i_width, id->p_encoder->fmt_in.video.i_height ); id->p_encoder->p_module = module_need( id->p_encoder, "encoder", p_sys->psz_venc, true ); if( !id->p_encoder->p_module ) { msg_Err( p_stream, "cannot find video encoder (module:%s fourcc:%4.4s)", p_sys->psz_venc ? p_sys->psz_venc : "any", (char *)&p_sys->i_vcodec ); return VLC_EGENERIC; } id->p_encoder->fmt_in.video.i_chroma = id->p_encoder->fmt_in.i_codec; /* */ id->p_encoder->fmt_out.i_codec = vlc_fourcc_GetCodec( VIDEO_ES, id->p_encoder->fmt_out.i_codec ); id->id = sout_StreamIdAdd( p_stream->p_next, &id->p_encoder->fmt_out ); if( !id->id ) { msg_Err( p_stream, "cannot add this stream" ); return VLC_EGENERIC; } return VLC_SUCCESS; }
vlc_fourcc_t vlc_fourcc_GetCodecFromString( int i_cat, const char *psz_fourcc ) { if( !psz_fourcc || strlen(psz_fourcc) != 4 ) return 0; return vlc_fourcc_GetCodec( i_cat, VLC_FOURCC( psz_fourcc[0], psz_fourcc[1], psz_fourcc[2], psz_fourcc[3] ) ); }
static const char *GetOmxAudioEncRole( vlc_fourcc_t i_fourcc ) { unsigned int i; i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc ); for( i = 0; audio_enc_format_table[i].i_codec != 0; i++ ) if( audio_enc_format_table[i].i_fourcc == i_fourcc ) break; return audio_enc_format_table[i].psz_role; }
static const char *GetOmxVideoEncRole( vlc_fourcc_t i_fourcc ) { unsigned int i; i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc ); for( i = 0; video_enc_format_table[i].i_codec != 0; i++ ) if( video_enc_format_table[i].i_fourcc == i_fourcc ) break; return video_enc_format_table[i].psz_role; }
bool es_format_IsSimilar( const es_format_t *p_fmt1, const es_format_t *p_fmt2 ) { if( p_fmt1->i_cat != p_fmt2->i_cat || vlc_fourcc_GetCodec( p_fmt1->i_cat, p_fmt1->i_codec ) != vlc_fourcc_GetCodec( p_fmt2->i_cat, p_fmt2->i_codec ) ) return false; switch( p_fmt1->i_cat ) { case AUDIO_ES: { audio_format_t a1 = p_fmt1->audio; audio_format_t a2 = p_fmt2->audio; if( a1.i_format && a2.i_format && a1.i_format != a2.i_format ) return false; if( a1.i_rate != a2.i_rate || a1.i_physical_channels != a2.i_physical_channels || a1.i_original_channels != a2.i_original_channels ) return false; return true; } case VIDEO_ES: { video_format_t v1 = p_fmt1->video; video_format_t v2 = p_fmt2->video; if( !v1.i_chroma ) v1.i_chroma = vlc_fourcc_GetCodec( p_fmt1->i_cat, p_fmt1->i_codec ); if( !v2.i_chroma ) v2.i_chroma = vlc_fourcc_GetCodec( p_fmt1->i_cat, p_fmt2->i_codec ); return video_format_IsSimilar( &p_fmt1->video, &p_fmt2->video ); } case SPU_ES: default: return true; } }
int GetOmxVideoFormat( vlc_fourcc_t i_fourcc, OMX_VIDEO_CODINGTYPE *pi_omx_codec, const char **ppsz_name ) { unsigned int i; i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc ); for( i = 0; video_format_table[i].i_codec != 0; i++ ) if( video_format_table[i].i_fourcc == i_fourcc ) break; if( pi_omx_codec ) *pi_omx_codec = video_format_table[i].i_codec; if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc ); return !!video_format_table[i].i_codec; }
int GetOmxAudioFormat( vlc_fourcc_t i_fourcc, OMX_AUDIO_CODINGTYPE *pi_omx_codec, const char **ppsz_name ) { unsigned int i; i_fourcc = vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc ); for( i = 0; audio_format_table[i].i_codec != 0; i++ ) if( audio_format_table[i].i_fourcc == i_fourcc ) break; if( pi_omx_codec ) *pi_omx_codec = audio_format_table[i].i_codec; if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( AUDIO_ES, i_fourcc ); return !!audio_format_table[i].i_codec; }
int GetOmxChromaFormat( vlc_fourcc_t i_fourcc, OMX_COLOR_FORMATTYPE *pi_omx_codec, const char **ppsz_name ) { unsigned int i; i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc ); for( i = 0; chroma_format_table[i].i_codec != 0; i++ ) if( chroma_format_table[i].i_fourcc == i_fourcc ) break; if( pi_omx_codec ) *pi_omx_codec = chroma_format_table[i].i_codec; if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( VIDEO_ES, i_fourcc ); return !!chroma_format_table[i].i_codec; }
int GetFfmpegCodec( vlc_fourcc_t i_fourcc, int *pi_cat, unsigned *pi_ffmpeg_codec, const char **ppsz_name ) { i_fourcc = vlc_fourcc_GetCodec( UNKNOWN_ES, i_fourcc ); for( unsigned i = 0; i < codecs_count; i++ ) { if( codecs_table[i].i_fourcc == i_fourcc ) { if( pi_cat ) *pi_cat = codecs_table[i].i_cat; if( pi_ffmpeg_codec ) *pi_ffmpeg_codec = codecs_table[i].i_codec; if( ppsz_name ) *ppsz_name = vlc_fourcc_GetDescription( UNKNOWN_ES, i_fourcc );//char *)codecs_table[i].psz_name; return true; } } return false; }
/***************************************************************************** * aout_BitsPerSample : get the number of bits per sample *****************************************************************************/ unsigned int aout_BitsPerSample( vlc_fourcc_t i_format ) { switch( vlc_fourcc_GetCodec( AUDIO_ES, i_format ) ) { case VLC_CODEC_U8: case VLC_CODEC_S8: case VLC_CODEC_ALAW: case VLC_CODEC_MULAW: return 8; case VLC_CODEC_U16L: case VLC_CODEC_S16L: case VLC_CODEC_U16B: case VLC_CODEC_S16B: return 16; case VLC_CODEC_U24L: case VLC_CODEC_S24L: case VLC_CODEC_U24B: case VLC_CODEC_S24B: return 24; case VLC_CODEC_S24L32: case VLC_CODEC_S24B32: case VLC_CODEC_U32L: case VLC_CODEC_U32B: case VLC_CODEC_S32L: case VLC_CODEC_S32B: case VLC_CODEC_F32L: case VLC_CODEC_F32B: return 32; case VLC_CODEC_F64L: case VLC_CODEC_F64B: return 64; default: /* For these formats the caller has to indicate the parameters * by hand. */ return 0; } }
static int transcode_audio_initialize_encoder( sout_stream_id_t *id, sout_stream_t *p_stream ) { sout_stream_sys_t *p_sys = p_stream->p_sys; /* Initialization of encoder format structures */ es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat, id->p_decoder->fmt_out.i_codec ); id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec; id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate; id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_out.audio.i_physical_channels; aout_FormatPrepare( &id->p_encoder->fmt_in.audio ); id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg; id->p_encoder->p_module = module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true ); if( !id->p_encoder->p_module ) { msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s). Take a look few lines earlier to see possible reason.", p_sys->psz_aenc ? p_sys->psz_aenc : "any", (char *)&p_sys->i_acodec ); module_unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = NULL; return VLC_EGENERIC; } id->p_encoder->fmt_out.i_codec = vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec ); /* Fix input format */ id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec; if( !id->p_encoder->fmt_in.audio.i_physical_channels || !id->p_encoder->fmt_in.audio.i_original_channels ) { if( id->p_encoder->fmt_in.audio.i_channels < 6 ) id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_in.audio.i_original_channels = pi_channels_maps[id->p_encoder->fmt_in.audio.i_channels]; } aout_FormatPrepare( &id->p_encoder->fmt_in.audio ); return VLC_SUCCESS; }
int GetVlcChromaSizes( vlc_fourcc_t i_fourcc, unsigned int width, unsigned int height, unsigned int *size, unsigned int *pitch, unsigned int *chroma_pitch_div ) { unsigned int i; i_fourcc = vlc_fourcc_GetCodec( VIDEO_ES, i_fourcc ); for( i = 0; chroma_format_table[i].i_codec != 0; i++ ) if( chroma_format_table[i].i_fourcc == i_fourcc ) break; /* Align on macroblock boundary */ width = (width + 15) & ~0xF; height = (height + 15) & ~0xF; if( size ) *size = width * height * chroma_format_table[i].i_size_mul / 2; if( pitch ) *pitch = width * chroma_format_table[i].i_line_mul; if( chroma_pitch_div ) *chroma_pitch_div = chroma_format_table[i].i_line_chroma_div; return !!chroma_format_table[i].i_codec; }
vlc_fourcc_t vlc_fourcc_GetCodecAudio( vlc_fourcc_t i_fourcc, int i_bits ) { const int i_bytes = ( i_bits + 7 ) / 8; if( i_fourcc == VLC_FOURCC( 'a', 'f', 'l', 't' ) ) { switch( i_bytes ) { case 4: return VLC_CODEC_FL32; case 8: return VLC_CODEC_FL64; default: return 0; } } else if( i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) || i_fourcc == VLC_FOURCC( 'p', 'c', 'm', ' ' ) ) { switch( i_bytes ) { case 1: return VLC_CODEC_U8; case 2: return VLC_CODEC_S16L; case 3: return VLC_CODEC_S24L; break; case 4: return VLC_CODEC_S32L; default: return 0; } } else if( i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) ) { switch( i_bytes ) { case 1: return VLC_CODEC_S8; case 2: return VLC_CODEC_S16B; case 3: return VLC_CODEC_S24B; case 4: return VLC_CODEC_S32B; default: return 0; } } else if( i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) ) { switch( i_bytes ) { case 1: return VLC_CODEC_S8; case 2: return VLC_CODEC_S16L; case 3: return VLC_CODEC_S24L; case 4: return VLC_CODEC_S32L; default: return 0; } } else { return vlc_fourcc_GetCodec( AUDIO_ES, i_fourcc ); } }
int transcode_audio_new( sout_stream_t *p_stream, sout_stream_id_t *id ) { sout_stream_sys_t *p_sys = p_stream->p_sys; audio_sample_format_t fmt_last; /* * Open decoder */ /* Initialization of decoder structures */ id->p_decoder->fmt_out = id->p_decoder->fmt_in; id->p_decoder->fmt_out.i_extra = 0; id->p_decoder->fmt_out.p_extra = 0; id->p_decoder->pf_decode_audio = NULL; id->p_decoder->pf_aout_format_update = audio_update_format; /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */ id->p_decoder->p_module = module_need( id->p_decoder, "decoder", "$codec", false ); if( !id->p_decoder->p_module ) { msg_Err( p_stream, "cannot find audio decoder" ); return VLC_EGENERIC; } /* decoders don't set audio.i_format, but audio filters use it */ id->p_decoder->fmt_out.audio.i_format = id->p_decoder->fmt_out.i_codec; aout_FormatPrepare( &id->p_decoder->fmt_out.audio ); fmt_last = id->p_decoder->fmt_out.audio; /* Fix AAC SBR changing number of channels and sampling rate */ if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A && fmt_last.i_rate != id->p_encoder->fmt_in.audio.i_rate && fmt_last.i_channels != id->p_encoder->fmt_in.audio.i_channels) ) fmt_last.i_rate = id->p_decoder->fmt_in.audio.i_rate; /* * Open encoder */ /* Initialization of encoder format structures */ es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat, id->p_decoder->fmt_out.i_codec ); id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec; id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate; id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_out.audio.i_physical_channels; aout_FormatPrepare( &id->p_encoder->fmt_in.audio ); id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg; id->p_encoder->p_module = module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true ); if( !id->p_encoder->p_module ) { msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s). Take a look few lines earlier to see possible reason.", p_sys->psz_aenc ? p_sys->psz_aenc : "any", (char *)&p_sys->i_acodec ); module_unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = NULL; return VLC_EGENERIC; } id->p_encoder->fmt_out.i_codec = vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec ); /* Fix input format */ id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec; if( !id->p_encoder->fmt_in.audio.i_physical_channels || !id->p_encoder->fmt_in.audio.i_original_channels ) { if( id->p_encoder->fmt_in.audio.i_channels < 6 ) id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_in.audio.i_original_channels = pi_channels_maps[id->p_encoder->fmt_in.audio.i_channels]; } aout_FormatPrepare( &id->p_encoder->fmt_in.audio ); if( unlikely( transcode_audio_initialize_filters( p_stream, id, p_sys, &fmt_last ) != VLC_SUCCESS ) ) return VLC_EGENERIC; return VLC_SUCCESS; }
void video_format_Setup( video_format_t *p_fmt, vlc_fourcc_t i_chroma, int i_width, int i_height, int i_sar_num, int i_sar_den ) { p_fmt->i_chroma = vlc_fourcc_GetCodec( VIDEO_ES, i_chroma ); p_fmt->i_width = p_fmt->i_visible_width = i_width; p_fmt->i_height = p_fmt->i_visible_height = i_height; p_fmt->i_x_offset = p_fmt->i_y_offset = 0; vlc_ureduce( &p_fmt->i_sar_num, &p_fmt->i_sar_den, i_sar_num, i_sar_den, 0 ); switch( p_fmt->i_chroma ) { case VLC_CODEC_YUVA: p_fmt->i_bits_per_pixel = 32; break; case VLC_CODEC_I444: case VLC_CODEC_J444: p_fmt->i_bits_per_pixel = 24; break; case VLC_CODEC_I422: case VLC_CODEC_YUYV: case VLC_CODEC_YVYU: case VLC_CODEC_UYVY: case VLC_CODEC_VYUY: case VLC_CODEC_J422: p_fmt->i_bits_per_pixel = 16; break; case VLC_CODEC_I440: case VLC_CODEC_J440: p_fmt->i_bits_per_pixel = 16; break; case VLC_CODEC_I411: case VLC_CODEC_YV12: case VLC_CODEC_I420: case VLC_CODEC_J420: case VLC_CODEC_MV12: p_fmt->i_bits_per_pixel = 12; break; case VLC_CODEC_YV9: case VLC_CODEC_I410: p_fmt->i_bits_per_pixel = 9; break; case VLC_CODEC_Y211: p_fmt->i_bits_per_pixel = 8; break; case VLC_CODEC_YUVP: p_fmt->i_bits_per_pixel = 8; break; case VLC_CODEC_RGB32: case VLC_CODEC_RGBA: p_fmt->i_bits_per_pixel = 32; break; case VLC_CODEC_RGB24: p_fmt->i_bits_per_pixel = 24; break; case VLC_CODEC_RGB15: case VLC_CODEC_RGB16: p_fmt->i_bits_per_pixel = 16; break; case VLC_CODEC_RGB8: p_fmt->i_bits_per_pixel = 8; break; case VLC_CODEC_GREY: case VLC_CODEC_RGBP: p_fmt->i_bits_per_pixel = 8; break; default: p_fmt->i_bits_per_pixel = 0; break; } }
int transcode_audio_new( sout_stream_t *p_stream, sout_stream_id_t *id ) { sout_stream_sys_t *p_sys = p_stream->p_sys; es_format_t fmt_last; /* * Open decoder */ /* Initialization of decoder structures */ id->p_decoder->fmt_out = id->p_decoder->fmt_in; id->p_decoder->fmt_out.i_extra = 0; id->p_decoder->fmt_out.p_extra = 0; id->p_decoder->pf_decode_audio = NULL; id->p_decoder->pf_aout_buffer_new = audio_new_buffer; id->p_decoder->pf_aout_buffer_del = audio_del_buffer; /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */ id->p_decoder->p_module = module_need( id->p_decoder, "decoder", "$codec", false ); if( !id->p_decoder->p_module ) { msg_Err( p_stream, "cannot find audio decoder" ); return VLC_EGENERIC; } id->p_decoder->fmt_out.audio.i_bitspersample = aout_BitsPerSample( id->p_decoder->fmt_out.i_codec ); fmt_last = id->p_decoder->fmt_out; /* Fix AAC SBR changing number of channels and sampling rate */ if( !(id->p_decoder->fmt_in.i_codec == VLC_CODEC_MP4A && fmt_last.audio.i_rate != id->p_encoder->fmt_in.audio.i_rate && fmt_last.audio.i_channels != id->p_encoder->fmt_in.audio.i_channels) ) fmt_last.audio.i_rate = id->p_decoder->fmt_in.audio.i_rate; /* * Open encoder */ /* Initialization of encoder format structures */ es_format_Init( &id->p_encoder->fmt_in, id->p_decoder->fmt_in.i_cat, id->p_decoder->fmt_out.i_codec ); id->p_encoder->fmt_in.audio.i_format = id->p_decoder->fmt_out.i_codec; id->p_encoder->fmt_in.audio.i_rate = id->p_encoder->fmt_out.audio.i_rate; id->p_encoder->fmt_in.audio.i_physical_channels = id->p_encoder->fmt_out.audio.i_physical_channels; id->p_encoder->fmt_in.audio.i_original_channels = id->p_encoder->fmt_out.audio.i_original_channels; id->p_encoder->fmt_in.audio.i_channels = id->p_encoder->fmt_out.audio.i_channels; id->p_encoder->fmt_in.audio.i_bitspersample = aout_BitsPerSample( id->p_encoder->fmt_in.i_codec ); id->p_encoder->p_cfg = p_stream->p_sys->p_audio_cfg; id->p_encoder->p_module = module_need( id->p_encoder, "encoder", p_sys->psz_aenc, true ); if( !id->p_encoder->p_module ) { msg_Err( p_stream, "cannot find audio encoder (module:%s fourcc:%4.4s)", p_sys->psz_aenc ? p_sys->psz_aenc : "any", (char *)&p_sys->i_acodec ); module_unneed( id->p_decoder, id->p_decoder->p_module ); id->p_decoder->p_module = NULL; return VLC_EGENERIC; } id->p_encoder->fmt_in.audio.i_format = id->p_encoder->fmt_in.i_codec; id->p_encoder->fmt_in.audio.i_bitspersample = aout_BitsPerSample( id->p_encoder->fmt_in.i_codec ); /* Load user specified audio filters */ if( p_sys->psz_af ) { es_format_t fmt_fl32 = fmt_last; fmt_fl32.i_codec = fmt_fl32.audio.i_format = VLC_CODEC_FL32; id->p_uf_chain = filter_chain_New( p_stream, "audio filter", false, transcode_audio_filter_allocation_init, NULL, NULL ); filter_chain_Reset( id->p_uf_chain, &fmt_last, &fmt_fl32 ); if( transcode_audio_filter_chain_build( p_stream, id->p_uf_chain, &fmt_fl32, &fmt_last ) ) { transcode_audio_close( id ); return VLC_EGENERIC; } fmt_last = fmt_fl32; if( filter_chain_AppendFromString( id->p_uf_chain, p_sys->psz_af ) > 0 ) fmt_last = *filter_chain_GetFmtOut( id->p_uf_chain ); } /* Load conversion filters */ id->p_f_chain = filter_chain_New( p_stream, "audio filter", true, transcode_audio_filter_allocation_init, NULL, NULL ); filter_chain_Reset( id->p_f_chain, &fmt_last, &id->p_encoder->fmt_in ); if( transcode_audio_filter_chain_build( p_stream, id->p_f_chain, &id->p_encoder->fmt_in, &fmt_last ) ) { transcode_audio_close( id ); return VLC_EGENERIC; } fmt_last = id->p_encoder->fmt_in; /* */ id->p_encoder->fmt_out.i_codec = vlc_fourcc_GetCodec( AUDIO_ES, id->p_encoder->fmt_out.i_codec ); return VLC_SUCCESS; }
static int SetOutputType(decoder_t *p_dec, DWORD stream_id, IMFMediaType **result) { decoder_sys_t *p_sys = p_dec->p_sys; HRESULT hr; *result = NULL; IMFMediaType *output_media_type = NULL; /* * Enumerate available output types. The list is ordered by * preference thus we will use the first one unless YV12/I420 is * available for video or float32 for audio. */ int output_type_index = 0; bool found = false; for (int i = 0; !found; ++i) { hr = IMFTransform_GetOutputAvailableType(p_sys->mft, stream_id, i, &output_media_type); if (hr == MF_E_NO_MORE_TYPES) break; else if (hr == MF_E_TRANSFORM_TYPE_NOT_SET) { /* The input type must be set before setting the output type for this MFT. */ return VLC_SUCCESS; } else if (FAILED(hr)) goto error; GUID subtype; hr = IMFMediaType_GetGUID(output_media_type, &MF_MT_SUBTYPE, &subtype); if (FAILED(hr)) goto error; if (p_dec->fmt_in.i_cat == VIDEO_ES) { if (IsEqualGUID(&subtype, &MFVideoFormat_YV12) || IsEqualGUID(&subtype, &MFVideoFormat_I420)) found = true; } else { UINT32 bits_per_sample; hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bits_per_sample); if (FAILED(hr)) continue; if (bits_per_sample == 32 && IsEqualGUID(&subtype, &MFAudioFormat_Float)) found = true; } if (found) output_type_index = i; IMFMediaType_Release(output_media_type); output_media_type = NULL; } /* * It's not an error if we don't find the output type we were * looking for, in this case we use the first available type which * is the "preferred" output type for this MFT. */ hr = IMFTransform_GetOutputAvailableType(p_sys->mft, stream_id, output_type_index, &output_media_type); if (FAILED(hr)) goto error; hr = IMFTransform_SetOutputType(p_sys->mft, stream_id, output_media_type, 0); if (FAILED(hr)) goto error; GUID subtype; hr = IMFMediaType_GetGUID(output_media_type, &MF_MT_SUBTYPE, &subtype); if (FAILED(hr)) goto error; if (p_dec->fmt_in.i_cat == VIDEO_ES) { video_format_Copy( &p_dec->fmt_out.video, &p_dec->fmt_in.video ); p_dec->fmt_out.i_codec = vlc_fourcc_GetCodec(p_dec->fmt_in.i_cat, subtype.Data1); } else { p_dec->fmt_out.audio = p_dec->fmt_in.audio; UINT32 bitspersample = 0; hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bitspersample); if (SUCCEEDED(hr) && bitspersample) p_dec->fmt_out.audio.i_bitspersample = bitspersample; UINT32 channels = 0; hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_NUM_CHANNELS, &channels); if (SUCCEEDED(hr) && channels) p_dec->fmt_out.audio.i_channels = channels; UINT32 rate = 0; hr = IMFMediaType_GetUINT32(output_media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate); if (SUCCEEDED(hr) && rate) p_dec->fmt_out.audio.i_rate = rate; vlc_fourcc_t fourcc; wf_tag_to_fourcc(subtype.Data1, &fourcc, NULL); p_dec->fmt_out.i_codec = vlc_fourcc_GetCodecAudio(fourcc, p_dec->fmt_out.audio.i_bitspersample); p_dec->fmt_out.audio.i_physical_channels = pi_channels_maps[p_dec->fmt_out.audio.i_channels]; } *result = output_media_type; return VLC_SUCCESS; error: msg_Err(p_dec, "Error in SetOutputType()"); if (output_media_type) IMFMediaType_Release(output_media_type); return VLC_EGENERIC; }