• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "avc_utils"
19 #include <utils/Log.h>
20 
21 #include "include/avc_utils.h"
22 
23 #include <media/stagefright/foundation/ABitReader.h>
24 #include <media/stagefright/foundation/ADebug.h>
25 #include <media/stagefright/foundation/hexdump.h>
26 #include <media/stagefright/MediaDefs.h>
27 #include <media/stagefright/MediaErrors.h>
28 #include <media/stagefright/MetaData.h>
29 
30 namespace android {
31 
parseUE(ABitReader * br)32 unsigned parseUE(ABitReader *br) {
33     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.
FindAVCDimensions(const sp<ABuffer> & seqParamSet,int32_t * width,int32_t * height,int32_t * sarWidth,int32_t * sarHeight)44 void FindAVCDimensions(
45         const sp<ABuffer> &seqParamSet,
46         int32_t *width, int32_t *height,
47         int32_t *sarWidth, int32_t *sarHeight) {
48     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 
54     unsigned chroma_format_idc = 1;  // 4:2:0 chroma format
55 
56     if (profile_idc == 100 || profile_idc == 110
57             || profile_idc == 122 || profile_idc == 244
58             || profile_idc == 44 || profile_idc == 83 || profile_idc == 86) {
59         chroma_format_idc = parseUE(&br);
60         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);
100 
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 
125         ALOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u",
126              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     }
135 
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     }
177 }
178 
getNextNALUnit(const uint8_t ** _data,size_t * _size,const uint8_t ** nalStart,size_t * nalSize,bool startCodeFollows)179 status_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;
236     while (endOffset > startOffset + 1 && data[endOffset - 1] == 0x00) {
237         --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 
FindNAL(const uint8_t * data,size_t size,unsigned nalType,size_t * stopOffset)254 static 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 
AVCProfileToString(uint8_t profile)270 const 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 
MakeAVCCodecSpecificData(const sp<ABuffer> & accessUnit)292 sp<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;
302     int32_t sarWidth, sarHeight;
303     FindAVCDimensions(
304             seqParamSet, &width, &height, &sarWidth, &sarHeight);
305 
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...
320 
321     uint8_t profile = out[0];
322     uint8_t level = out[2];
323 
324     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
340     ALOGI("AVC seq param set");
341     hexdump(seqParamSet->data(), seqParamSet->size());
342 #endif
343 
344     sp<MetaData> meta = new MetaData;
345     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
346 
347     meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
348     meta->setInt32(kKeyWidth, width);
349     meta->setInt32(kKeyHeight, height);
350 
351     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     }
374 
375     return meta;
376 }
377 
IsIDR(const sp<ABuffer> & buffer)378 bool 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 
IsAVCReferenceFrame(const sp<ABuffer> & accessUnit)400 bool 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 
MakeAACCodecSpecificData(unsigned profile,unsigned sampling_freq_index,unsigned channel_configuration)422 sp<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 
ExtractDimensionsFromVOLHeader(const uint8_t * data,size_t size,int32_t * width,int32_t * height)469 bool 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 
GetMPEGAudioFrameSize(uint32_t header,size_t * frame_size,int * out_sampling_rate,int * out_channels,int * out_bitrate,int * out_num_samples)549 bool 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) {
671                 *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
672             }
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
683             size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
684             *frame_size = tmp * bitrate / sampling_rate + padding;
685         }
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 
701 }  // namespace android
702 
703