Skip to content

Commit

Permalink
Migrate LAV Splitter to AVChannelLayout
Browse files Browse the repository at this point in the history
  • Loading branch information
Nevcairiel committed Aug 23, 2022
1 parent f3d1c56 commit a2ae7a2
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 42 deletions.
11 changes: 5 additions & 6 deletions demuxer/Demuxers/BDDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
66 changes: 41 additions & 25 deletions demuxer/Demuxers/LAVFAudioHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;

Expand All @@ -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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
8 changes: 4 additions & 4 deletions demuxer/Demuxers/LAVFDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2957,8 +2957,8 @@ const CBaseDemuxer::stream *CLAVFDemuxer::SelectAudioStream(std::list<std::strin
continue;

// First, check number of channels
int old_num_chans = old_stream->codecpar->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;
Expand Down
9 changes: 6 additions & 3 deletions demuxer/Demuxers/LAVFStreamInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions demuxer/Demuxers/LAVFUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit a2ae7a2

Please sign in to comment.