Loading media/libmediatranscoding/transcoder/MediaSampleWriter.cpp +22 −4 Original line number Diff line number Diff line Loading @@ -122,7 +122,12 @@ bool MediaSampleWriter::addTrack(const std::shared_ptr<MediaSampleQueue>& sample return false; } mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex)); int64_t durationUs; if (!AMediaFormat_getInt64(trackFormat.get(), AMEDIAFORMAT_KEY_DURATION, &durationUs)) { durationUs = 0; } mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex), durationUs); return true; } Loading Loading @@ -200,10 +205,23 @@ media_status_t MediaSampleWriter::runWriterLoop() { } else if (sample->info.flags & SAMPLE_FLAG_END_OF_STREAM) { // Track reached end of stream. track.mReachedEos = true; break; } // Preserve source track duration by setting the appropriate timestamp on the // empty End-Of-Stream sample. if (track.mDurationUs > 0 && track.mFirstSampleTimeSet) { sample->info.presentationTimeUs = track.mDurationUs + track.mFirstSampleTimeUs; } } else { samplesLeft = true; } // Record the first sample's timestamp in order to translate duration to EOS time // for tracks that does not start at 0. if (!track.mFirstSampleTimeSet) { track.mFirstSampleTimeUs = sample->info.presentationTimeUs; track.mFirstSampleTimeSet = true; } bufferInfo.offset = sample->dataOffset; bufferInfo.size = sample->info.size; Loading @@ -217,7 +235,7 @@ media_status_t MediaSampleWriter::runWriterLoop() { return status; } } while (sample->info.presentationTimeUs < segmentEndTimeUs); } while (sample->info.presentationTimeUs < segmentEndTimeUs && !track.mReachedEos); } segmentEndTimeUs += mTrackSegmentLengthUs; Loading media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -372,6 +372,14 @@ void VideoTrackTranscoder::updateTrackFormat(AMediaFormat* outputFormat) { AMediaFormat_setInt32(formatCopy, AMEDIAFORMAT_KEY_ROTATION, rotation); } // Transfer track duration. // Preserve the source track duration by sending it to MediaSampleWriter. int64_t durationUs; if (AMediaFormat_getInt64(mSourceFormat.get(), AMEDIAFORMAT_KEY_DURATION, &durationUs) && durationUs > 0) { AMediaFormat_setInt64(formatCopy, AMEDIAFORMAT_KEY_DURATION, durationUs); } // TODO: transfer other fields as required. mActualOutputFormat = std::shared_ptr<AMediaFormat>(formatCopy, &AMediaFormat_delete); Loading media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h +11 −2 Original line number Diff line number Diff line Loading @@ -144,11 +144,20 @@ private: media_status_t runWriterLoop(); struct TrackRecord { TrackRecord(const std::shared_ptr<MediaSampleQueue>& sampleQueue, size_t trackIndex) : mSampleQueue(sampleQueue), mTrackIndex(trackIndex), mReachedEos(false) {} TrackRecord(const std::shared_ptr<MediaSampleQueue>& sampleQueue, size_t trackIndex, int64_t durationUs) : mSampleQueue(sampleQueue), mTrackIndex(trackIndex), mDurationUs(durationUs), mFirstSampleTimeUs(0), mFirstSampleTimeSet(false), mReachedEos(false) {} std::shared_ptr<MediaSampleQueue> mSampleQueue; const size_t mTrackIndex; int64_t mDurationUs; int64_t mFirstSampleTimeUs; bool mFirstSampleTimeSet; bool mReachedEos; }; Loading media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -374,6 +374,16 @@ TEST_F(MediaSampleWriterTests, TestInterleaving) { EXPECT_EQ(event.info.flags, sample->info.flags); } // Verify EOS samples. for (int trackIndex = 0; trackIndex < kNumTracks; ++trackIndex) { auto trackFormat = mediaSource.mTrackFormats[trackIndex % mediaSource.mTrackCount]; int64_t duration = 0; AMediaFormat_getInt64(trackFormat.get(), AMEDIAFORMAT_KEY_DURATION, &duration); const AMediaCodecBufferInfo info = {0, 0, duration, AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM}; EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::WriteSample(trackIndex, nullptr, &info)); } EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::Stop()); EXPECT_TRUE(writer.stop()); } Loading media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,7 @@ public: std::shared_ptr<MediaSampleReader> sampleReader = MediaSampleReaderNDK::createFromFd(dstFd, 0, fileSize); ASSERT_NE(sampleReader, nullptr); std::shared_ptr<AMediaFormat> videoFormat; const size_t trackCount = sampleReader->getTrackCount(); Loading @@ -211,6 +212,7 @@ public: if (trackFormat != nullptr) { const char* mime = nullptr; AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime); if (strncmp(mime, "video/", 6) == 0) { LOG(INFO) << "Track # " << trackIndex << ": " << AMediaFormat_toString(trackFormat); Loading Loading
media/libmediatranscoding/transcoder/MediaSampleWriter.cpp +22 −4 Original line number Diff line number Diff line Loading @@ -122,7 +122,12 @@ bool MediaSampleWriter::addTrack(const std::shared_ptr<MediaSampleQueue>& sample return false; } mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex)); int64_t durationUs; if (!AMediaFormat_getInt64(trackFormat.get(), AMEDIAFORMAT_KEY_DURATION, &durationUs)) { durationUs = 0; } mTracks.emplace_back(sampleQueue, static_cast<size_t>(trackIndex), durationUs); return true; } Loading Loading @@ -200,10 +205,23 @@ media_status_t MediaSampleWriter::runWriterLoop() { } else if (sample->info.flags & SAMPLE_FLAG_END_OF_STREAM) { // Track reached end of stream. track.mReachedEos = true; break; } // Preserve source track duration by setting the appropriate timestamp on the // empty End-Of-Stream sample. if (track.mDurationUs > 0 && track.mFirstSampleTimeSet) { sample->info.presentationTimeUs = track.mDurationUs + track.mFirstSampleTimeUs; } } else { samplesLeft = true; } // Record the first sample's timestamp in order to translate duration to EOS time // for tracks that does not start at 0. if (!track.mFirstSampleTimeSet) { track.mFirstSampleTimeUs = sample->info.presentationTimeUs; track.mFirstSampleTimeSet = true; } bufferInfo.offset = sample->dataOffset; bufferInfo.size = sample->info.size; Loading @@ -217,7 +235,7 @@ media_status_t MediaSampleWriter::runWriterLoop() { return status; } } while (sample->info.presentationTimeUs < segmentEndTimeUs); } while (sample->info.presentationTimeUs < segmentEndTimeUs && !track.mReachedEos); } segmentEndTimeUs += mTrackSegmentLengthUs; Loading
media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -372,6 +372,14 @@ void VideoTrackTranscoder::updateTrackFormat(AMediaFormat* outputFormat) { AMediaFormat_setInt32(formatCopy, AMEDIAFORMAT_KEY_ROTATION, rotation); } // Transfer track duration. // Preserve the source track duration by sending it to MediaSampleWriter. int64_t durationUs; if (AMediaFormat_getInt64(mSourceFormat.get(), AMEDIAFORMAT_KEY_DURATION, &durationUs) && durationUs > 0) { AMediaFormat_setInt64(formatCopy, AMEDIAFORMAT_KEY_DURATION, durationUs); } // TODO: transfer other fields as required. mActualOutputFormat = std::shared_ptr<AMediaFormat>(formatCopy, &AMediaFormat_delete); Loading
media/libmediatranscoding/transcoder/include/media/MediaSampleWriter.h +11 −2 Original line number Diff line number Diff line Loading @@ -144,11 +144,20 @@ private: media_status_t runWriterLoop(); struct TrackRecord { TrackRecord(const std::shared_ptr<MediaSampleQueue>& sampleQueue, size_t trackIndex) : mSampleQueue(sampleQueue), mTrackIndex(trackIndex), mReachedEos(false) {} TrackRecord(const std::shared_ptr<MediaSampleQueue>& sampleQueue, size_t trackIndex, int64_t durationUs) : mSampleQueue(sampleQueue), mTrackIndex(trackIndex), mDurationUs(durationUs), mFirstSampleTimeUs(0), mFirstSampleTimeSet(false), mReachedEos(false) {} std::shared_ptr<MediaSampleQueue> mSampleQueue; const size_t mTrackIndex; int64_t mDurationUs; int64_t mFirstSampleTimeUs; bool mFirstSampleTimeSet; bool mReachedEos; }; Loading
media/libmediatranscoding/transcoder/tests/MediaSampleWriterTests.cpp +10 −0 Original line number Diff line number Diff line Loading @@ -374,6 +374,16 @@ TEST_F(MediaSampleWriterTests, TestInterleaving) { EXPECT_EQ(event.info.flags, sample->info.flags); } // Verify EOS samples. for (int trackIndex = 0; trackIndex < kNumTracks; ++trackIndex) { auto trackFormat = mediaSource.mTrackFormats[trackIndex % mediaSource.mTrackCount]; int64_t duration = 0; AMediaFormat_getInt64(trackFormat.get(), AMEDIAFORMAT_KEY_DURATION, &duration); const AMediaCodecBufferInfo info = {0, 0, duration, AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM}; EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::WriteSample(trackIndex, nullptr, &info)); } EXPECT_EQ(mTestMuxer->popEvent(), TestMuxer::Stop()); EXPECT_TRUE(writer.stop()); } Loading
media/libmediatranscoding/transcoder/tests/MediaTranscoderTests.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,7 @@ public: std::shared_ptr<MediaSampleReader> sampleReader = MediaSampleReaderNDK::createFromFd(dstFd, 0, fileSize); ASSERT_NE(sampleReader, nullptr); std::shared_ptr<AMediaFormat> videoFormat; const size_t trackCount = sampleReader->getTrackCount(); Loading @@ -211,6 +212,7 @@ public: if (trackFormat != nullptr) { const char* mime = nullptr; AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime); if (strncmp(mime, "video/", 6) == 0) { LOG(INFO) << "Track # " << trackIndex << ": " << AMediaFormat_toString(trackFormat); Loading