From 516dacfb02d0b0eafe21114330c98ce0e7d90da9 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 3 Dec 2012 15:20:40 -0800 Subject: Respect sample aspect ratio in NuPlayer. related-to-bug: 7569402 Change-Id: I302de95d83b180bd2dc72ddd0c69a665dbce2527 --- media/libstagefright/avc_utils.cpp | 76 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'media/libstagefright/avc_utils.cpp') diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp index a141752..b822868 100644 --- a/media/libstagefright/avc_utils.cpp +++ b/media/libstagefright/avc_utils.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -41,7 +42,9 @@ unsigned parseUE(ABitReader *br) { // Determine video dimensions from the sequence parameterset. void FindAVCDimensions( - const sp &seqParamSet, int32_t *width, int32_t *height) { + const sp &seqParamSet, + int32_t *width, int32_t *height, + int32_t *sarWidth, int32_t *sarHeight) { ABitReader br(seqParamSet->data() + 1, seqParamSet->size() - 1); unsigned profile_idc = br.getBits(8); @@ -129,6 +132,48 @@ void FindAVCDimensions( *height -= (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY; } + + if (sarWidth != NULL) { + *sarWidth = 0; + } + + if (sarHeight != NULL) { + *sarHeight = 0; + } + + if (br.getBits(1)) { // vui_parameters_present_flag + unsigned sar_width = 0, sar_height = 0; + + if (br.getBits(1)) { // aspect_ratio_info_present_flag + unsigned aspect_ratio_idc = br.getBits(8); + + if (aspect_ratio_idc == 255 /* extendedSAR */) { + sar_width = br.getBits(16); + sar_height = br.getBits(16); + } else if (aspect_ratio_idc > 0 && aspect_ratio_idc < 14) { + static const int32_t kFixedSARWidth[] = { + 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160 + }; + + static const int32_t kFixedSARHeight[] = { + 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99 + }; + + sar_width = kFixedSARWidth[aspect_ratio_idc - 1]; + sar_height = kFixedSARHeight[aspect_ratio_idc - 1]; + } + } + + ALOGV("sample aspect ratio = %u : %u", sar_width, sar_height); + + if (sarWidth != NULL) { + *sarWidth = sar_width; + } + + if (sarHeight != NULL) { + *sarHeight = sar_height; + } + } } status_t getNextNALUnit( @@ -254,7 +299,9 @@ sp MakeAVCCodecSpecificData(const sp &accessUnit) { } int32_t width, height; - FindAVCDimensions(seqParamSet, &width, &height); + int32_t sarWidth, sarHeight; + FindAVCDimensions( + seqParamSet, &width, &height, &sarWidth, &sarHeight); size_t stopOffset; sp picParamSet = FindNAL(data, size, 8, &stopOffset); @@ -301,8 +348,29 @@ sp MakeAVCCodecSpecificData(const sp &accessUnit) { meta->setInt32(kKeyWidth, width); meta->setInt32(kKeyHeight, height); - ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)", - width, height, AVCProfileToString(profile), level / 10, level % 10); + if (sarWidth > 1 || sarHeight > 1) { + // We treat 0:0 (unspecified) as 1:1. + + meta->setInt32(kKeySARWidth, sarWidth); + meta->setInt32(kKeySARHeight, sarHeight); + + ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d) " + "SAR %d : %d", + width, + height, + AVCProfileToString(profile), + level / 10, + level % 10, + sarWidth, + sarHeight); + } else { + ALOGI("found AVC codec config (%d x %d, %s-profile level %d.%d)", + width, + height, + AVCProfileToString(profile), + level / 10, + level % 10); + } return meta; } -- cgit v1.1