blob: af6b0b9bd3f915a178905feb4f62cf0817a9399f
1 | #include <stdio.h> |
2 | #include <intreadwrite.h> |
3 | #include "adec-armdec-mgt.h" |
4 | #include "audio-dec.h" |
5 | #include "amports/aformat.h" |
6 | #include <android/log.h> |
7 | #include <sys/time.h> |
8 | #include <stdint.h> |
9 | |
10 | #define LOG_TAG "PcmDecoder" |
11 | #define PRINTF(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) |
12 | |
13 | /* Audio channel masks */ |
14 | #define CH_FRONT_LEFT 0x00000001 |
15 | #define CH_FRONT_RIGHT 0x00000002 |
16 | #define CH_FRONT_CENTER 0x00000004 |
17 | #define CH_LOW_FREQUENCY 0x00000008 |
18 | #define CH_BACK_LEFT 0x00000010 |
19 | #define CH_BACK_RIGHT 0x00000020 |
20 | #define CH_FRONT_LEFT_OF_CENTER 0x00000040 |
21 | #define CH_FRONT_RIGHT_OF_CENTER 0x00000080 |
22 | #define CH_BACK_CENTER 0x00000100 |
23 | #define CH_SIDE_LEFT 0x00000200 |
24 | #define CH_SIDE_RIGHT 0x00000400 |
25 | #define CH_TOP_CENTER 0x00000800 |
26 | #define CH_TOP_FRONT_LEFT 0x00001000 |
27 | #define CH_TOP_FRONT_CENTER 0x00002000 |
28 | #define CH_TOP_FRONT_RIGHT 0x00004000 |
29 | #define CH_TOP_BACK_LEFT 0x00008000 |
30 | #define CH_TOP_BACK_CENTER 0x00010000 |
31 | #define CH_TOP_BACK_RIGHT 0x00020000 |
32 | #define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. |
33 | #define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT. |
34 | /* Audio channel convenience macros */ |
35 | #define CH_LAYOUT_MONO (CH_FRONT_CENTER) |
36 | #define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT) |
37 | #define CH_LAYOUT_2_1 (CH_LAYOUT_STEREO|CH_BACK_CENTER) |
38 | #define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER) |
39 | #define CH_LAYOUT_4POINT0 (CH_LAYOUT_SURROUND|CH_BACK_CENTER) |
40 | #define CH_LAYOUT_2_2 (CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT) |
41 | #define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT) |
42 | #define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT) |
43 | #define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY) |
44 | #define CH_LAYOUT_5POINT0_BACK (CH_LAYOUT_SURROUND|CH_BACK_LEFT|CH_BACK_RIGHT) |
45 | #define CH_LAYOUT_5POINT1_BACK (CH_LAYOUT_5POINT0_BACK|CH_LOW_FREQUENCY) |
46 | #define CH_LAYOUT_7POINT0 (CH_LAYOUT_5POINT0|CH_BACK_LEFT|CH_BACK_RIGHT) |
47 | #define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT) |
48 | #define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_5POINT1_BACK|CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER) |
49 | #define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT) |
50 | |
51 | #define CHECK_BLUERAY_PCM_HEADER |
52 | #define pcm_buffer_size (1024*6) |
53 | #define bluray_pcm_size (1024*17) |
54 | #define LOCAL inline |
55 | #define SIGN_BIT (0x80) |
56 | #define QUANT_MASK (0xf) |
57 | #define NSEGS (8) |
58 | #define SEG_SHIFT (4) |
59 | #define SEG_MASK (0x70) |
60 | #define BIAS (0x84) |
61 | static short table[256]; |
62 | |
63 | typedef struct { |
64 | int ValidDataLen; |
65 | int UsedDataLen; |
66 | unsigned char *BufStart; |
67 | unsigned char *pcur; |
68 | } pcm_read_ctl_t; |
69 | |
70 | typedef struct { |
71 | int pcm_channels; |
72 | int pcm_samplerate; |
73 | int bit_per_sample; |
74 | int jump_read_head_flag; |
75 | int frame_size_check; |
76 | int frame_size_check_flag; |
77 | int pcm_bluray_header; |
78 | int pcm_bluray_size; |
79 | unsigned char *pcm_buffer; |
80 | int lpcm_header_parsed; |
81 | int BlurayHeaderCheckDisable; |
82 | } pcm_priv_data_t; |
83 | |
84 | static int pcm_read_init(pcm_read_ctl_t *pcm_read_ctx, unsigned char* inbuf, int size) |
85 | { |
86 | pcm_read_ctx->ValidDataLen = size; |
87 | pcm_read_ctx->UsedDataLen = 0; |
88 | pcm_read_ctx->BufStart = inbuf; |
89 | pcm_read_ctx->pcur = inbuf; |
90 | return 0; |
91 | } |
92 | |
93 | static int pcm_read(pcm_read_ctl_t *pcm_read_ctx, unsigned char* outbuf, int size) |
94 | { |
95 | int bytes_read = 0; |
96 | if (size <= pcm_read_ctx->ValidDataLen) { |
97 | memcpy(outbuf, pcm_read_ctx->pcur, size); |
98 | pcm_read_ctx->ValidDataLen -= size; |
99 | pcm_read_ctx->UsedDataLen += size; |
100 | pcm_read_ctx->pcur += size; |
101 | bytes_read = size; |
102 | } |
103 | return bytes_read; |
104 | } |
105 | |
106 | static int av_get_bits_per_sample(int codec_id) |
107 | { |
108 | switch (codec_id) { |
109 | case AFORMAT_ALAW: |
110 | case AFORMAT_MULAW: |
111 | case AFORMAT_PCM_U8: |
112 | return 8; |
113 | case AFORMAT_PCM_S16BE: |
114 | case AFORMAT_PCM_S16LE: |
115 | return 16; |
116 | default: |
117 | return 0; |
118 | } |
119 | } |
120 | |
121 | static int alaw2linear(unsigned char a_val) |
122 | { |
123 | int t; |
124 | int seg; |
125 | a_val ^= 0x55; |
126 | t = a_val & QUANT_MASK; |
127 | seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; |
128 | if (seg) { |
129 | t = (t + t + 1 + 32) << (seg + 2); |
130 | } else { |
131 | t = (t + t + 1) << 3; |
132 | } |
133 | return (a_val & SIGN_BIT) ? t : -t; |
134 | } |
135 | |
136 | static int ulaw2linear(unsigned char u_val) |
137 | { |
138 | int t; |
139 | u_val = ~u_val; |
140 | t = ((u_val & QUANT_MASK) << 3) + BIAS; |
141 | t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; |
142 | return (u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS); |
143 | } |
144 | |
145 | /** |
146 | * Parse the header of a LPCM frame read from a MPEG-TS stream |
147 | * @param avctx the codec context |
148 | * @param header pointer to the first four bytes of the data packet |
149 | */ |
150 | static int pcm_bluray_pheader(pcm_read_ctl_t *pcm_read_ctl, aml_audio_dec_t *audec, char *header, int *bps) |
151 | { |
152 | audio_decoder_operations_t *adec_ops = (audio_decoder_operations_t *)audec->adec_ops; |
153 | pcm_priv_data_t *pPcm_priv_data = (pcm_priv_data_t *)adec_ops->priv_dec_data; |
154 | |
155 | uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; |
156 | uint32_t channel_layouts[16] = { |
157 | 0, CH_LAYOUT_MONO, 0, CH_LAYOUT_STEREO, CH_LAYOUT_SURROUND, |
158 | CH_LAYOUT_2_1, CH_LAYOUT_4POINT0, CH_LAYOUT_2_2, CH_LAYOUT_5POINT0, |
159 | CH_LAYOUT_5POINT1, CH_LAYOUT_7POINT0, CH_LAYOUT_7POINT1, 0, 0, 0, 0 |
160 | }; |
161 | uint8_t channels[16] = { |
162 | 0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0 |
163 | }; |
164 | int frame_size = header[0] << 8 | header[1]; |
165 | uint8_t channel_layout = header[2] >> 4; |
166 | int frame_header = header[0] << 24 | header[1] << 16 | header[2] << 8 | header[3]; |
167 | |
168 | if (frame_header != pPcm_priv_data->pcm_bluray_header) { |
169 | PRINTF("[%s %d]NOTE:pcm_bluray_header: header = %02x%02x%02x%02x\n", __FUNCTION__, __LINE__, header[0], header[1], header[2], header[3]); |
170 | pPcm_priv_data->pcm_bluray_header = frame_header; |
171 | } |
172 | if (frame_size != pPcm_priv_data->pcm_bluray_size) { |
173 | PRINTF("[%s %d]bluray pcm frame size is %d\n", __FUNCTION__, __LINE__, frame_size); |
174 | pPcm_priv_data->pcm_bluray_size = frame_size; |
175 | } |
176 | |
177 | /* get the sample depth and derive the sample format from it */ |
178 | *bps = bits_per_samples[header[3] >> 6]; |
179 | if (*bps == 0) { |
180 | PRINTF("[%s %d]unsupported sample datawitth (0)\n", __FUNCTION__, __LINE__); |
181 | return -1; |
182 | } |
183 | |
184 | /* get the sample rate. Not all values are known or exist. */ |
185 | switch (header[2] & 0x0f) { |
186 | case 1: |
187 | pPcm_priv_data->pcm_samplerate = 48000; |
188 | break; |
189 | case 4: |
190 | pPcm_priv_data->pcm_samplerate = 96000; |
191 | break; |
192 | case 5: |
193 | pPcm_priv_data->pcm_samplerate = 192000; |
194 | break; |
195 | default: |
196 | pPcm_priv_data->pcm_samplerate = 0; |
197 | PRINTF("[%s %d]unsupported sample rate (%d)\n", __FUNCTION__, __LINE__, header[2] & 0x0f); |
198 | return -1; |
199 | } |
200 | |
201 | /* |
202 | * get the channel number (and mapping). Not all values are known or exist. |
203 | * It must be noted that the number of channels in the MPEG stream can |
204 | * differ from the actual meaningful number, e.g. mono audio still has two |
205 | * channels, one being empty. |
206 | */ |
207 | //avctx->channel_layout = channel_layouts[channel_layout]; |
208 | pPcm_priv_data->pcm_channels = channels[channel_layout]; |
209 | if (!pPcm_priv_data->pcm_channels) { |
210 | PRINTF("[%s %d]unsupported channel configuration (%d)\n", __FUNCTION__, __LINE__, channel_layout); |
211 | return -1; |
212 | } |
213 | return frame_size; |
214 | } |
215 | |
216 | |
217 | #define Emphasis_Off 0 |
218 | #define Emphasis_On 1 |
219 | #define Quantization_Word_16bit 0 |
220 | #define Quantization_Word_Reserved 0xff |
221 | #define Audio_Sampling_44_1 1 |
222 | #define Audio_Sampling_48 2 |
223 | #define Audio_Sampling_Reserved 0xff |
224 | #define Audio_channel_Dual_Mono 0 |
225 | #define Audio_channel_Stero 1 |
226 | #define Audio_channel_Reserved 0xff |
227 | #define FramesPerAU 80 //according to spec of wifi display |
228 | #define Wifi_Display_Private_Header_Size 4 |
229 | |
230 | |
231 | static int parse_wifi_display_pcm_header(aml_audio_dec_t *audec, char *header, int *bps) |
232 | { |
233 | char number_of_frame_header, audio_emphasis, quant, sample, channel; |
234 | int frame_size = -1; |
235 | audio_decoder_operations_t *adec_ops = (audio_decoder_operations_t *)audec->adec_ops; |
236 | pcm_priv_data_t *pPcm_priv_data = (pcm_priv_data_t *)adec_ops->priv_dec_data; |
237 | //check sub id |
238 | if (header[0] == 0xa0) { |
239 | number_of_frame_header = header[1]; |
240 | audio_emphasis = header[2] & 1; |
241 | quant = header[3] >> 6; |
242 | sample = (header[3] >> 3) & 7; |
243 | channel = header[3] & 7; |
244 | |
245 | if (quant == Quantization_Word_16bit) { |
246 | *bps = 16; |
247 | } else { |
248 | PRINTF("[%s %d]using reserved bps %d\n", __FUNCTION__, __LINE__, *bps); |
249 | } |
250 | |
251 | if (sample == Audio_Sampling_44_1) { |
252 | pPcm_priv_data->pcm_samplerate = 44100; |
253 | } else if (sample == Audio_Sampling_48) { |
254 | pPcm_priv_data->pcm_samplerate = 48000; |
255 | } else { |
256 | PRINTF("[%s %d]using reserved sample_rate %d\n", __FUNCTION__, __LINE__, audec->samplerate); |
257 | pPcm_priv_data->pcm_samplerate = audec->samplerate; |
258 | } |
259 | |
260 | if (channel == Audio_channel_Dual_Mono) { |
261 | pPcm_priv_data->pcm_channels = 1; //note: this is not sure |
262 | } else if (channel == Audio_channel_Stero) { |
263 | pPcm_priv_data->pcm_channels = 2; |
264 | } else { |
265 | PRINTF("using reserved channel %d\n", audec->channels); |
266 | pPcm_priv_data->pcm_channels = audec->channels; |
267 | } |
268 | pPcm_priv_data->lpcm_header_parsed = 1; |
269 | |
270 | frame_size = FramesPerAU * (*bps >> 3) * audec->channels * number_of_frame_header; |
271 | } else { |
272 | PRINTF("[%s %d]unknown sub id\n", __FUNCTION__, __LINE__); |
273 | } |
274 | |
275 | return frame_size; |
276 | } |
277 | /** |
278 | * Read PCM samples macro |
279 | * @param type Datatype of native machine format |
280 | * @param endian bytestream_get_xxx() endian suffix |
281 | * @param src Source pointer (variable name) |
282 | * @param dst Destination pointer (variable name) |
283 | * @param n Total number of samples (variable name) |
284 | * @param shift Bitshift (bits) |
285 | * @param offset Sample value offset |
286 | */ |
287 | #define DEF_T(type, name, bytes, read, write) \ |
288 | static type bytestream_get_ ## name(const uint8_t **b){\ |
289 | (*b) += bytes;\ |
290 | return read(*b - bytes);\ |
291 | }\ |
292 | static void bytestream_put_ ##name(uint8_t **b, const type value){\ |
293 | write(*b, value);\ |
294 | (*b) += bytes;\ |
295 | } |
296 | #define DEF(name, bytes, read, write) DEF_T(unsigned int, name, bytes, read, write) |
297 | |
298 | |
299 | DEF(le32, 4, AV_RL32, AV_WL32) |
300 | DEF(le24, 3, AV_RL24, AV_WL24) |
301 | DEF(le16, 2, AV_RL16, AV_WL16) |
302 | DEF(be32, 4, AV_RB32, AV_WB32) |
303 | DEF(be24, 3, AV_RB24, AV_WB24) |
304 | DEF(be16, 2, AV_RB16, AV_WB16) |
305 | DEF(byte, 1, AV_RB8 , AV_WB8) |
306 | |
307 | #define DECODE(type, endian, src, dst, n, shift, offset) \ |
308 | dst_##type = (type*)dst; \ |
309 | for(;n>0;n--) { \ |
310 | register type v = bytestream_get_##endian((const unsigned char**)&src); \ |
311 | *dst_##type++ = (v - offset) << shift; \ |
312 | } \ |
313 | dst = (short*)dst_##type; |
314 | |
315 | |
316 | static int pcm_init(aml_audio_dec_t *audec) |
317 | { |
318 | int i; |
319 | audio_decoder_operations_t *adec_ops = NULL; |
320 | pcm_priv_data_t *pPcm_priv_data = NULL; |
321 | |
322 | pPcm_priv_data = malloc(sizeof(pcm_priv_data_t)); |
323 | if (pPcm_priv_data == NULL) { |
324 | PRINTF("[%s %d]malloc memory failed!\n", __FUNCTION__, __LINE__); |
325 | return -1; |
326 | } |
327 | memset(pPcm_priv_data, 0, sizeof(pcm_priv_data_t)); |
328 | adec_ops = (audio_decoder_operations_t *)audec->adec_ops; |
329 | adec_ops->priv_dec_data = pPcm_priv_data; |
330 | adec_ops->nInBufSize = pcm_buffer_size; |
331 | adec_ops->nOutBufSize = 0; |
332 | pPcm_priv_data->pcm_buffer = malloc(bluray_pcm_size); |
333 | if (pPcm_priv_data->pcm_buffer == NULL) { |
334 | free(adec_ops->priv_dec_data); |
335 | adec_ops->priv_dec_data = NULL; |
336 | PRINTF("[%s %d]malloc memory failed!\n", __FUNCTION__, __LINE__); |
337 | return -1; |
338 | } |
339 | memset(pPcm_priv_data->pcm_buffer, 0, bluray_pcm_size); |
340 | |
341 | PRINTF("[%s]audec->format/%d adec_ops->samplerate/%d adec_ops->channels/%d\n", |
342 | __FUNCTION__, audec->format, adec_ops->samplerate, adec_ops->channels); |
343 | |
344 | pPcm_priv_data->pcm_samplerate = adec_ops->samplerate; |
345 | pPcm_priv_data->pcm_channels = adec_ops->channels; |
346 | if (audec->format == AFORMAT_PCM_BLURAY) { |
347 | pPcm_priv_data->pcm_bluray_size = 0; |
348 | pPcm_priv_data->pcm_bluray_header = 0; |
349 | pPcm_priv_data->frame_size_check = 0; |
350 | pPcm_priv_data->jump_read_head_flag = 0; |
351 | pPcm_priv_data->frame_size_check_flag = 1; |
352 | |
353 | #ifdef CHECK_BLUERAY_PCM_HEADER |
354 | pPcm_priv_data->frame_size_check_flag = 0; |
355 | if (/*!audec->extradata ||*/ audec->extradata_size != 4) { |
356 | free(pPcm_priv_data->pcm_buffer); |
357 | free(adec_ops->priv_dec_data); |
358 | adec_ops->priv_dec_data = NULL; |
359 | PRINTF("[%s %d] pcm_init failed: need extradata !\n", __FUNCTION__, __LINE__); |
360 | return -1; |
361 | } |
362 | memcpy(&pPcm_priv_data->pcm_bluray_header, audec->extradata, 4); |
363 | PRINTF("blueray frame 4 byte header[0x%x],[0x%x],[0x%x],[0x%x]\n", audec->extradata[0], audec->extradata[1], \ |
364 | audec->extradata[2], audec->extradata[3]); |
365 | #endif |
366 | |
367 | return 0; |
368 | } |
369 | |
370 | switch (audec->format) { |
371 | case AFORMAT_ALAW: |
372 | for (i = 0; i < 256; i++) { |
373 | table[i] = alaw2linear(i); |
374 | } |
375 | break; |
376 | case AFORMAT_MULAW: |
377 | for (i = 0; i < 256; i++) { |
378 | table[i] = ulaw2linear(i); |
379 | } |
380 | break; |
381 | default: |
382 | break; |
383 | } |
384 | return 0; |
385 | } |
386 | |
387 | #define CHECK_DATA_ENOUGH(Ctl,NeedBytes,UsedSetIfNo) { \ |
388 | if((Ctl)->ValidDataLen < (NeedBytes)){ \ |
389 | PRINTF("[%s %d]NOTE--> no enough data\n",__FUNCTION__,__LINE__);\ |
390 | (Ctl)->UsedDataLen-=(UsedSetIfNo); \ |
391 | return -1; \ |
392 | } \ |
393 | } |
394 | |
395 | |
396 | |
397 | static int check_frame_size(pcm_read_ctl_t *pcm_read_ctl, aml_audio_dec_t *audec , int *bps) |
398 | { |
399 | int index; |
400 | int find_header_cnt = 0, first_header_pos = -1; |
401 | int size ; |
402 | int header, frame_size; |
403 | int first_head_pos = 0; |
404 | audio_decoder_operations_t *adec_ops = (audio_decoder_operations_t *)audec->adec_ops; |
405 | pcm_priv_data_t *pPcm_priv_data = (pcm_priv_data_t *)adec_ops->priv_dec_data; |
406 | |
407 | CHECK_DATA_ENOUGH(pcm_read_ctl, 4, 0) |
408 | pcm_read(pcm_read_ctl, pPcm_priv_data->pcm_buffer, 4); |
409 | |
410 | index = 0; |
411 | while (1) { |
412 | header = (pPcm_priv_data->pcm_buffer[0] << 24) | (pPcm_priv_data->pcm_buffer[1] << 16) | \ |
413 | (pPcm_priv_data->pcm_buffer[2] << 8) | (pPcm_priv_data->pcm_buffer[3]); |
414 | if (header == pPcm_priv_data->pcm_bluray_header) { |
415 | break; |
416 | } |
417 | pPcm_priv_data->pcm_buffer[0] = pPcm_priv_data->pcm_buffer[1]; |
418 | pPcm_priv_data->pcm_buffer[1] = pPcm_priv_data->pcm_buffer[2]; |
419 | pPcm_priv_data->pcm_buffer[2] = pPcm_priv_data->pcm_buffer[3]; |
420 | CHECK_DATA_ENOUGH(pcm_read_ctl, 1, 3) |
421 | pcm_read(pcm_read_ctl, &pPcm_priv_data->pcm_buffer[3], 1); |
422 | index++; |
423 | } |
424 | |
425 | first_head_pos = pcm_read_ctl->UsedDataLen - 4; |
426 | PRINTF("[%s %d]First BluRay Header offset=%d\n", __FUNCTION__, __LINE__, first_head_pos); |
427 | //--------------------------------------------- |
428 | frame_size = pcm_bluray_pheader(pcm_read_ctl, audec, pPcm_priv_data->pcm_buffer, bps); |
429 | if (frame_size > 0) { |
430 | PRINTF("[%s %d]frame_size from parser:%d\n", __FUNCTION__, __LINE__, frame_size); |
431 | CHECK_DATA_ENOUGH(pcm_read_ctl, frame_size, 4); |
432 | |
433 | } else { |
434 | PRINTF("[%s %d]ERR: invalid frame_size from parser:%d\n", __FUNCTION__, __LINE__, frame_size); |
435 | pPcm_priv_data->frame_size_check_flag = 1; |
436 | return -1; |
437 | } |
438 | |
439 | index = 1; |
440 | if (!pcm_read(pcm_read_ctl, &pPcm_priv_data->pcm_buffer[4], 1)) { |
441 | PRINTF("[%s %d]NOTE--> no enough data\n", __FUNCTION__, __LINE__); |
442 | pcm_read_ctl->UsedDataLen = first_head_pos; |
443 | return -1; |
444 | } |
445 | |
446 | while (1) { |
447 | if (index + 3 == bluray_pcm_size) { |
448 | PRINTF("[%s %d]ExtraData(First Bluray FrmHeader)May be Broken,used Unchecked Mode..\n", __FUNCTION__, __LINE__); |
449 | pcm_read_ctl->UsedDataLen = first_head_pos; |
450 | pPcm_priv_data->frame_size_check_flag = 1; |
451 | pPcm_priv_data->jump_read_head_flag = 0; |
452 | pPcm_priv_data->frame_size_check = frame_size; |
453 | pPcm_priv_data->BlurayHeaderCheckDisable = 1; |
454 | return -1; |
455 | } |
456 | header = (pPcm_priv_data->pcm_buffer[index] << 24) | (pPcm_priv_data->pcm_buffer[index + 1] << 16) | \ |
457 | (pPcm_priv_data->pcm_buffer[index + 2] << 8) | (pPcm_priv_data->pcm_buffer[index + 3]); |
458 | if (header == pPcm_priv_data->pcm_bluray_header) { |
459 | pPcm_priv_data->frame_size_check_flag = 1; |
460 | pPcm_priv_data->frame_size_check = index - 4; |
461 | pPcm_priv_data->jump_read_head_flag = 1; |
462 | PRINTF("frame_size_check=%d\n", pPcm_priv_data->frame_size_check); |
463 | break; |
464 | } |
465 | |
466 | if (!pcm_read(pcm_read_ctl, &pPcm_priv_data->pcm_buffer[index + 4], 1)) { |
467 | PRINTF("[%s %d]NOTE--> no enough data\n", __FUNCTION__, __LINE__); |
468 | pcm_read_ctl->UsedDataLen = first_head_pos; |
469 | return -1; |
470 | } |
471 | index++; |
472 | } |
473 | |
474 | |
475 | memmove(pPcm_priv_data->pcm_buffer, &pPcm_priv_data->pcm_buffer[4], pPcm_priv_data->frame_size_check); |
476 | if (frame_size != pPcm_priv_data->frame_size_check) { |
477 | PRINTF("[%s %d]WARNING-->STREAM_ERR:frame_size!=frame_size_check %d/%d\n ", |
478 | __FUNCTION__, __LINE__, frame_size, pPcm_priv_data->frame_size_check); |
479 | frame_size = pPcm_priv_data->frame_size_check; |
480 | } |
481 | return frame_size; |
482 | |
483 | } |
484 | |
485 | static inline int16_t av_clip_int16(int a) |
486 | { |
487 | if ((a + 32768) & ~65535) { |
488 | return (a >> 31) ^ 32767; |
489 | } else { |
490 | return a; |
491 | } |
492 | } |
493 | |
494 | static int pcm_decode_frame(pcm_read_ctl_t *pcm_read_ctl, unsigned char *buf, int len, aml_audio_dec_t *audec) |
495 | { |
496 | short *sample; |
497 | unsigned char *src; |
498 | int size = 0, n, i, j, bps = 16, wifi_display_drop_header = 0; |
499 | int sample_size; |
500 | unsigned int header; |
501 | int16_t *dst_int16_t; |
502 | int32_t *dst_int32_t; |
503 | int64_t *dst_int64_t; |
504 | uint16_t *dst_uint16_t; |
505 | uint32_t *dst_uint32_t; |
506 | int frame_size; |
507 | audio_decoder_operations_t *adec_ops = (audio_decoder_operations_t *)audec->adec_ops; |
508 | pcm_priv_data_t *pPcm_priv_data = (pcm_priv_data_t *)adec_ops->priv_dec_data; |
509 | |
510 | sample = (short *)buf; |
511 | src = pPcm_priv_data->pcm_buffer; |
512 | |
513 | if (audec->format == AFORMAT_PCM_BLURAY) { |
514 | int i, j; |
515 | int tmp_buf[10] = {0}; |
516 | if (!pPcm_priv_data->frame_size_check_flag) { |
517 | frame_size = check_frame_size(pcm_read_ctl, audec, &bps); |
518 | if (frame_size < 0) { |
519 | return 0; |
520 | } |
521 | if (bps > 0) { |
522 | pPcm_priv_data->bit_per_sample = bps; |
523 | } |
524 | } else { |
525 | if (pPcm_priv_data->jump_read_head_flag == 1) { |
526 | frame_size = pPcm_priv_data->frame_size_check; |
527 | pPcm_priv_data->jump_read_head_flag = 0; |
528 | } else if (pPcm_priv_data->jump_read_head_flag == 0) { |
529 | |
530 | #ifdef CHECK_BLUERAY_PCM_HEADER |
531 | if (pcm_read(pcm_read_ctl, pPcm_priv_data->pcm_buffer, 4) == 0) { |
532 | return 0; |
533 | } |
534 | while (!pPcm_priv_data->BlurayHeaderCheckDisable) { |
535 | header = (pPcm_priv_data->pcm_buffer[0] << 24) | (pPcm_priv_data->pcm_buffer[1] << 16) | \ |
536 | (pPcm_priv_data->pcm_buffer[2] << 8) | (pPcm_priv_data->pcm_buffer[3]); |
537 | if (header == pPcm_priv_data->pcm_bluray_header) { |
538 | break; |
539 | } |
540 | pPcm_priv_data->pcm_buffer[0] = pPcm_priv_data->pcm_buffer[1]; |
541 | pPcm_priv_data->pcm_buffer[1] = pPcm_priv_data->pcm_buffer[2]; |
542 | pPcm_priv_data->pcm_buffer[2] = pPcm_priv_data->pcm_buffer[3]; |
543 | if (!pcm_read(pcm_read_ctl, &pPcm_priv_data->pcm_buffer[3], 1)) { |
544 | pcm_read_ctl->UsedDataLen -= 3; |
545 | return 0; |
546 | } |
547 | } |
548 | #else |
549 | if (!pcm_read(pcm_read_ctl, pPcm_priv_data->pcm_buffer, 4)) { |
550 | return 0; |
551 | } |
552 | #endif |
553 | |
554 | frame_size = pcm_bluray_pheader(pPcm_priv_data, audec, pPcm_priv_data->pcm_buffer, &bps); |
555 | pPcm_priv_data->bit_per_sample = bps; |
556 | if (frame_size < 960 || frame_size > 17280) { |
557 | PRINTF("STREAM_ERR:illegal blueray frame size \n"); |
558 | return 0; |
559 | } |
560 | |
561 | #ifdef CHECK_BLUERAY_PCM_HEADER |
562 | if (frame_size != pPcm_priv_data->frame_size_check && !pPcm_priv_data->BlurayHeaderCheckDisable) { |
563 | frame_size = pPcm_priv_data->frame_size_check; |
564 | } |
565 | #endif |
566 | |
567 | } |
568 | if (bps > 0) { |
569 | pPcm_priv_data->bit_per_sample = bps; |
570 | } |
571 | |
572 | if (!pcm_read(pcm_read_ctl, pPcm_priv_data->pcm_buffer, frame_size)) { |
573 | pcm_read_ctl->UsedDataLen -= 4; |
574 | return 0; |
575 | } |
576 | } |
577 | |
578 | if (pPcm_priv_data->bit_per_sample == 16) { |
579 | if (pPcm_priv_data->pcm_channels == 1) { |
580 | for (i = 0, j = 0; i < frame_size;) { |
581 | sample[j + 1] = sample[j] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
582 | i += 2; |
583 | j += 2; |
584 | } |
585 | } else if (pPcm_priv_data->pcm_channels == 2) { |
586 | for (i = 0, j = 0; i < frame_size;) { |
587 | sample[j++] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
588 | i += 2; |
589 | sample[j++] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
590 | i += 2; |
591 | } |
592 | } else if (pPcm_priv_data->pcm_channels > 2 && pPcm_priv_data->pcm_channels <= 8) { |
593 | int k; |
594 | memset(tmp_buf, 0, sizeof(tmp_buf)); |
595 | for (i = 0, j = 0; i < frame_size;) { |
596 | for (k = 0; k < pPcm_priv_data->pcm_channels; k++) { |
597 | tmp_buf[k] = (int16_t)((pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]); |
598 | i += 2; |
599 | } |
600 | //LoRo downmix:L R C Ls Rs LFE Lsr Rsr |
601 | sample[j++] = av_clip_int16(tmp_buf[0] + 0.707f * tmp_buf[2] + 0.707f * (tmp_buf[3] + tmp_buf[6])); //Lo=L+0.707C+0.707 (Ls+Lsr) |
602 | sample[j++] = av_clip_int16(tmp_buf[1] + 0.707f * tmp_buf[2] + 0.707f * (tmp_buf[4] + tmp_buf[7])); //Ro=R+0.707C+0.707(Rs+Rsr) |
603 | } |
604 | } |
605 | } else if (pPcm_priv_data->bit_per_sample == 24 || pPcm_priv_data->bit_per_sample == 20) { |
606 | int k; |
607 | memset(tmp_buf, 0, sizeof(tmp_buf)); |
608 | if (pPcm_priv_data->pcm_channels == 1) { |
609 | for (i = 0, j = 0; i < frame_size;) { |
610 | sample[j++] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
611 | i += 3; |
612 | } |
613 | } else if (pPcm_priv_data->pcm_channels == 2) { |
614 | for (i = 0, j = 0; i < frame_size;) { |
615 | sample[j++] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
616 | i += 3; |
617 | sample[j++] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
618 | i += 3; |
619 | } |
620 | } else if (pPcm_priv_data->pcm_channels >= 2 && pPcm_priv_data->pcm_channels <= 8) { |
621 | int k; |
622 | memset(tmp_buf, 0, sizeof(tmp_buf)); |
623 | for (i = 0, j = 0; i < frame_size;) { |
624 | for (k = 0; k < pPcm_priv_data->pcm_channels; k++) { |
625 | tmp_buf[k] = (int16_t)(pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
626 | i += 3; |
627 | } |
628 | //LoRo downmix:L R C Ls Rs LFE Lsr Rsr |
629 | sample[j++] = av_clip_int16(tmp_buf[0] + 0.707f * tmp_buf[2] + 0.707f * (tmp_buf[3] + tmp_buf[6])); //Lo=L+0.707C+0.707 (Ls+Lsr) |
630 | sample[j++] = av_clip_int16(tmp_buf[1] + 0.707f * tmp_buf[2] + 0.707f * (tmp_buf[4] + tmp_buf[7])); //Ro=R+0.707C+0.707(Rs+Rsr) |
631 | } |
632 | } |
633 | } else { |
634 | PRINTF("[%s %d]blueray pcm is %d bps, don't process now\n", __FUNCTION__, __LINE__, pPcm_priv_data->bit_per_sample); |
635 | return 0; |
636 | } |
637 | return j * 2; |
638 | } else if (audec->format == AFORMAT_PCM_WIFIDISPLAY) { |
639 | //check audio info for wifi display LPCM, by zefeng.tong@amlogic.com |
640 | if (!pcm_read(pcm_read_ctl, pPcm_priv_data->pcm_buffer, Wifi_Display_Private_Header_Size)) { |
641 | return 0; |
642 | } |
643 | |
644 | if (pPcm_priv_data->pcm_buffer[0] == 0xa0) { |
645 | frame_size = parse_wifi_display_pcm_header(audec, pPcm_priv_data->pcm_buffer, &bps); |
646 | if (!pcm_read(pcm_read_ctl, pPcm_priv_data->pcm_buffer, frame_size)) { |
647 | pcm_read_ctl->UsedDataLen -= Wifi_Display_Private_Header_Size; |
648 | return -1; |
649 | } |
650 | pPcm_priv_data->bit_per_sample = bps; |
651 | } else { |
652 | frame_size = Wifi_Display_Private_Header_Size; //transimit error or something? |
653 | } |
654 | |
655 | if (pPcm_priv_data->bit_per_sample == 16) { |
656 | if (pPcm_priv_data->pcm_channels == 1) { |
657 | for (i = 0, j = 0; i < frame_size;) { |
658 | sample[j + 1] = sample[j] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
659 | i += 2; |
660 | j += 2; |
661 | } |
662 | } else if (pPcm_priv_data->pcm_channels == 2) { |
663 | for (i = 0, j = 0; i < frame_size;) { |
664 | sample[j++] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
665 | i += 2; |
666 | sample[j++] = (pPcm_priv_data->pcm_buffer[i] << 8) | pPcm_priv_data->pcm_buffer[i + 1]; |
667 | i += 2; |
668 | } |
669 | } |
670 | return frame_size; |
671 | } else { |
672 | PRINTF("[%s %d]wifi display:unimplemented bps %d\n", __FUNCTION__, __LINE__, bps); |
673 | } |
674 | |
675 | return 0; |
676 | } |
677 | |
678 | unsigned byte_to_read = pcm_buffer_size; |
679 | while (pcm_read_ctl->ValidDataLen < byte_to_read) { |
680 | byte_to_read = byte_to_read >> 1; |
681 | } |
682 | size = pcm_read(pcm_read_ctl, pPcm_priv_data->pcm_buffer, byte_to_read); |
683 | |
684 | sample_size = av_get_bits_per_sample(audec->format) / 8; |
685 | n = size / sample_size; |
686 | |
687 | switch (audec->format) { |
688 | case AFORMAT_ALAW: |
689 | case AFORMAT_MULAW: |
690 | for (; n > 0; n--) { |
691 | *sample++ = table[*src++]; |
692 | } |
693 | //dbuf.data_size = size *2; |
694 | size *= 2; |
695 | break; |
696 | |
697 | case AFORMAT_PCM_S16LE: { |
698 | int i, j; |
699 | short tmp_buf[10]; |
700 | short* p; |
701 | p = (short*)pPcm_priv_data->pcm_buffer; |
702 | if (pPcm_priv_data->pcm_channels == 6) { |
703 | for (i = 0, j = 0; (i + 6) < (size / 2);) { |
704 | *(tmp_buf) = p[i]; //L |
705 | *(tmp_buf + 1) = p[i + 1]; //R |
706 | *(tmp_buf + 2) = p[i + 2]; //C |
707 | i += 6; |
708 | |
709 | sample[j++] = (*(tmp_buf) >> 1) + (*(tmp_buf + 2) >> 1); |
710 | sample[j++] = (*(tmp_buf + 1) >> 1) + (*(tmp_buf + 2) >> 1); |
711 | } |
712 | size = 2 * j; |
713 | } else { |
714 | memcpy(sample, src, n * sample_size); |
715 | } |
716 | //dbuf.data_size = size; |
717 | |
718 | } |
719 | break; |
720 | |
721 | case AFORMAT_PCM_S16BE: |
722 | DECODE(int16_t, be16, src, sample, n, 0, 0) |
723 | break; |
724 | |
725 | case AFORMAT_PCM_U8: |
726 | for (; n > 0; n--) { |
727 | *sample++ = ((int) * src++ - 128) << 8; |
728 | } |
729 | //dbuf.data_size = size*2; |
730 | size *= 2; |
731 | break; |
732 | |
733 | default: |
734 | PRINTF("[%s %d]Not support format audec->format=%d!\n", __FUNCTION__, __LINE__, audec->format); |
735 | break; |
736 | } |
737 | |
738 | return size; |
739 | } |
740 | |
741 | |
742 | int audio_dec_init(audio_decoder_operations_t *adec_ops) |
743 | { |
744 | aml_audio_dec_t *audec = (aml_audio_dec_t *)(adec_ops->priv_data); |
745 | //PRINTF("\n\n[%s]BuildDate--%s BuildTime--%s", __FUNCTION__, __DATE__, __TIME__); |
746 | return pcm_init(audec); |
747 | |
748 | } |
749 | |
750 | int audio_dec_decode(audio_decoder_operations_t *adec_ops, char *outbuf, int *outlen, char *inbuf, int inlen) |
751 | { |
752 | aml_audio_dec_t *audec = (aml_audio_dec_t *)(adec_ops->priv_data); |
753 | pcm_read_ctl_t pcm_read_ctl = {0}; |
754 | pcm_read_init(&pcm_read_ctl, inbuf, inlen); |
755 | *outlen = pcm_decode_frame(&pcm_read_ctl, outbuf, *outlen, audec); |
756 | return pcm_read_ctl.UsedDataLen; |
757 | |
758 | } |
759 | |
760 | int audio_dec_release(audio_decoder_operations_t *adec_ops) |
761 | { |
762 | pcm_priv_data_t *pPcm_priv_data = (pcm_priv_data_t *)adec_ops->priv_dec_data; |
763 | if (pPcm_priv_data != NULL && pPcm_priv_data->pcm_buffer) { |
764 | free(pPcm_priv_data->pcm_buffer); |
765 | free(pPcm_priv_data); |
766 | } |
767 | adec_ops->priv_dec_data = NULL; |
768 | return 0; |
769 | } |
770 | |
771 | int audio_dec_getinfo(audio_decoder_operations_t *adec_ops, void *pAudioInfo) |
772 | { |
773 | pcm_priv_data_t *pPcm_priv_data = (pcm_priv_data_t *)adec_ops->priv_dec_data; |
774 | ((AudioInfo *)pAudioInfo)->channels = pPcm_priv_data->pcm_channels > 2 ? 2 : pPcm_priv_data->pcm_channels; |
775 | ((AudioInfo *)pAudioInfo)->samplerate = pPcm_priv_data->pcm_samplerate; |
776 | return 0; |
777 | } |
778 | |
779 | |
780 | |
781 |