@@ -74,6 +74,10 @@ static int cc608_parity(uint8_t byte);
7474static int cc608_good_parity (const int *parity_table, uint16_t data);
7575static 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+
7781static 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