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

Commit af4a3215 authored by Linus Nilsson's avatar Linus Nilsson
Browse files

Transcoder: Fix codec config error with single frame video

Add default frame rate config in order to successfully
configure the encoder when frame rate information is
missing, such as for single-frame videos.

Bug: 175641397
Test: Unit tests
Change-Id: I2bab3534d5de5df41e5309049cb8e1249cf955d1
parent 0c01f3d1
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -235,6 +235,33 @@ media_status_t MediaSampleReaderNDK::selectTrack(int trackIndex) {
    return AMEDIA_OK;
}

media_status_t MediaSampleReaderNDK::unselectTrack(int trackIndex) {
    std::scoped_lock lock(mExtractorMutex);

    if (trackIndex < 0 || trackIndex >= mTrackCount) {
        LOG(ERROR) << "Invalid trackIndex " << trackIndex << " for trackCount " << mTrackCount;
        return AMEDIA_ERROR_INVALID_PARAMETER;
    } else if (mExtractorTrackIndex >= 0) {
        LOG(ERROR) << "unselectTrack must be called before sample reading begins.";
        return AMEDIA_ERROR_UNSUPPORTED;
    }

    auto it = mTrackSignals.find(trackIndex);
    if (it == mTrackSignals.end()) {
        LOG(ERROR) << "TrackIndex " << trackIndex << " is not selected";
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }
    mTrackSignals.erase(it);

    media_status_t status = AMediaExtractor_unselectTrack(mExtractor, trackIndex);
    if (status != AMEDIA_OK) {
        LOG(ERROR) << "AMediaExtractor_selectTrack returned error: " << status;
        return status;
    }

    return AMEDIA_OK;
}

media_status_t MediaSampleReaderNDK::setEnforceSequentialAccess(bool enforce) {
    LOG(DEBUG) << "setEnforceSequentialAccess( " << enforce << " )";

+7 −6
Original line number Diff line number Diff line
@@ -274,12 +274,6 @@ media_status_t MediaTranscoder::configureTrackFormat(size_t trackIndex, AMediaFo
        return AMEDIA_ERROR_INVALID_PARAMETER;
    }

    media_status_t status = mSampleReader->selectTrack(trackIndex);
    if (status != AMEDIA_OK) {
        LOG(ERROR) << "Unable to select track " << trackIndex;
        return status;
    }

    std::shared_ptr<MediaTrackTranscoder> transcoder;
    std::shared_ptr<AMediaFormat> format;

@@ -321,10 +315,17 @@ media_status_t MediaTranscoder::configureTrackFormat(size_t trackIndex, AMediaFo
        format = std::shared_ptr<AMediaFormat>(mergedFormat, &AMediaFormat_delete);
    }

    media_status_t status = mSampleReader->selectTrack(trackIndex);
    if (status != AMEDIA_OK) {
        LOG(ERROR) << "Unable to select track " << trackIndex;
        return status;
    }

    status = transcoder->configure(mSampleReader, trackIndex, format);
    if (status != AMEDIA_OK) {
        LOG(ERROR) << "Configure track transcoder for track #" << trackIndex << " returned error "
                   << status;
        mSampleReader->unselectTrack(trackIndex);
        return status;
    }

+5 −1
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ static constexpr int32_t kDefaultCodecOperatingRate = 240;
static constexpr int32_t kDefaultCodecPriority = 1;
// Default bitrate, in case source estimation fails.
static constexpr int32_t kDefaultBitrateMbps = 10 * 1000 * 1000;
// Default frame rate.
static constexpr int32_t kDefaultFrameRate = 30;

template <typename T>
void VideoTrackTranscoder::BlockingQueue<T>::push(T const& value, bool front) {
@@ -210,7 +212,7 @@ media_status_t VideoTrackTranscoder::configureDestinationFormat(
    SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_OPERATING_RATE, encoderFormat,
                               kDefaultCodecOperatingRate);
    SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_PRIORITY, encoderFormat, kDefaultCodecPriority);

    SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_FRAME_RATE, encoderFormat, kDefaultFrameRate);
    AMediaFormat_setInt32(encoderFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, kColorFormatSurface);

    // Always encode without rotation. The rotation degree will be transferred directly to
@@ -235,6 +237,7 @@ media_status_t VideoTrackTranscoder::configureDestinationFormat(
    }
    mEncoder = std::make_shared<CodecWrapper>(encoder, shared_from_this());

    LOG(DEBUG) << "Configuring encoder with: " << AMediaFormat_toString(mDestinationFormat.get());
    status = AMediaCodec_configure(mEncoder->getCodec(), mDestinationFormat.get(),
                                   NULL /* surface */, NULL /* crypto */,
                                   AMEDIACODEC_CONFIGURE_FLAG_ENCODE);
@@ -282,6 +285,7 @@ media_status_t VideoTrackTranscoder::configureDestinationFormat(
    CopyFormatEntries(mDestinationFormat.get(), decoderFormat.get(), kEncoderEntriesToCopy,
                      entryCount);

    LOG(DEBUG) << "Configuring decoder with: " << AMediaFormat_toString(decoderFormat.get());
    status = AMediaCodec_configure(mDecoder, decoderFormat.get(), mSurface, NULL /* crypto */,
                                   0 /* flags */);
    if (status != AMEDIA_OK) {
+4 −0
Original line number Diff line number Diff line
@@ -167,6 +167,10 @@ public:
        return AMEDIA_OK;
    }

    media_status_t unselectTrack(int trackIndex __unused) override {
        return AMEDIA_ERROR_UNSUPPORTED;
    }

    media_status_t setEnforceSequentialAccess(bool enforce __unused) override { return AMEDIA_OK; }

    media_status_t getEstimatedBitrateForTrack(int trackIndex __unused,
+7 −0
Original line number Diff line number Diff line
@@ -68,6 +68,13 @@ public:
     */
    virtual media_status_t selectTrack(int trackIndex) = 0;

    /**
     * Undo a track selection.
     * @param trackIndex The track to un-select.
     * @return AMEDIA_OK on success.
     */
    virtual media_status_t unselectTrack(int trackIndex) = 0;

    /**
     * Toggles sequential access enforcement on or off. When the reader enforces sequential access
     * calls to read sample information will block unless the underlying extractor points to the
Loading