annotate foosdk/sdk/foobar2000/helpers/packet_decoder_aac_common.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "StdAfx.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "packet_decoder_aac_common.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include "../SDK/filesystem_helper.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include "bitreader_helper.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 size_t packet_decoder_aac_common::skipADTSHeader( const uint8_t * data,size_t size ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 if ( size < 7 ) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 PFC_ASSERT( bitreader_helper::extract_int(data, 0, 12) == 0xFFF);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 if (bitreader_helper::extract_bit(data, 12+1+2)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 return 7; // ABSENT flag
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 if (size < 9) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 return 9;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 pfc::array_t<uint8_t> packet_decoder_aac_common::parseDecoderSetup( const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 if ( p_owner == owner_ADTS ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 pfc::array_t<uint8_t> ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 ret.resize( 2 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 ret[0] = 0; ret[1] = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 // ret:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 // 5 bits AOT
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 // 4 bits freqindex
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 // 4 bits channelconfig
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 // source:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 // 12 bits 0xFFF
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 // 4 bits disregard
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 // 2 bits AOT-1 @ 16
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 // 4 bits freqindex @ 18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 // 1 bit disregard
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 // 3 bits channelconfig @ 23
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 // 26 bits total, 4 bytes minimum
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 if ( p_param2size < 4 ) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 const uint8_t * source = (const uint8_t*) p_param2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 if ( bitreader_helper::extract_int(source, 0, 12) != 0xFFF ) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 size_t aot = bitreader_helper::extract_int(source, 16, 2) + 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 if ( aot >= 31 ) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 size_t freqindex = bitreader_helper::extract_int(source, 18, 4);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 if ( freqindex > 12 ) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 size_t channelconfig = bitreader_helper::extract_bits( source, 23, 3);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 bitreader_helper::write_int(ret.get_ptr(), 0, 5, aot);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 bitreader_helper::write_int(ret.get_ptr(), 5, 4, freqindex);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 bitreader_helper::write_int(ret.get_ptr(), 9, 4, channelconfig);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 } else if ( p_owner == owner_ADIF ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 // bah
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 } else if ( p_owner == owner_MP4 )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 if ( p_param1 == 0x40 || p_param1 == 0x66 || p_param1 == 0x67 || p_param1 == 0x68 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 pfc::array_t<uint8_t> ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 ret.set_data_fromptr( (const uint8_t*) p_param2, p_param2size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 else if ( p_owner == owner_matroska )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 const matroska_setup * setup = ( const matroska_setup * ) p_param2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 if ( p_param2size == sizeof(*setup) )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 if ( !strcmp(setup->codec_id, "A_AAC") || !strncmp(setup->codec_id, "A_AAC/", 6) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 pfc::array_t<uint8_t> ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 ret.set_data_fromptr( (const uint8_t*) setup->codec_private, setup->codec_private_size );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 #if 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 bool packet_decoder_aac_common::parseDecoderSetup(const GUID &p_owner, t_size p_param1, const void *p_param2, t_size p_param2size, const void *&outCodecPrivate, size_t &outCodecPrivateSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 outCodecPrivate = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 outCodecPrivateSize = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 if ( p_owner == owner_ADTS ) { return true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 else if ( p_owner == owner_ADIF ) { return true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 else if ( p_owner == owner_MP4 )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 if ( p_param1 == 0x40 || p_param1 == 0x66 || p_param1 == 0x67 || p_param1 == 0x68 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 outCodecPrivate = p_param2; outCodecPrivateSize = p_param2size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 else if ( p_owner == owner_matroska )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 const matroska_setup * setup = ( const matroska_setup * ) p_param2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 if ( p_param2size == sizeof(*setup) )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 if ( !strcmp(setup->codec_id, "A_AAC") || !strncmp(setup->codec_id, "A_AAC/", 6) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 outCodecPrivate = (const uint8_t *) setup->codec_private;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 outCodecPrivateSize = setup->codec_private_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 bool packet_decoder_aac_common::testDecoderSetup( const GUID & p_owner, t_size p_param1, const void * p_param2, t_size p_param2size ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 if ( p_owner == owner_ADTS ) { return true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 else if ( p_owner == owner_ADIF ) { return true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 else if ( p_owner == owner_MP4 )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 if ( p_param1 == 0x40 || p_param1 == 0x66 || p_param1 == 0x67 || p_param1 == 0x68 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 else if ( p_owner == owner_matroska )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 const matroska_setup * setup = ( const matroska_setup * ) p_param2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 if ( p_param2size == sizeof(*setup) )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 if ( !strcmp(setup->codec_id, "A_AAC") || !strncmp(setup->codec_id, "A_AAC/", 6) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 namespace {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 class esds_maker : public stream_writer_buffer_simple {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 void write_esds_obj( uint8_t code, const void * data, size_t size, abort_callback & aborter ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 if ( size >= ( 1 << 28 ) ) throw pfc::exception_overflow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 write_byte(code, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 for ( int i = 3; i >= 0; -- i ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 uint8_t c = (uint8_t)( 0x7F & ( size >> 7 * i ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 if ( i > 0 ) c |= 0x80;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 write_byte(c, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 write( data, size, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 void write_esds_obj( uint8_t code, esds_maker const & other, abort_callback & aborter ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 write_esds_obj( code, other.m_buffer.get_ptr(), other.m_buffer.get_size(), aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 void write_byte( uint8_t byte , abort_callback & aborter ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 write( &byte, 1, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 void packet_decoder_aac_common::make_ESDS( pfc::array_t<uint8_t> & outESDS, const void * inCodecPrivate, size_t inCodecPrivateSize ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 if (inCodecPrivateSize > 1024*1024) throw exception_io_data(); // sanity
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 auto & p_abort = fb2k::noAbort;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 esds_maker esds4;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 const uint8_t crap[] = {0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x05, 0x34, 0x08, 0x00, 0x02, 0x3D, 0x55};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 esds4.write( crap, sizeof(crap), p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 esds_maker esds5;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 esds5.write( inCodecPrivate, inCodecPrivateSize, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 esds4.write_esds_obj(5, esds5, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 esds_maker esds3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 esds3.write_byte( 0, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 esds3.write_byte( 1, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 esds3.write_byte( 0, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 esds3.write_esds_obj(4, esds4, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 // esds6 after esds4, but doesn't seem that important
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 esds_maker final;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 final.write_esds_obj(3, esds3, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 outESDS.set_data_fromptr( final.m_buffer.get_ptr(), final.m_buffer.get_size() );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 /*
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 static const uint8_t esdsTemplate[] = {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 0x03, 0x80, 0x80, 0x80, 0x25, 0x00, 0x01, 0x00, 0x04, 0x80, 0x80, 0x80, 0x17, 0x40, 0x15, 0x00,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 0x00, 0x00, 0x00, 0x05, 0x34, 0x08, 0x00, 0x02, 0x3D, 0x55, 0x05, 0x80, 0x80, 0x80, 0x05, 0x12,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 0x30, 0x56, 0xE5, 0x00, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 // ESDS: 03 80 80 80 25 00 01 00 04 80 80 80 17 40 15 00 00 00 00 05 34 08 00 02 3D 55 05 80 80 80 05 12 30 56 E5 00 06 80 80 80 01 02
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 // For: 12 30 56 E5 00
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 const uint32_t aac_sample_rates[] = {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 static unsigned readSamplingFreq(bitreader_helper::bitreader_limited& r) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 unsigned samplingRateIndex = (unsigned)r.read(4);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 if (samplingRateIndex == 15) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 return (unsigned)r.read(24);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 if (samplingRateIndex >= PFC_TABSIZE(aac_sample_rates)) throw exception_io_data();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 return aac_sample_rates[samplingRateIndex];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 packet_decoder_aac_common::audioSpecificConfig_t packet_decoder_aac_common::parseASC(const void * p_, size_t s) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 // Source: https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 bitreader_helper::bitreader_limited r((const uint8_t*)p_, 0, s * 8);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 audioSpecificConfig_t cfg = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 cfg.m_objectType = (unsigned) r.read(5);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 if (cfg.m_objectType == 31) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 cfg.m_objectType = 32 + (unsigned) r.read(6);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 cfg.m_sampleRate = readSamplingFreq(r);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 cfg.m_channels = (unsigned) r.read( 4 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 if (cfg.m_objectType == 5 || cfg.m_objectType == 29) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 cfg.m_explicitSBR = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 cfg.m_explicitPS = (cfg.m_objectType == 29);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 cfg.m_sbrRate = readSamplingFreq(r);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 cfg.m_objectType = (unsigned)r.read(5);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 switch (cfg.m_objectType) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 case 1: case 2: case 3: case 4: case 17: case 23:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 cfg.m_shortWindow = (r.read(1) != 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 return cfg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 unsigned packet_decoder_aac_common::get_ASC_object_type(const void * p_, size_t s) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 // Source: https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 bitreader_helper::bitreader_limited r((const uint8_t*)p_, 0, s * 8);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 unsigned objectType = (unsigned) r.read(5);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 if (objectType == 31) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 objectType = 32 + (unsigned) r.read(6);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 return objectType;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 const char * packet_decoder_aac_common::objectTypeStr( unsigned ot ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 switch(ot) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 case 1: return "Main";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 case 2: return "LC";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 case 3: return "SSR";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 case 4: return "LTP";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 case 5: return "SBR";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 case 23: return "LD";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 case 39: return "ELD";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 case 42:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 case 45:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 return "USAC";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 return nullptr; // unknown
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 const char * packet_decoder_aac_common::audioSpecificConfig_t::objectTypeStr() const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 return packet_decoder_aac_common::objectTypeStr( this->m_objectType );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 pfc::array_t<uint8_t> packet_decoder_aac_common::buildASC(audioSpecificConfig_t const& arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 pfc::array_t<uint8_t> ret; ret.resize(5); memset(ret.get_ptr(), 0, ret.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 unsigned pos = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 auto write = [&](unsigned v, unsigned bits) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 bitreader_helper::write_int(ret.get_ptr(), pos, bits, v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 pos += bits;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 if (arg.m_objectType < 32) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 write(arg.m_objectType, 5);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 write(31, 5);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 write(arg.m_objectType - 32, 6);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 bool stdRate = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 for (unsigned i = 0; i < std::size(aac_sample_rates); ++i) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 if (arg.m_sampleRate == aac_sample_rates[i]) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 write(i, 4);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 stdRate = true; break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 if (!stdRate) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 write(arg.m_sampleRate, 24);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 write(arg.m_channels, 4);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 ret.set_size((pos + 7) / 8);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 pfc::array_t<uint8_t> packet_decoder_aac_common::buildSafeASC(unsigned rate) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 if (rate == 0) rate = 44100;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 audioSpecificConfig_t info = {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 info.m_sampleRate = rate;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 info.m_objectType = 1; // 1 = main, 2 = LC
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 info.m_channels = 2; // stereo
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 return buildASC(info);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 }