LibMedia: Set the AVCodecContext's sample rate and channel layout
This is required in order for our audio block output function to create a sample specification for WAV files.
This commit is contained in:
parent
b4ca17fd29
commit
fa3cda8e4a
3 changed files with 15 additions and 3 deletions
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
namespace Media::FFmpeg {
|
||||
|
||||
DecoderErrorOr<NonnullOwnPtr<FFmpegAudioDecoder>> FFmpegAudioDecoder::try_create(CodecID codec_id, ReadonlyBytes codec_initialization_data)
|
||||
DecoderErrorOr<NonnullOwnPtr<FFmpegAudioDecoder>> FFmpegAudioDecoder::try_create(CodecID codec_id, Audio::SampleSpecification const& sample_specification, ReadonlyBytes codec_initialization_data)
|
||||
{
|
||||
AVCodecContext* codec_context = nullptr;
|
||||
AVPacket* packet = nullptr;
|
||||
|
|
@ -37,6 +37,17 @@ DecoderErrorOr<NonnullOwnPtr<FFmpegAudioDecoder>> FFmpegAudioDecoder::try_create
|
|||
codec_context->time_base = { 1, 1'000'000 };
|
||||
codec_context->thread_count = static_cast<int>(min(Core::System::hardware_concurrency(), 4));
|
||||
|
||||
if (sample_specification.sample_rate() > NumericLimits<int>::max())
|
||||
return DecoderError::with_description(DecoderErrorCategory::Corrupted, "Sample rate is too large"sv);
|
||||
codec_context->sample_rate = static_cast<int>(sample_specification.sample_rate());
|
||||
|
||||
if (sample_specification.channel_map().is_valid()) {
|
||||
auto channel_layout_result = channel_map_to_av_channel_layout(sample_specification.channel_map());
|
||||
if (channel_layout_result.is_error())
|
||||
return DecoderError::format(DecoderErrorCategory::Invalid, channel_layout_result.error().string_literal());
|
||||
codec_context->ch_layout = channel_layout_result.release_value();
|
||||
}
|
||||
|
||||
if (!codec_initialization_data.is_empty()) {
|
||||
if (codec_initialization_data.size() > NumericLimits<int>::max())
|
||||
return DecoderError::corrupted("Codec initialization data is too large"sv);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Media::FFmpeg {
|
|||
|
||||
class MEDIA_API FFmpegAudioDecoder final : public AudioDecoder {
|
||||
public:
|
||||
static DecoderErrorOr<NonnullOwnPtr<FFmpegAudioDecoder>> try_create(CodecID, ReadonlyBytes codec_initialization_data);
|
||||
static DecoderErrorOr<NonnullOwnPtr<FFmpegAudioDecoder>> try_create(CodecID, Audio::SampleSpecification const&, ReadonlyBytes codec_initialization_data);
|
||||
FFmpegAudioDecoder(AVCodecContext* codec_context, AVPacket* packet, AVFrame* frame);
|
||||
virtual ~FFmpegAudioDecoder() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@ namespace Media {
|
|||
DecoderErrorOr<NonnullRefPtr<AudioDataProvider>> AudioDataProvider::try_create(NonnullRefPtr<Core::WeakEventLoopReference> const& main_thread_event_loop, NonnullRefPtr<MutexedDemuxer> const& demuxer, Track const& track)
|
||||
{
|
||||
auto codec_id = TRY(demuxer->get_codec_id_for_track(track));
|
||||
auto const& sample_specification = track.audio_data().sample_specification;
|
||||
auto codec_initialization_data = TRY(demuxer->get_codec_initialization_data_for_track(track));
|
||||
auto decoder = DECODER_TRY_ALLOC(FFmpeg::FFmpegAudioDecoder::try_create(codec_id, codec_initialization_data));
|
||||
auto decoder = DECODER_TRY_ALLOC(FFmpeg::FFmpegAudioDecoder::try_create(codec_id, sample_specification, codec_initialization_data));
|
||||
auto converter = DECODER_TRY_ALLOC(FFmpeg::FFmpegAudioConverter::try_create());
|
||||
|
||||
auto thread_data = DECODER_TRY_ALLOC(try_make_ref_counted<AudioDataProvider::ThreadData>(main_thread_event_loop, demuxer, track, move(decoder), move(converter)));
|
||||
|
|
|
|||
Loading…
Reference in a new issue