From a2ae7a2212c12fe554636114261a18ca2ab2f77a Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Tue, 23 Aug 2022 13:06:16 +0200 Subject: [PATCH] Migrate LAV Splitter to AVChannelLayout --- demuxer/Demuxers/BDDemuxer.cpp | 11 +++-- demuxer/Demuxers/LAVFAudioHelper.cpp | 66 +++++++++++++++++----------- demuxer/Demuxers/LAVFDemuxer.cpp | 8 ++-- demuxer/Demuxers/LAVFStreamInfo.cpp | 9 ++-- demuxer/Demuxers/LAVFUtils.cpp | 8 ++-- 5 files changed, 60 insertions(+), 42 deletions(-) diff --git a/demuxer/Demuxers/BDDemuxer.cpp b/demuxer/Demuxers/BDDemuxer.cpp index fa3024b86..0fea01865 100644 --- a/demuxer/Demuxers/BDDemuxer.cpp +++ b/demuxer/Demuxers/BDDemuxer.cpp @@ -855,13 +855,12 @@ void CBDDemuxer::ProcessClipInfo(CLPI_CL *clpi, bool overwrite) } else if (avstream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - if (avstream->codecpar->channels == 0) + if (avstream->codecpar->ch_layout.nb_channels == 0) { - avstream->codecpar->channels = (stream->format == BLURAY_AUDIO_FORMAT_MONO) - ? 1 - : (stream->format == BLURAY_AUDIO_FORMAT_STEREO) ? 2 : 6; - avstream->codecpar->channel_layout = - av_get_default_channel_layout(avstream->codecpar->channels); + av_channel_layout_default(&avstream->codecpar->ch_layout, + (stream->format == BLURAY_AUDIO_FORMAT_MONO) ? 1 + : (stream->format == BLURAY_AUDIO_FORMAT_STEREO) ? 2 + : 6); avstream->codecpar->sample_rate = (stream->rate == BLURAY_AUDIO_RATE_96 || stream->rate == BLURAY_AUDIO_RATE_96_COMBO) ? 96000 diff --git a/demuxer/Demuxers/LAVFAudioHelper.cpp b/demuxer/Demuxers/LAVFAudioHelper.cpp index 0e2ffb9f7..df8ab1dd2 100644 --- a/demuxer/Demuxers/LAVFAudioHelper.cpp +++ b/demuxer/Demuxers/LAVFAudioHelper.cpp @@ -135,7 +135,7 @@ WAVEFORMATEX *CLAVFAudioHelper::CreateWVFMTEX(const AVStream *avstream, ULONG *s wvfmt->wFormatTag = avstream->codecpar->codec_tag; - wvfmt->nChannels = avstream->codecpar->channels ? avstream->codecpar->channels : 2; + wvfmt->nChannels = avstream->codecpar->ch_layout.nb_channels ? avstream->codecpar->ch_layout.nb_channels : 2; wvfmt->nSamplesPerSec = avstream->codecpar->sample_rate ? avstream->codecpar->sample_rate : 48000; wvfmt->nAvgBytesPerSec = (DWORD)(avstream->codecpar->bit_rate / 8); @@ -225,19 +225,23 @@ WAVEFORMATEX_HDMV_LPCM *CLAVFAudioHelper::CreateWVFMTEX_LPCM(const AVStream *avs lpcm->cbSize = sizeof(WAVEFORMATEX_HDMV_LPCM) - sizeof(WAVEFORMATEX); BYTE channel_conf = 0; - switch (avstream->codecpar->channel_layout) + if (avstream->codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) { - case AV_CH_LAYOUT_MONO: channel_conf = 1; break; - case AV_CH_LAYOUT_STEREO: channel_conf = 3; break; - case AV_CH_LAYOUT_SURROUND: channel_conf = 4; break; - case AV_CH_LAYOUT_2_1: channel_conf = 5; break; - case AV_CH_LAYOUT_4POINT0: channel_conf = 6; break; - case AV_CH_LAYOUT_2_2: channel_conf = 7; break; - case AV_CH_LAYOUT_5POINT0: channel_conf = 8; break; - case AV_CH_LAYOUT_5POINT1: channel_conf = 9; break; - case AV_CH_LAYOUT_7POINT0: channel_conf = 10; break; - case AV_CH_LAYOUT_7POINT1: channel_conf = 11; break; - default: channel_conf = 0; + + switch (avstream->codecpar->ch_layout.u.mask) + { + case AV_CH_LAYOUT_MONO: channel_conf = 1; break; + case AV_CH_LAYOUT_STEREO: channel_conf = 3; break; + case AV_CH_LAYOUT_SURROUND: channel_conf = 4; break; + case AV_CH_LAYOUT_2_1: channel_conf = 5; break; + case AV_CH_LAYOUT_4POINT0: channel_conf = 6; break; + case AV_CH_LAYOUT_2_2: channel_conf = 7; break; + case AV_CH_LAYOUT_5POINT0: channel_conf = 8; break; + case AV_CH_LAYOUT_5POINT1: channel_conf = 9; break; + case AV_CH_LAYOUT_7POINT0: channel_conf = 10; break; + case AV_CH_LAYOUT_7POINT1: channel_conf = 11; break; + default: channel_conf = 0; + } } lpcm->channel_conf = channel_conf; @@ -257,7 +261,7 @@ WAVEFORMATEXTENSIBLE *CLAVFAudioHelper::CreateWFMTEX_RAW_PCM(const AVStream *avs WAVEFORMATEX *wfe = &wfex->Format; wfe->wFormatTag = (WORD)subtype.Data1; - wfe->nChannels = avstream->codecpar->channels; + wfe->nChannels = avstream->codecpar->ch_layout.nb_channels; wfe->nSamplesPerSec = avstream->codecpar->sample_rate; if (avstream->codecpar->format == AV_SAMPLE_FMT_S32 && avstream->codecpar->bits_per_raw_sample > 0) { @@ -272,21 +276,33 @@ WAVEFORMATEXTENSIBLE *CLAVFAudioHelper::CreateWFMTEX_RAW_PCM(const AVStream *avs wfe->nBlockAlign = wfe->nChannels * wfe->wBitsPerSample / 8; wfe->nAvgBytesPerSec = wfe->nSamplesPerSec * wfe->nBlockAlign; + bool bUseExtensible = false; + DWORD dwChannelMask = 0; - if ((wfe->wBitsPerSample > 16 || wfe->nSamplesPerSec > 48000) && wfe->nChannels <= 2) - { - dwChannelMask = wfe->nChannels == 2 ? (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) : SPEAKER_FRONT_CENTER; - } - else if (wfe->nChannels > 2) + if (wfe->nChannels > 2) { - dwChannelMask = (DWORD)avstream->codecpar->channel_layout; + bUseExtensible = true; + + if (avstream->codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) + dwChannelMask = (DWORD)avstream->codecpar->ch_layout.u.mask; + if (!dwChannelMask) { - dwChannelMask = (DWORD)av_get_default_channel_layout(wfe->nChannels); + AVChannelLayout Layout{}; + av_channel_layout_default(&Layout, wfe->nChannels); + dwChannelMask = (DWORD)Layout.u.mask; } + + if (dwChannelMask && av_popcount(dwChannelMask) != wfe->nChannels) + dwChannelMask = 0; + } + else if ((wfe->wBitsPerSample > 16 || wfe->nSamplesPerSec > 48000) && wfe->nChannels <= 2) + { + bUseExtensible = true; + dwChannelMask = wfe->nChannels == 2 ? (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT) : SPEAKER_FRONT_CENTER; } - if (dwChannelMask) + if (bUseExtensible) { wfex->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfex->Format.cbSize = sizeof(*wfex) - sizeof(wfex->Format); @@ -325,7 +341,7 @@ MPEG1WAVEFORMAT *CLAVFAudioHelper::CreateMP1WVFMT(const AVStream *avstream, ULON memcpy(&mpwvfmt->wfx, wvfmt, sizeof(WAVEFORMATEX)); mpwvfmt->dwHeadBitrate = (DWORD)avstream->codecpar->bit_rate; - mpwvfmt->fwHeadMode = avstream->codecpar->channels == 1 ? ACM_MPEG_SINGLECHANNEL : ACM_MPEG_DUALCHANNEL; + mpwvfmt->fwHeadMode = avstream->codecpar->ch_layout.nb_channels == 1 ? ACM_MPEG_SINGLECHANNEL : ACM_MPEG_DUALCHANNEL; mpwvfmt->fwHeadLayer = (avstream->codecpar->codec_id == AV_CODEC_ID_MP1) ? ACM_MPEG_LAYER1 : ACM_MPEG_LAYER2; if (avstream->codecpar->sample_rate == 0) @@ -352,7 +368,7 @@ VORBISFORMAT *CLAVFAudioHelper::CreateVorbis(const AVStream *avstream, ULONG *si return nullptr; memset(vfmt, 0, sizeof(VORBISFORMAT)); - vfmt->nChannels = avstream->codecpar->channels; + vfmt->nChannels = avstream->codecpar->ch_layout.nb_channels; vfmt->nSamplesPerSec = avstream->codecpar->sample_rate; vfmt->nAvgBitsPerSec = (DWORD)avstream->codecpar->bit_rate; vfmt->nMinBitsPerSec = vfmt->nMaxBitsPerSec = (DWORD)-1; @@ -393,7 +409,7 @@ VORBISFORMAT2 *CLAVFAudioHelper::CreateVorbis2(const AVStream *avstream, ULONG * return nullptr; memset(pvf2, 0, sizeof(VORBISFORMAT2)); - pvf2->Channels = avstream->codecpar->channels; + pvf2->Channels = avstream->codecpar->ch_layout.nb_channels; pvf2->SamplesPerSec = avstream->codecpar->sample_rate; pvf2->BitsPerSample = get_bits_per_sample(avstream->codecpar); diff --git a/demuxer/Demuxers/LAVFDemuxer.cpp b/demuxer/Demuxers/LAVFDemuxer.cpp index 92cb137ff..ad64a502c 100644 --- a/demuxer/Demuxers/LAVFDemuxer.cpp +++ b/demuxer/Demuxers/LAVFDemuxer.cpp @@ -2212,7 +2212,7 @@ STDMETHODIMP_(BOOL) CLAVFDemuxer::GetTrackExtendedInfo(UINT aTrackIdx, void *pSt pTEIA->Size = sizeof(*pTEIA); pTEIA->BitDepth = st->codecpar->bits_per_coded_sample; - pTEIA->Channels = st->codecpar->channels; + pTEIA->Channels = st->codecpar->ch_layout.nb_channels; pTEIA->OutputSamplingFrequency = (FLOAT)st->codecpar->sample_rate; pTEIA->SamplingFreq = (FLOAT)st->codecpar->sample_rate; } @@ -2439,7 +2439,7 @@ STDMETHODIMP CLAVFDemuxer::CreateStreams() } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && dwAudioScore < 4) { - if (st->codecpar->channels != 0) + if (st->codecpar->ch_layout.nb_channels != 0) dwAudioScore = 4; else dwAudioScore = 1; @@ -2957,8 +2957,8 @@ const CBaseDemuxer::stream *CLAVFDemuxer::SelectAudioStream(std::listcodecpar->channels; - int new_num_chans = new_stream->codecpar->channels; + int old_num_chans = old_stream->codecpar->ch_layout.nb_channels; + int new_num_chans = new_stream->codecpar->ch_layout.nb_channels; if (new_num_chans > old_num_chans) { best = *sit; diff --git a/demuxer/Demuxers/LAVFStreamInfo.cpp b/demuxer/Demuxers/LAVFStreamInfo.cpp index 3fee57e01..3480d75b4 100644 --- a/demuxer/Demuxers/LAVFStreamInfo.cpp +++ b/demuxer/Demuxers/LAVFStreamInfo.cpp @@ -57,12 +57,15 @@ STDMETHODIMP CLAVFStreamInfo::CreateAudioMediaType(AVFormatContext *avctx, AVStr avstream->codecpar->codec_tag = av_codec_get_tag(mp_wav_taglists, avstream->codecpar->codec_id); } - if (avstream->codecpar->channels == 0 || avstream->codecpar->sample_rate == 0) + if (avstream->codecpar->ch_layout.nb_channels == 0 || avstream->codecpar->sample_rate == 0) { if (avstream->codecpar->codec_id == AV_CODEC_ID_AAC && avstream->codecpar->bit_rate) { - if (!avstream->codecpar->channels) - avstream->codecpar->channels = 2; + if (!avstream->codecpar->ch_layout.nb_channels) + { + avstream->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + avstream->codecpar->ch_layout.nb_channels = 2; + } if (!avstream->codecpar->sample_rate) avstream->codecpar->sample_rate = 48000; } diff --git a/demuxer/Demuxers/LAVFUtils.cpp b/demuxer/Demuxers/LAVFUtils.cpp index 64f63c4b3..6ef7ec789 100644 --- a/demuxer/Demuxers/LAVFUtils.cpp +++ b/demuxer/Demuxers/LAVFUtils.cpp @@ -34,7 +34,7 @@ static int64_t get_bit_rate(const AVCodecParameters *par) case AVMEDIA_TYPE_ATTACHMENT: bit_rate = par->bit_rate; break; case AVMEDIA_TYPE_AUDIO: bit_rate = - par->bit_rate ? par->bit_rate : par->sample_rate * par->channels * av_get_bits_per_sample(par->codec_id); + par->bit_rate ? par->bit_rate : par->sample_rate * par->ch_layout.nb_channels * av_get_bits_per_sample(par->codec_id); break; default: bit_rate = 0; break; } @@ -357,11 +357,11 @@ std::string lavf_get_stream_description(const AVStream *pStream) { buf << ", " << par->sample_rate << " Hz"; } - if (par->channels) + if (par->ch_layout.nb_channels) { // Get channel layout - char channel[32]; - av_get_channel_layout_string(channel, 32, par->channels, par->channel_layout); + char channel[64] = {0}; + av_channel_layout_describe(&par->ch_layout, channel, sizeof(channel)); buf << ", " << channel; } // Sample Format