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

Commit 687a009e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Transcoder: Preserve source track's bitrate by default."

parents 262eb70e 800793f3
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <media/MediaSampleReaderNDK.h>

#include <algorithm>
#include <cmath>
#include <vector>

namespace android {
@@ -189,6 +190,78 @@ media_status_t MediaSampleReaderNDK::positionExtractorForTrack_l(int trackIndex)
    return AMEDIA_OK;
}

media_status_t MediaSampleReaderNDK::getEstimatedBitrateForTrack(int trackIndex, int32_t* bitrate) {
    std::scoped_lock lock(mExtractorMutex);
    media_status_t status = AMEDIA_OK;

    if (trackIndex < 0 || trackIndex >= mTrackCount) {
        LOG(ERROR) << "Invalid trackIndex " << trackIndex << " for trackCount " << mTrackCount;
        return AMEDIA_ERROR_INVALID_PARAMETER;
    } else if (bitrate == nullptr) {
        LOG(ERROR) << "bitrate pointer is NULL.";
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    // Rewind the extractor and sample from the beginning of the file.
    if (mExtractorSampleIndex > 0) {
        status = AMediaExtractor_seekTo(mExtractor, 0, AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC);
        if (status != AMEDIA_OK) {
            LOG(ERROR) << "Unable to reset extractor: " << status;
            return status;
        }

        mExtractorTrackIndex = AMediaExtractor_getSampleTrackIndex(mExtractor);
        mExtractorSampleIndex = 0;
    }

    // Sample the track.
    static constexpr int64_t kSamplingDurationUs = 10 * 1000 * 1000;  // 10 seconds
    size_t lastSampleSize = 0;
    size_t totalSampleSize = 0;
    int64_t firstSampleTimeUs = 0;
    int64_t lastSampleTimeUs = 0;

    do {
        if (mExtractorTrackIndex == trackIndex) {
            lastSampleTimeUs = AMediaExtractor_getSampleTime(mExtractor);
            if (totalSampleSize == 0) {
                firstSampleTimeUs = lastSampleTimeUs;
            }

            lastSampleSize = AMediaExtractor_getSampleSize(mExtractor);
            totalSampleSize += lastSampleSize;
        }
    } while ((lastSampleTimeUs - firstSampleTimeUs) < kSamplingDurationUs && advanceExtractor_l());

    int64_t durationUs = 0;
    const int64_t sampledDurationUs = lastSampleTimeUs - firstSampleTimeUs;

    if (sampledDurationUs < kSamplingDurationUs) {
        // Track is shorter than the sampling duration so use the full track duration to get better
        // accuracy (i.e. don't skip the last sample).
        AMediaFormat* trackFormat = getTrackFormat(trackIndex);
        if (!AMediaFormat_getInt64(trackFormat, AMEDIAFORMAT_KEY_DURATION, &durationUs)) {
            durationUs = 0;
        }
        AMediaFormat_delete(trackFormat);
    }

    if (durationUs == 0) {
        // The sampled duration does not account for the last sample's duration so its size should
        // not be included either.
        totalSampleSize -= lastSampleSize;
        durationUs = sampledDurationUs;
    }

    if (totalSampleSize == 0 || durationUs <= 0) {
        LOG(ERROR) << "Unable to estimate track bitrate";
        return AMEDIA_ERROR_MALFORMED;
    }

    *bitrate = roundf((float)totalSampleSize * 8 * 1000000 / durationUs);
    return AMEDIA_OK;
}

media_status_t MediaSampleReaderNDK::getSampleInfoForTrack(int trackIndex, MediaSampleInfo* info) {
    std::scoped_lock lock(mExtractorMutex);

+2 −3
Original line number Diff line number Diff line
@@ -45,9 +45,8 @@ media_status_t MediaTrackTranscoder::configure(
    mMediaSampleReader = mediaSampleReader;
    mTrackIndex = trackIndex;

    mSourceFormat =
            std::shared_ptr<AMediaFormat>(mMediaSampleReader->getTrackFormat(mTrackIndex),
                                          std::bind(AMediaFormat_delete, std::placeholders::_1));
    mSourceFormat = std::shared_ptr<AMediaFormat>(mMediaSampleReader->getTrackFormat(mTrackIndex),
                                                  &AMediaFormat_delete);
    if (mSourceFormat == nullptr) {
        LOG(ERROR) << "Unable to get format for track #" << mTrackIndex;
        return AMEDIA_ERROR_MALFORMED;
+14 −0
Original line number Diff line number Diff line
@@ -164,6 +164,8 @@ VideoTrackTranscoder::~VideoTrackTranscoder() {
// Creates and configures the codecs.
media_status_t VideoTrackTranscoder::configureDestinationFormat(
        const std::shared_ptr<AMediaFormat>& destinationFormat) {
    static constexpr int32_t kDefaultBitrateMbps = 10 * 1000 * 1000;

    media_status_t status = AMEDIA_OK;

    if (destinationFormat == nullptr) {
@@ -177,6 +179,18 @@ media_status_t VideoTrackTranscoder::configureDestinationFormat(
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    int32_t bitrate;
    if (!AMediaFormat_getInt32(encoderFormat, AMEDIAFORMAT_KEY_BIT_RATE, &bitrate)) {
        status = mMediaSampleReader->getEstimatedBitrateForTrack(mTrackIndex, &bitrate);
        if (status != AMEDIA_OK) {
            LOG(ERROR) << "Unable to estimate bitrate. Using default " << kDefaultBitrateMbps;
            bitrate = kDefaultBitrateMbps;
        }

        LOG(INFO) << "Configuring bitrate " << bitrate;
        AMediaFormat_setInt32(encoderFormat, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
    }

    float tmp;
    if (!AMediaFormat_getFloat(encoderFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, &tmp)) {
        AMediaFormat_setFloat(encoderFormat, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL,
+10 −0
Original line number Diff line number Diff line
@@ -56,6 +56,16 @@ public:
     */
    virtual AMediaFormat* getTrackFormat(int trackIndex) = 0;

    /**
     * Estimates the bitrate of a source track by sampling sample sizes. The bitrate is returned in
     * megabits per second (Mbps). This method will fail if the track only contains a single sample
     * and does not have an associated duration.
     * @param trackIndex The source track index.
     * @param bitrate Output param for the bitrate.
     * @return AMEDIA_OK on success.
     */
    virtual media_status_t getEstimatedBitrateForTrack(int trackIndex, int32_t* bitrate);

    /**
     * Returns the sample information for the current sample in the specified track.
     * @param trackIndex The track index (zero-based).
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ public:
    AMediaFormat* getFileFormat() override;
    size_t getTrackCount() const override;
    AMediaFormat* getTrackFormat(int trackIndex) override;
    media_status_t getEstimatedBitrateForTrack(int trackIndex, int32_t* bitrate) override;
    media_status_t getSampleInfoForTrack(int trackIndex, MediaSampleInfo* info) override;
    media_status_t readSampleDataForTrack(int trackIndex, uint8_t* buffer,
                                          size_t bufferSize) override;
Loading