static void SetupOutputFormat( decoder_t *p_dec, bool b_trust ) { decoder_sys_t *p_sys = p_dec->p_sys; GetVlcAudioFormat( &p_dec->fmt_out.i_codec, &p_dec->fmt_out.audio.i_bitspersample, p_sys->p_context->sample_fmt ); p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate; /* */ if( p_sys->i_previous_channels == p_sys->p_context->channels && p_sys->i_previous_layout == p_sys->p_context->channel_layout ) return; if( b_trust ) { p_sys->i_previous_channels = p_sys->p_context->channels; p_sys->i_previous_layout = p_sys->p_context->channel_layout; } /* Specified order * FIXME should we use fmt_in.audio.i_physical_channels or not ? */ const unsigned i_order_max = 8 * sizeof(p_sys->p_context->channel_layout); uint32_t pi_order_src[i_order_max]; int i_channels_src = 0; if( p_sys->p_context->channel_layout ) { for( unsigned i = 0; i < sizeof(pi_channels_map)/sizeof(*pi_channels_map); i++ ) { if( p_sys->p_context->channel_layout & pi_channels_map[i][0] ) pi_order_src[i_channels_src++] = pi_channels_map[i][1]; } } else { /* Create default order */ if( b_trust ) msg_Warn( p_dec, "Physical channel configuration not set : guessing" ); for( unsigned int i = 0; i < __MIN( i_order_max, (unsigned)p_sys->p_context->channels ); i++ ) { if( i < sizeof(pi_channels_map)/sizeof(*pi_channels_map) ) pi_order_src[i_channels_src++] = pi_channels_map[i][1]; } } if( i_channels_src != p_sys->p_context->channels && b_trust ) msg_Err( p_dec, "Channel layout not understood" ); uint32_t i_layout_dst; int i_channels_dst; p_sys->b_extract = aout_CheckChannelExtraction( p_sys->pi_extraction, &i_layout_dst, &i_channels_dst, NULL, pi_order_src, i_channels_src ); if( i_channels_dst != i_channels_src && b_trust ) msg_Warn( p_dec, "%d channels are dropped", i_channels_src - i_channels_dst ); p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = i_layout_dst; p_dec->fmt_out.audio.i_channels = i_channels_dst; }
static int Audio_GetOutput(decoder_t *p_dec, picture_t **pp_out_pic, block_t **pp_out_block, bool *p_abort, mtime_t i_timeout) { decoder_sys_t *p_sys = p_dec->p_sys; mc_api_out out; int i_ret; (void) p_abort; assert(!pp_out_pic && pp_out_block); i_ret = p_sys->api->get_out(p_sys->api, &out, i_timeout); if (i_ret != 1) return i_ret; if (out.type == MC_OUT_TYPE_BUF) { block_t *p_block = NULL; if (!p_sys->b_has_format) { msg_Warn(p_dec, "Buffers returned before output format is set, dropping frame"); return p_sys->api->release_out(p_sys->api, out.u.buf.i_index, false); } p_block = block_Alloc(out.u.buf.i_size); if (!p_block) return -1; p_block->i_nb_samples = out.u.buf.i_size / p_dec->fmt_out.audio.i_bytes_per_frame; if (p_sys->u.audio.b_extract) { aout_ChannelExtract(p_block->p_buffer, p_dec->fmt_out.audio.i_channels, out.u.buf.p_ptr, p_sys->u.audio.i_channels, p_block->i_nb_samples, p_sys->u.audio.pi_extraction, p_dec->fmt_out.audio.i_bitspersample); } else memcpy(p_block->p_buffer, out.u.buf.p_ptr, out.u.buf.i_size); if (out.u.buf.i_ts != 0 && out.u.buf.i_ts != date_Get(&p_sys->u.audio.i_end_date)) date_Set(&p_sys->u.audio.i_end_date, out.u.buf.i_ts); p_block->i_pts = date_Get(&p_sys->u.audio.i_end_date); p_block->i_length = date_Increment(&p_sys->u.audio.i_end_date, p_block->i_nb_samples) - p_block->i_pts; if (p_sys->api->release_out(p_sys->api, out.u.buf.i_index, false)) { block_Release(p_block); return -1; } *pp_out_block = p_block; return 1; } else { uint32_t i_layout_dst; int i_channels_dst; assert(out.type == MC_OUT_TYPE_CONF); if (out.u.conf.audio.channel_count <= 0 || out.u.conf.audio.channel_count > 8 || out.u.conf.audio.sample_rate <= 0) { msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d", out.u.conf.audio.channel_count, out.u.conf.audio.sample_rate); return -1; } msg_Err(p_dec, "output: channel_count: %d, channel_mask: 0x%X, rate: %d", out.u.conf.audio.channel_count, out.u.conf.audio.channel_mask, out.u.conf.audio.sample_rate); p_dec->fmt_out.i_codec = VLC_CODEC_S16N; p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec; p_dec->fmt_out.audio.i_rate = out.u.conf.audio.sample_rate; date_Init(&p_sys->u.audio.i_end_date, out.u.conf.audio.sample_rate, 1 ); p_sys->u.audio.i_channels = out.u.conf.audio.channel_count; p_sys->u.audio.b_extract = aout_CheckChannelExtraction(p_sys->u.audio.pi_extraction, &i_layout_dst, &i_channels_dst, NULL, pi_audio_order_src, p_sys->u.audio.i_channels); if (p_sys->u.audio.b_extract) msg_Warn(p_dec, "need channel extraction: %d -> %d", p_sys->u.audio.i_channels, i_channels_dst); p_dec->fmt_out.audio.i_original_channels = p_dec->fmt_out.audio.i_physical_channels = i_layout_dst; aout_FormatPrepare(&p_dec->fmt_out.audio); if (decoder_UpdateAudioFormat(p_dec)) return -1; p_sys->b_has_format = true; return 0; } }
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust ) { decoder_sys_t *p_sys = p_dec->p_sys; #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 51, 65, 0 ) switch( p_sys->p_context->sample_fmt ) { case SAMPLE_FMT_U8: p_dec->fmt_out.i_codec = VLC_CODEC_U8; p_dec->fmt_out.audio.i_bitspersample = 8; break; case SAMPLE_FMT_S32: p_dec->fmt_out.i_codec = VLC_CODEC_S32N; p_dec->fmt_out.audio.i_bitspersample = 32; break; case SAMPLE_FMT_FLT: p_dec->fmt_out.i_codec = VLC_CODEC_FL32; p_dec->fmt_out.audio.i_bitspersample = 32; break; case SAMPLE_FMT_DBL: p_dec->fmt_out.i_codec = VLC_CODEC_FL64; p_dec->fmt_out.audio.i_bitspersample = 64; break; case SAMPLE_FMT_S16: default: p_dec->fmt_out.i_codec = VLC_CODEC_S16N; p_dec->fmt_out.audio.i_bitspersample = 16; break; } #else p_dec->fmt_out.i_codec = VLC_CODEC_S16N; p_dec->fmt_out.audio.i_bitspersample = 16; #endif p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate; /* */ #if defined(LIBAVCODEC_AUDIO_LAYOUT) if( p_sys->i_previous_channels == p_sys->p_context->channels && p_sys->i_previous_layout == p_sys->p_context->channel_layout ) return; #else if( p_sys->i_previous_channels == p_sys->p_context->channels ) return; #endif if( b_trust ) { p_sys->i_previous_channels = p_sys->p_context->channels; #if defined(LIBAVCODEC_AUDIO_LAYOUT) p_sys->i_previous_layout = p_sys->p_context->channel_layout; #endif } /* Specified order * FIXME should we use fmt_in.audio.i_physical_channels or not ? */ #if defined(LIBAVCODEC_AUDIO_LAYOUT) const unsigned i_order_max = 8 * sizeof(p_sys->p_context->channel_layout); #else const unsigned i_order_max = 64; #endif uint32_t pi_order_src[i_order_max]; int i_channels_src = 0; #if defined(LIBAVCODEC_AUDIO_LAYOUT) if( p_sys->p_context->channel_layout ) { for( unsigned i = 0; i < sizeof(pi_channels_map)/sizeof(*pi_channels_map); i++ ) { if( p_sys->p_context->channel_layout & pi_channels_map[i][0] ) pi_order_src[i_channels_src++] = pi_channels_map[i][1]; } } else #endif { /* Create default order */ if( b_trust ) msg_Warn( p_dec, "Physical channel configuration not set : guessing" ); for( unsigned int i = 0; i < __MIN( i_order_max, (unsigned)p_sys->p_context->channels ); i++ ) { if( i < sizeof(pi_channels_map)/sizeof(*pi_channels_map) ) pi_order_src[i_channels_src++] = pi_channels_map[i][1]; } } if( i_channels_src != p_sys->p_context->channels && b_trust ) msg_Err( p_dec, "Channel layout not understood" ); uint32_t i_layout_dst; int i_channels_dst; p_sys->b_extract = aout_CheckChannelExtraction( p_sys->pi_extraction, &i_layout_dst, &i_channels_dst, NULL, pi_order_src, i_channels_src ); if( i_channels_dst != i_channels_src && b_trust ) msg_Warn( p_dec, "%d channels are dropped", i_channels_src - i_channels_dst ); p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = i_layout_dst; p_dec->fmt_out.audio.i_channels = i_channels_dst; }