blob: b822868b132a561f3d6ec8065ea501d241e93dea [file] [log] [blame]
Andreas Huber85f12e92010-08-19 10:39:47 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber5bc087c2010-12-23 10:27:40 -080017//#define LOG_NDEBUG 0
18#define LOG_TAG "avc_utils"
19#include <utils/Log.h>
20
Andreas Huber85f12e92010-08-19 10:39:47 -070021#include "include/avc_utils.h"
22
23#include <media/stagefright/foundation/ABitReader.h>
24#include <media/stagefright/foundation/ADebug.h>
Andreas Hubere9810fa2012-12-03 15:20:40 -080025#include <media/stagefright/foundation/hexdump.h>
Andreas Huberc68a48c2010-10-08 12:06:27 -070026#include <media/stagefright/MediaDefs.h>
27#include <media/stagefright/MediaErrors.h>
28#include <media/stagefright/MetaData.h>
Andreas Huber85f12e92010-08-19 10:39:47 -070029
30namespace android {
31
Andreas Huber6a63a932010-10-01 10:51:41 -070032unsigned parseUE(ABitReader *br) {
Andreas Huber85f12e92010-08-19 10:39:47 -070033 unsigned numZeroes = 0;
34 while (br->getBits(1) == 0) {
35 ++numZeroes;
36 }
37
38 unsigned x = br->getBits(numZeroes);
39
40 return x + (1u << numZeroes) - 1;
41}
42
43// Determine video dimensions from the sequence parameterset.
44void FindAVCDimensions(
Andreas Hubere9810fa2012-12-03 15:20:40 -080045 const sp<ABuffer> &seqParamSet,
46 int32_t *width, int32_t *height,
47 int32_t *sarWidth, int32_t *sarHeight) {
Andreas Huber85f12e92010-08-19 10:39:47 -070048 ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1);
49
50 unsigned profile_idc = br.getBits(8);
51 br.skipBits(16);
52 parseUE(&br); // seq_parameter_set_id
53
Andreas Huber2d511ff2010-10-08 10:38:39 -070054 unsigned chroma_format_idc = 1; // 4:2:0 chroma format
55
Andreas Huber85f12e92010-08-19 10:39:47 -070056 if (profile_idc == 100 || profile_idc == 110
57 || profile_idc == 122 || profile_idc == 244
58 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) {
Andreas Huber2d511ff2010-10-08 10:38:39 -070059 chroma_format_idc = parseUE(&br);
Andreas Huber85f12e92010-08-19 10:39:47 -070060 if (chroma_format_idc == 3) {
61 br.skipBits(1); // residual_colour_transform_flag
62 }
63 parseUE(&br); // bit_depth_luma_minus8
64 parseUE(&br); // bit_depth_chroma_minus8
65 br.skipBits(1); // qpprime_y_zero_transform_bypass_flag
66 CHECK_EQ(br.getBits(1), 0u); // seq_scaling_matrix_present_flag
67 }
68
69 parseUE(&br); // log2_max_frame_num_minus4
70 unsigned pic_order_cnt_type = parseUE(&br);
71
72 if (pic_order_cnt_type == 0) {
73 parseUE(&br); // log2_max_pic_order_cnt_lsb_minus4
74 } else if (pic_order_cnt_type == 1) {
75 // offset_for_non_ref_pic, offset_for_top_to_bottom_field and
76 // offset_for_ref_frame are technically se(v), but since we are
77 // just skipping over them the midpoint does not matter.
78
79 br.getBits(1); // delta_pic_order_always_zero_flag
80 parseUE(&br); // offset_for_non_ref_pic
81 parseUE(&br); // offset_for_top_to_bottom_field
82
83 unsigned num_ref_frames_in_pic_order_cnt_cycle = parseUE(&br);
84 for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) {
85 parseUE(&br); // offset_for_ref_frame
86 }
87 }
88
89 parseUE(&br); // num_ref_frames
90 br.getBits(1); // gaps_in_frame_num_value_allowed_flag
91
92 unsigned pic_width_in_mbs_minus1 = parseUE(&br);
93 unsigned pic_height_in_map_units_minus1 = parseUE(&br);
94 unsigned frame_mbs_only_flag = br.getBits(1);
95
96 *width = pic_width_in_mbs_minus1 * 16 + 16;
97
98 *height = (2 - frame_mbs_only_flag)
99 * (pic_height_in_map_units_minus1 * 16 + 16);
Andreas Huber2d511ff2010-10-08 10:38:39 -0700100
101 if (!frame_mbs_only_flag) {
102 br.getBits(1); // mb_adaptive_frame_field_flag
103 }
104
105 br.getBits(1); // direct_8x8_inference_flag
106
107 if (br.getBits(1)) { // frame_cropping_flag
108 unsigned frame_crop_left_offset = parseUE(&br);
109 unsigned frame_crop_right_offset = parseUE(&br);
110 unsigned frame_crop_top_offset = parseUE(&br);
111 unsigned frame_crop_bottom_offset = parseUE(&br);
112
113 unsigned cropUnitX, cropUnitY;
114 if (chroma_format_idc == 0 /* monochrome */) {
115 cropUnitX = 1;
116 cropUnitY = 2 - frame_mbs_only_flag;
117 } else {
118 unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2;
119 unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1;
120
121 cropUnitX = subWidthC;
122 cropUnitY = subHeightC * (2 - frame_mbs_only_flag);
123 }
124
Steve Block3856b092011-10-20 11:56:00 +0100125 ALOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u",
Andreas Huber2d511ff2010-10-08 10:38:39 -0700126 frame_crop_left_offset, frame_crop_right_offset,
127 frame_crop_top_offset, frame_crop_bottom_offset,
128 cropUnitX, cropUnitY);
129
130 *width -=
131 (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX;
132 *height -=
133 (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY;
134 }
Andreas Hubere9810fa2012-12-03 15:20:40 -0800135
136 if (sarWidth != NULL) {
137 *sarWidth = 0;
138 }
139
140 if (sarHeight != NULL) {
141 *sarHeight = 0;
142 }
143
144 if (br.getBits(1)) { // vui_parameters_present_flag
145 unsigned sar_width = 0, sar_height = 0;
146
147 if (br.getBits(1)) { // aspect_ratio_info_present_flag
148 unsigned aspect_ratio_idc = br.getBits(8);
149
150 if (aspect_ratio_idc == 255 /* extendedSAR */) {
151 sar_width = br.getBits(16);
152 sar_height = br.getBits(16);
153 } else if (aspect_ratio_idc > 0 && aspect_ratio_idc < 14) {
154 static const int32_t kFixedSARWidth[] = {
155 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160
156 };
157
158 static const int32_t kFixedSARHeight[] = {
159 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99
160 };
161
162 sar_width = kFixedSARWidth[aspect_ratio_idc - 1];
163 sar_height = kFixedSARHeight[aspect_ratio_idc - 1];
164 }
165 }
166
167 ALOGV("sample aspect ratio = %u : %u", sar_width, sar_height);
168
169 if (sarWidth != NULL) {
170 *sarWidth = sar_width;
171 }
172
173 if (sarHeight != NULL) {
174 *sarHeight = sar_height;
175 }
176 }
Andreas Huber85f12e92010-08-19 10:39:47 -0700177}
178
Andreas Huberc68a48c2010-10-08 12:06:27 -0700179status_t getNextNALUnit(
180 const uint8_t **_data, size_t *_size,
181 const uint8_t **nalStart, size_t *nalSize,
182 bool startCodeFollows) {
183 const uint8_t *data = *_data;
184 size_t size = *_size;
185
186 *nalStart = NULL;
187 *nalSize = 0;
188
189 if (size == 0) {
190 return -EAGAIN;
191 }
192
193 // Skip any number of leading 0x00.
194
195 size_t offset = 0;
196 while (offset < size && data[offset] == 0x00) {
197 ++offset;
198 }
199
200 if (offset == size) {
201 return -EAGAIN;
202 }
203
204 // A valid startcode consists of at least two 0x00 bytes followed by 0x01.
205
206 if (offset < 2 || data[offset] != 0x01) {
207 return ERROR_MALFORMED;
208 }
209
210 ++offset;
211
212 size_t startOffset = offset;
213
214 for (;;) {
215 while (offset < size && data[offset] != 0x01) {
216 ++offset;
217 }
218
219 if (offset == size) {
220 if (startCodeFollows) {
221 offset = size + 2;
222 break;
223 }
224
225 return -EAGAIN;
226 }
227
228 if (data[offset - 1] == 0x00 && data[offset - 2] == 0x00) {
229 break;
230 }
231
232 ++offset;
233 }
234
235 size_t endOffset = offset - 2;
Andreas Huber7f048fd2011-08-01 13:22:26 -0700236 while (endOffset > startOffset + 1 && data[endOffset - 1] == 0x00) {
Andreas Huberc68a48c2010-10-08 12:06:27 -0700237 --endOffset;
238 }
239
240 *nalStart = &data[startOffset];
241 *nalSize = endOffset - startOffset;
242
243 if (offset + 2 < size) {
244 *_data = &data[offset - 2];
245 *_size = size - offset + 2;
246 } else {
247 *_data = NULL;
248 *_size = 0;
249 }
250
251 return OK;
252}
253
254static sp<ABuffer> FindNAL(
255 const uint8_t *data, size_t size, unsigned nalType,
256 size_t *stopOffset) {
257 const uint8_t *nalStart;
258 size_t nalSize;
259 while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
260 if ((nalStart[0] & 0x1f) == nalType) {
261 sp<ABuffer> buffer = new ABuffer(nalSize);
262 memcpy(buffer->data(), nalStart, nalSize);
263 return buffer;
264 }
265 }
266
267 return NULL;
268}
269
Andreas Huberbfd41f32010-11-15 09:01:13 -0800270const char *AVCProfileToString(uint8_t profile) {
271 switch (profile) {
272 case kAVCProfileBaseline:
273 return "Baseline";
274 case kAVCProfileMain:
275 return "Main";
276 case kAVCProfileExtended:
277 return "Extended";
278 case kAVCProfileHigh:
279 return "High";
280 case kAVCProfileHigh10:
281 return "High 10";
282 case kAVCProfileHigh422:
283 return "High 422";
284 case kAVCProfileHigh444:
285 return "High 444";
286 case kAVCProfileCAVLC444Intra:
287 return "CAVLC 444 Intra";
288 default: return "Unknown";
289 }
290}
291
Andreas Huberc68a48c2010-10-08 12:06:27 -0700292sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
293 const uint8_t *data = accessUnit->data();
294 size_t size = accessUnit->size();
295
296 sp<ABuffer> seqParamSet = FindNAL(data, size, 7, NULL);
297 if (seqParamSet == NULL) {
298 return NULL;
299 }
300
301 int32_t width, height;
Andreas Hubere9810fa2012-12-03 15:20:40 -0800302 int32_t sarWidth, sarHeight;
303 FindAVCDimensions(
304 seqParamSet, &width, &height, &sarWidth, &sarHeight);
Andreas Huberc68a48c2010-10-08 12:06:27 -0700305
306 size_t stopOffset;
307 sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
308 CHECK(picParamSet != NULL);
309
310 size_t csdSize =
311 1 + 3 + 1 + 1
312 + 2 * 1 + seqParamSet->size()
313 + 1 + 2 * 1 + picParamSet->size();
314
315 sp<ABuffer> csd = new ABuffer(csdSize);
316 uint8_t *out = csd->data();
317
318 *out++ = 0x01; // configurationVersion
319 memcpy(out, seqParamSet->data() + 1, 3); // profile/level...
Andreas Huberbfd41f32010-11-15 09:01:13 -0800320
321 uint8_t profile = out[0];
322 uint8_t level = out[2];
323
Andreas Huberc68a48c2010-10-08 12:06:27 -0700324 out += 3;
325 *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes
326 *out++ = 0xe0 | 1;
327
328 *out++ = seqParamSet->size() >> 8;
329 *out++ = seqParamSet->size() & 0xff;
330 memcpy(out, seqParamSet->data(), seqParamSet->size());
331 out += seqParamSet->size();
332
333 *out++ = 1;
334
335 *out++ = picParamSet->size() >> 8;
336 *out++ = picParamSet->size() & 0xff;
337 memcpy(out, picParamSet->data(), picParamSet->size());
338
339#if 0
Steve Blockdf64d152012-01-04 20:05:49 +0000340 ALOGI("AVC seq param set");
Andreas Huberc68a48c2010-10-08 12:06:27 -0700341 hexdump(seqParamSet->data(), seqParamSet->size());
342#endif
343
344 sp<MetaData> meta = new MetaData;
345 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
346
Andreas Huberc639aad2011-09-21 13:19:54 -0700347 meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
Andreas Huberc68a48c2010-10-08 12:06:27 -0700348 meta->setInt32(kKeyWidth, width);
349 meta->setInt32(kKeyHeight, height);
350
Andreas Hubere9810fa2012-12-03 15:20:40 -0800351 if (sarWidth > 1 || sarHeight > 1) {
352 // We treat 0:0 (unspecified) as 1:1.
353
354 meta->setInt32(kKeySARWidth, sarWidth);
355 meta->setInt32(kKeySARHeight, sarHeight);
356
357 ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d) "
358 "SAR %d : %d",
359 width,
360 height,
361 AVCProfileToString(profile),
362 level / 10,
363 level % 10,
364 sarWidth,
365 sarHeight);
366 } else {
367 ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)",
368 width,
369 height,
370 AVCProfileToString(profile),
371 level / 10,
372 level % 10);
373 }
Andreas Huberc68a48c2010-10-08 12:06:27 -0700374
375 return meta;
376}
377
378bool IsIDR(const sp<ABuffer> &buffer) {
379 const uint8_t *data = buffer->data();
380 size_t size = buffer->size();
381
382 bool foundIDR = false;
383
384 const uint8_t *nalStart;
385 size_t nalSize;
386 while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
387 CHECK_GT(nalSize, 0u);
388
389 unsigned nalType = nalStart[0] & 0x1f;
390
391 if (nalType == 5) {
392 foundIDR = true;
393 break;
394 }
395 }
396
397 return foundIDR;
398}
399
Andreas Huber3fe62152011-09-16 15:09:22 -0700400bool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit) {
401 const uint8_t *data = accessUnit->data();
402 size_t size = accessUnit->size();
403
404 const uint8_t *nalStart;
405 size_t nalSize;
406 while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
407 CHECK_GT(nalSize, 0u);
408
409 unsigned nalType = nalStart[0] & 0x1f;
410
411 if (nalType == 5) {
412 return true;
413 } else if (nalType == 1) {
414 unsigned nal_ref_idc = (nalStart[0] >> 5) & 3;
415 return nal_ref_idc != 0;
416 }
417 }
418
419 return true;
420}
421
Gloria Wang50c44c72011-02-02 14:12:49 -0800422sp<MetaData> MakeAACCodecSpecificData(
423 unsigned profile, unsigned sampling_freq_index,
424 unsigned channel_configuration) {
425 sp<MetaData> meta = new MetaData;
426 meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
427
428 CHECK_LE(sampling_freq_index, 11u);
429 static const int32_t kSamplingFreq[] = {
430 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
431 16000, 12000, 11025, 8000
432 };
433 meta->setInt32(kKeySampleRate, kSamplingFreq[sampling_freq_index]);
434 meta->setInt32(kKeyChannelCount, channel_configuration);
435
436 static const uint8_t kStaticESDS[] = {
437 0x03, 22,
438 0x00, 0x00, // ES_ID
439 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
440
441 0x04, 17,
442 0x40, // Audio ISO/IEC 14496-3
443 0x00, 0x00, 0x00, 0x00,
444 0x00, 0x00, 0x00, 0x00,
445 0x00, 0x00, 0x00, 0x00,
446
447 0x05, 2,
448 // AudioSpecificInfo follows
449
450 // oooo offf fccc c000
451 // o - audioObjectType
452 // f - samplingFreqIndex
453 // c - channelConfig
454 };
455 sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
456 memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
457
458 csd->data()[sizeof(kStaticESDS)] =
459 ((profile + 1) << 3) | (sampling_freq_index >> 1);
460
461 csd->data()[sizeof(kStaticESDS) + 1] =
462 ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
463
464 meta->setData(kKeyESDS, 0, csd->data(), csd->size());
465
466 return meta;
467}
468
Andreas Huber386d6092011-05-19 08:37:39 -0700469bool ExtractDimensionsFromVOLHeader(
470 const uint8_t *data, size_t size, int32_t *width, int32_t *height) {
471 ABitReader br(&data[4], size - 4);
472 br.skipBits(1); // random_accessible_vol
473 unsigned video_object_type_indication = br.getBits(8);
474
475 CHECK_NE(video_object_type_indication,
476 0x21u /* Fine Granularity Scalable */);
477
478 unsigned video_object_layer_verid;
479 unsigned video_object_layer_priority;
480 if (br.getBits(1)) {
481 video_object_layer_verid = br.getBits(4);
482 video_object_layer_priority = br.getBits(3);
483 }
484 unsigned aspect_ratio_info = br.getBits(4);
485 if (aspect_ratio_info == 0x0f /* extended PAR */) {
486 br.skipBits(8); // par_width
487 br.skipBits(8); // par_height
488 }
489 if (br.getBits(1)) { // vol_control_parameters
490 br.skipBits(2); // chroma_format
491 br.skipBits(1); // low_delay
492 if (br.getBits(1)) { // vbv_parameters
493 br.skipBits(15); // first_half_bit_rate
494 CHECK(br.getBits(1)); // marker_bit
495 br.skipBits(15); // latter_half_bit_rate
496 CHECK(br.getBits(1)); // marker_bit
497 br.skipBits(15); // first_half_vbv_buffer_size
498 CHECK(br.getBits(1)); // marker_bit
499 br.skipBits(3); // latter_half_vbv_buffer_size
500 br.skipBits(11); // first_half_vbv_occupancy
501 CHECK(br.getBits(1)); // marker_bit
502 br.skipBits(15); // latter_half_vbv_occupancy
503 CHECK(br.getBits(1)); // marker_bit
504 }
505 }
506 unsigned video_object_layer_shape = br.getBits(2);
507 CHECK_EQ(video_object_layer_shape, 0x00u /* rectangular */);
508
509 CHECK(br.getBits(1)); // marker_bit
510 unsigned vop_time_increment_resolution = br.getBits(16);
511 CHECK(br.getBits(1)); // marker_bit
512
513 if (br.getBits(1)) { // fixed_vop_rate
514 // range [0..vop_time_increment_resolution)
515
516 // vop_time_increment_resolution
517 // 2 => 0..1, 1 bit
518 // 3 => 0..2, 2 bits
519 // 4 => 0..3, 2 bits
520 // 5 => 0..4, 3 bits
521 // ...
522
523 CHECK_GT(vop_time_increment_resolution, 0u);
524 --vop_time_increment_resolution;
525
526 unsigned numBits = 0;
527 while (vop_time_increment_resolution > 0) {
528 ++numBits;
529 vop_time_increment_resolution >>= 1;
530 }
531
532 br.skipBits(numBits); // fixed_vop_time_increment
533 }
534
535 CHECK(br.getBits(1)); // marker_bit
536 unsigned video_object_layer_width = br.getBits(13);
537 CHECK(br.getBits(1)); // marker_bit
538 unsigned video_object_layer_height = br.getBits(13);
539 CHECK(br.getBits(1)); // marker_bit
540
541 unsigned interlaced = br.getBits(1);
542
543 *width = video_object_layer_width;
544 *height = video_object_layer_height;
545
546 return true;
547}
548
549bool GetMPEGAudioFrameSize(
550 uint32_t header, size_t *frame_size,
551 int *out_sampling_rate, int *out_channels,
552 int *out_bitrate, int *out_num_samples) {
553 *frame_size = 0;
554
555 if (out_sampling_rate) {
556 *out_sampling_rate = 0;
557 }
558
559 if (out_channels) {
560 *out_channels = 0;
561 }
562
563 if (out_bitrate) {
564 *out_bitrate = 0;
565 }
566
567 if (out_num_samples) {
568 *out_num_samples = 1152;
569 }
570
571 if ((header & 0xffe00000) != 0xffe00000) {
572 return false;
573 }
574
575 unsigned version = (header >> 19) & 3;
576
577 if (version == 0x01) {
578 return false;
579 }
580
581 unsigned layer = (header >> 17) & 3;
582
583 if (layer == 0x00) {
584 return false;
585 }
586
587 unsigned protection = (header >> 16) & 1;
588
589 unsigned bitrate_index = (header >> 12) & 0x0f;
590
591 if (bitrate_index == 0 || bitrate_index == 0x0f) {
592 // Disallow "free" bitrate.
593 return false;
594 }
595
596 unsigned sampling_rate_index = (header >> 10) & 3;
597
598 if (sampling_rate_index == 3) {
599 return false;
600 }
601
602 static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
603 int sampling_rate = kSamplingRateV1[sampling_rate_index];
604 if (version == 2 /* V2 */) {
605 sampling_rate /= 2;
606 } else if (version == 0 /* V2.5 */) {
607 sampling_rate /= 4;
608 }
609
610 unsigned padding = (header >> 9) & 1;
611
612 if (layer == 3) {
613 // layer I
614
615 static const int kBitrateV1[] = {
616 32, 64, 96, 128, 160, 192, 224, 256,
617 288, 320, 352, 384, 416, 448
618 };
619
620 static const int kBitrateV2[] = {
621 32, 48, 56, 64, 80, 96, 112, 128,
622 144, 160, 176, 192, 224, 256
623 };
624
625 int bitrate =
626 (version == 3 /* V1 */)
627 ? kBitrateV1[bitrate_index - 1]
628 : kBitrateV2[bitrate_index - 1];
629
630 if (out_bitrate) {
631 *out_bitrate = bitrate;
632 }
633
634 *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
635
636 if (out_num_samples) {
637 *out_num_samples = 384;
638 }
639 } else {
640 // layer II or III
641
642 static const int kBitrateV1L2[] = {
643 32, 48, 56, 64, 80, 96, 112, 128,
644 160, 192, 224, 256, 320, 384
645 };
646
647 static const int kBitrateV1L3[] = {
648 32, 40, 48, 56, 64, 80, 96, 112,
649 128, 160, 192, 224, 256, 320
650 };
651
652 static const int kBitrateV2[] = {
653 8, 16, 24, 32, 40, 48, 56, 64,
654 80, 96, 112, 128, 144, 160
655 };
656
657 int bitrate;
658 if (version == 3 /* V1 */) {
659 bitrate = (layer == 2 /* L2 */)
660 ? kBitrateV1L2[bitrate_index - 1]
661 : kBitrateV1L3[bitrate_index - 1];
662
663 if (out_num_samples) {
664 *out_num_samples = 1152;
665 }
666 } else {
667 // V2 (or 2.5)
668
669 bitrate = kBitrateV2[bitrate_index - 1];
670 if (out_num_samples) {
John Grossmanab736e12012-08-29 14:51:01 -0700671 *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
Andreas Huber386d6092011-05-19 08:37:39 -0700672 }
673 }
674
675 if (out_bitrate) {
676 *out_bitrate = bitrate;
677 }
678
679 if (version == 3 /* V1 */) {
680 *frame_size = 144000 * bitrate / sampling_rate + padding;
681 } else {
682 // V2 or V2.5
John Grossmanab736e12012-08-29 14:51:01 -0700683 size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
684 *frame_size = tmp * bitrate / sampling_rate + padding;
Andreas Huber386d6092011-05-19 08:37:39 -0700685 }
686 }
687
688 if (out_sampling_rate) {
689 *out_sampling_rate = sampling_rate;
690 }
691
692 if (out_channels) {
693 int channel_mode = (header >> 6) & 3;
694
695 *out_channels = (channel_mode == 3) ? 1 : 2;
696 }
697
698 return true;
699}
700
Andreas Huber85f12e92010-08-19 10:39:47 -0700701} // namespace android
702