Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 516dacfb authored by Andreas Huber's avatar Andreas Huber
Browse files

Respect sample aspect ratio in NuPlayer.

related-to-bug: 7569402
Change-Id: I302de95d83b180bd2dc72ddd0c69a665dbce2527
parent 88e67204
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ enum {
    kKeyHeight            = 'heig',  // int32_t, image pixel
    kKeyDisplayWidth      = 'dWid',  // int32_t, display/presentation
    kKeyDisplayHeight     = 'dHgt',  // int32_t, display/presentation
    kKeySARWidth          = 'sarW',  // int32_t, sampleAspectRatio width
    kKeySARHeight         = 'sarH',  // int32_t, sampleAspectRatio height

    // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
    kKeyCropRect          = 'crop',
+31 −10
Original line number Diff line number Diff line
@@ -448,7 +448,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
            } else if (what == ACodec::kWhatOutputFormatChanged) {
                if (audio) {
                    int32_t numChannels;
                    CHECK(codecRequest->findInt32("channel-count", &numChannels));
                    CHECK(codecRequest->findInt32(
                                "channel-count", &numChannels));

                    int32_t sampleRate;
                    CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
@@ -460,13 +461,15 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {

                    audio_output_flags_t flags;
                    int64_t durationUs;
                    // FIXME: we should handle the case where the video decoder is created after
                    // we receive the format change indication. Current code will just make that
                    // we select deep buffer with video which should not be a problem as it should
                    // FIXME: we should handle the case where the video decoder
                    // is created after we receive the format change indication.
                    // Current code will just make that we select deep buffer
                    // with video which should not be a problem as it should
                    // not prevent from keeping A/V sync.
                    if (mVideoDecoder == NULL &&
                            mSource->getDuration(&durationUs) == OK &&
                            durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
                            durationUs
                                > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
                        flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
                    } else {
                        flags = AUDIO_OUTPUT_FLAG_NONE;
@@ -502,17 +505,35 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                                "crop",
                                &cropLeft, &cropTop, &cropRight, &cropBottom));

                    int32_t displayWidth = cropRight - cropLeft + 1;
                    int32_t displayHeight = cropBottom - cropTop + 1;

                    ALOGV("Video output format changed to %d x %d "
                         "(crop: %d x %d @ (%d, %d))",
                         width, height,
                         (cropRight - cropLeft + 1),
                         (cropBottom - cropTop + 1),
                         displayWidth,
                         displayHeight,
                         cropLeft, cropTop);

                    sp<AMessage> videoInputFormat =
                        mSource->getFormat(false /* audio */);

                    // Take into account sample aspect ratio if necessary:
                    int32_t sarWidth, sarHeight;
                    if (videoInputFormat->findInt32("sar-width", &sarWidth)
                            && videoInputFormat->findInt32(
                                "sar-height", &sarHeight)) {
                        ALOGV("Sample aspect ratio %d : %d",
                              sarWidth, sarHeight);

                        displayWidth = (displayWidth * sarWidth) / sarHeight;

                        ALOGV("display dimensions %d x %d",
                              displayWidth, displayHeight);
                    }

                    notifyListener(
                            MEDIA_SET_VIDEO_SIZE,
                            cropRight - cropLeft + 1,
                            cropBottom - cropTop + 1);
                            MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight);
                }
            } else if (what == ACodec::kWhatShutdownCompleted) {
                ALOGV("%s shutdown completed", audio ? "audio" : "video");
+10 −4
Original line number Diff line number Diff line
@@ -966,17 +966,23 @@ status_t ACodec::configureCodec(
            err = INVALID_OPERATION;
        } else {
            if (encoder) {
                if (!msg->findInt32("flac-compression-level", &compressionLevel)) {
                if (!msg->findInt32(
                            "flac-compression-level", &compressionLevel)) {
                    compressionLevel = 5;// default FLAC compression level
                } else if (compressionLevel < 0) {
                    ALOGW("compression level %d outside [0..8] range, using 0", compressionLevel);
                    ALOGW("compression level %d outside [0..8] range, "
                          "using 0",
                          compressionLevel);
                    compressionLevel = 0;
                } else if (compressionLevel > 8) {
                    ALOGW("compression level %d outside [0..8] range, using 8", compressionLevel);
                    ALOGW("compression level %d outside [0..8] range, "
                          "using 8",
                          compressionLevel);
                    compressionLevel = 8;
                }
            }
            err = setupFlacCodec(encoder, numChannels, sampleRate, compressionLevel);
            err = setupFlacCodec(
                    encoder, numChannels, sampleRate, compressionLevel);
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
        int32_t numChannels, sampleRate;
+14 −0
Original line number Diff line number Diff line
@@ -85,6 +85,13 @@ status_t convertMetaDataToMessage(

        msg->setInt32("width", width);
        msg->setInt32("height", height);

        int32_t sarWidth, sarHeight;
        if (meta->findInt32(kKeySARWidth, &sarWidth)
                && meta->findInt32(kKeySARHeight, &sarHeight)) {
            msg->setInt32("sar-width", sarWidth);
            msg->setInt32("sar-height", sarHeight);
        }
    } else if (!strncasecmp("audio/", mime, 6)) {
        int32_t numChannels, sampleRate;
        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
@@ -372,6 +379,13 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
        } else {
            ALOGW("did not find width and/or height");
        }

        int32_t sarWidth, sarHeight;
        if (msg->findInt32("sar-width", &sarWidth)
                && msg->findInt32("sar-height", &sarHeight)) {
            meta->setInt32(kKeySARWidth, sarWidth);
            meta->setInt32(kKeySARHeight, sarHeight);
        }
    } else if (mime.startsWith("audio/")) {
        int32_t numChannels;
        if (msg->findInt32("channel-count", &numChannels)) {
+72 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
@@ -41,7 +42,9 @@ unsigned parseUE(ABitReader *br) {

// Determine video dimensions from the sequence parameterset.
void FindAVCDimensions(
        const sp<ABuffer> &seqParamSet, int32_t *width, int32_t *height) {
        const sp<ABuffer> &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<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
    }

    int32_t width, height;
    FindAVCDimensions(seqParamSet, &width, &height);
    int32_t sarWidth, sarHeight;
    FindAVCDimensions(
            seqParamSet, &width, &height, &sarWidth, &sarHeight);

    size_t stopOffset;
    sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
@@ -301,8 +348,29 @@ sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
    meta->setInt32(kKeyWidth, width);
    meta->setInt32(kKeyHeight, height);

    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);
             width,
             height,
             AVCProfileToString(profile),
             level / 10,
             level % 10);
    }

    return meta;
}
Loading