Skip to content

Commit d2db89e

Browse files
jyavenardBeirdo
authored andcommitted
Fix playback of DTS-HD and DTS-HD MA audio.
On system not supporting DTS-HD or DTS-HD MA via passthru, extract the core DTS stream instead. FFmpeg can not decode it unfortunately
1 parent b57e89c commit d2db89e

File tree

1 file changed

+118
-2
lines changed

1 file changed

+118
-2
lines changed

mythtv/libs/libmythtv/avformatdecoder.cpp

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ static int cc608_parity(uint8_t byte);
7474
static int cc608_good_parity(const int *parity_table, uint16_t data);
7575
static void cc608_build_parity_table(int *parity_table);
7676

77+
static int dts_decode_header(uint8_t *indata_ptr, int *rate,
78+
int *nblks, int *sfreq);
79+
static int extract_core_dts(unsigned char *data, int len);
80+
7781
static QSize get_video_dim(const AVCodecContext &ctx)
7882
{
7983
return QSize(ctx.width >> ctx.lowres, ctx.height >> ctx.lowres);
@@ -3746,9 +3750,20 @@ bool AvFormatDecoder::ProcessAudioPacket(AVStream *curstream, AVPacket *pkt,
37463750
return false;
37473751
}
37483752
}
3749-
3750-
m_spdifenc->WriteFrame(tmp_pkt.data, tmp_pkt.size);
3753+
// Extract core DTS unless we can process it
3754+
if (ctx->codec_id == CODEC_ID_DTS && !m_audio->CanHD())
3755+
{
3756+
tmp_pkt.size = extract_core_dts(tmp_pkt.data, tmp_pkt.size);
3757+
if (tmp_pkt.size < 0)
3758+
{
3759+
// error extracting core dts
3760+
avcodeclock->unlock();
3761+
return false;
3762+
}
3763+
}
37513764
data_size = tmp_pkt.size;
3765+
m_spdifenc->WriteFrame(tmp_pkt.data, data_size);
3766+
37523767
ret = m_spdifenc->GetData((unsigned char *)audioSamples, data_size);
37533768
if (ret < 0)
37543769
{
@@ -4505,4 +4520,105 @@ void AvFormatDecoder::av_update_stream_timings_video(AVFormatContext *ic)
45054520
}
45064521
}
45074522

4523+
static int extract_core_dts(unsigned char *data, int len)
4524+
{
4525+
int rate, sfreq, nblks;
4526+
4527+
int enc_len = dts_decode_header(data, &rate, &nblks, &sfreq);
4528+
if (enc_len < 0)
4529+
return enc_len;
4530+
4531+
int nr_samples = nblks * 32;
4532+
int block_len = nr_samples * 2 * 2;
4533+
4534+
if (enc_len == 0 || enc_len > len)
4535+
{
4536+
return len;
4537+
}
4538+
4539+
enc_len = (enc_len < block_len - 8) ? enc_len : block_len - 8;
4540+
4541+
return enc_len;
4542+
}
4543+
4544+
// defines from libavcodec/dca.h
4545+
#define DCA_MARKER_RAW_BE 0x7FFE8001
4546+
#define DCA_MARKER_RAW_LE 0xFE7F0180
4547+
#define DCA_MARKER_14B_BE 0x1FFFE800
4548+
#define DCA_MARKER_14B_LE 0xFF1F00E8
4549+
#define DCA_HD_MARKER 0x64582025
4550+
4551+
static int dts_decode_header(uint8_t *indata_ptr, int *rate,
4552+
int *nblks, int *sfreq)
4553+
{
4554+
uint id = ((indata_ptr[0] << 24) | (indata_ptr[1] << 16) |
4555+
(indata_ptr[2] << 8) | (indata_ptr[3]));
4556+
4557+
switch (id)
4558+
{
4559+
case DCA_MARKER_RAW_BE:
4560+
break;
4561+
case DCA_MARKER_RAW_LE:
4562+
case DCA_MARKER_14B_BE:
4563+
case DCA_MARKER_14B_LE:
4564+
case DCA_HD_MARKER:
4565+
VERBOSE(VB_AUDIO+VB_EXTRA, LOC +
4566+
QString("DTS: Unsupported frame (id 0x%1)").arg(id, 8, 16));
4567+
return -1;
4568+
break;
4569+
default:
4570+
VERBOSE(VB_IMPORTANT, LOC_ERR +
4571+
QString("DTS: Unknown frame (id 0x%1)").arg(id, 8, 16));
4572+
return -1;
4573+
}
4574+
4575+
int ftype = indata_ptr[4] >> 7;
4576+
4577+
int surp = (indata_ptr[4] >> 2) & 0x1f;
4578+
surp = (surp + 1) % 32;
4579+
4580+
*nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
4581+
++*nblks;
4582+
4583+
int fsize = (indata_ptr[5] & 0x03) << 12 |
4584+
(indata_ptr[6] << 4) | (indata_ptr[7] >> 4);
4585+
++fsize;
4586+
4587+
*sfreq = (indata_ptr[8] >> 2) & 0x0f;
4588+
*rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
4589+
4590+
if (ftype != 1)
4591+
{
4592+
VERBOSE(VB_IMPORTANT, LOC +
4593+
QString("DTS: Termination frames not handled (ftype %1)")
4594+
.arg(ftype));
4595+
return -1;
4596+
}
4597+
4598+
if (*sfreq != 13)
4599+
{
4600+
VERBOSE(VB_IMPORTANT, LOC +
4601+
QString("DTS: Only 48kHz supported (sfreq %1)").arg(*sfreq));
4602+
return -1;
4603+
}
4604+
4605+
if ((fsize > 8192) || (fsize < 96))
4606+
{
4607+
VERBOSE(VB_IMPORTANT, LOC +
4608+
QString("DTS: fsize: %1 invalid").arg(fsize));
4609+
return -1;
4610+
}
4611+
4612+
if (*nblks != 8 && *nblks != 16 && *nblks != 32 &&
4613+
*nblks != 64 && *nblks != 128 && ftype == 1)
4614+
{
4615+
VERBOSE(VB_IMPORTANT, LOC +
4616+
QString("DTS: nblks %1 not valid for normal frame")
4617+
.arg(*nblks));
4618+
return -1;
4619+
}
4620+
4621+
return fsize;
4622+
}
4623+
45084624
/* vim: set expandtab tabstop=4 shiftwidth=4: */

0 commit comments

Comments
 (0)