diff options
Diffstat (limited to 'dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp')
-rw-r--r-- | dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp b/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp deleted file mode 100644 index fa23616e9..000000000 --- a/dom/media/encoder/fmp4_muxer/ISOMediaWriter.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ISOMediaWriter.h" -#include "ISOControl.h" -#include "ISOMediaBoxes.h" -#include "ISOTrackMetadata.h" -#include "nsThreadUtils.h" -#include "MediaEncoder.h" -#include "VideoUtils.h" -#include "GeckoProfiler.h" - -#undef LOG -#ifdef MOZ_WIDGET_GONK -#include <android/log.h> -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "MediaEncoder", ## args); -#else -#define LOG(args, ...) -#endif - -namespace mozilla { - -const static uint32_t FRAG_DURATION = 2 * USECS_PER_S; // microsecond per unit - -ISOMediaWriter::ISOMediaWriter(uint32_t aType, uint32_t aHint) - : ContainerWriter() - , mState(MUXING_HEAD) - , mBlobReady(false) - , mType(0) -{ - if (aType & CREATE_AUDIO_TRACK) { - mType |= Audio_Track; - } - if (aType & CREATE_VIDEO_TRACK) { - mType |= Video_Track; - } - mControl = new ISOControl(aHint); - MOZ_COUNT_CTOR(ISOMediaWriter); -} - -ISOMediaWriter::~ISOMediaWriter() -{ - MOZ_COUNT_DTOR(ISOMediaWriter); -} - -nsresult -ISOMediaWriter::RunState() -{ - nsresult rv; - switch (mState) { - case MUXING_HEAD: - { - rv = mControl->GenerateFtyp(); - NS_ENSURE_SUCCESS(rv, rv); - rv = mControl->GenerateMoov(); - NS_ENSURE_SUCCESS(rv, rv); - mState = MUXING_FRAG; - break; - } - case MUXING_FRAG: - { - rv = mControl->GenerateMoof(mType); - NS_ENSURE_SUCCESS(rv, rv); - - bool EOS; - if (ReadyToRunState(EOS) && EOS) { - mState = MUXING_DONE; - } - break; - } - case MUXING_DONE: - { - break; - } - } - mBlobReady = true; - return NS_OK; -} - -nsresult -ISOMediaWriter::WriteEncodedTrack(const EncodedFrameContainer& aData, - uint32_t aFlags) -{ - PROFILER_LABEL("ISOMediaWriter", "WriteEncodedTrack", - js::ProfileEntry::Category::OTHER); - // Muxing complete, it doesn't allowed to reentry again. - if (mState == MUXING_DONE) { - MOZ_ASSERT(false); - return NS_ERROR_FAILURE; - } - - FragmentBuffer* frag = nullptr; - uint32_t len = aData.GetEncodedFrames().Length(); - - if (!len) { - // no frame? why bother to WriteEncodedTrack - return NS_OK; - } - for (uint32_t i = 0; i < len; i++) { - RefPtr<EncodedFrame> frame(aData.GetEncodedFrames()[i]); - EncodedFrame::FrameType type = frame->GetFrameType(); - if (type == EncodedFrame::AAC_AUDIO_FRAME || - type == EncodedFrame::AAC_CSD || - type == EncodedFrame::AMR_AUDIO_FRAME || - type == EncodedFrame::AMR_AUDIO_CSD || - type == EncodedFrame::EVRC_AUDIO_FRAME || - type == EncodedFrame::EVRC_AUDIO_CSD) { - frag = mAudioFragmentBuffer; - } else if (type == EncodedFrame::AVC_I_FRAME || - type == EncodedFrame::AVC_P_FRAME || - type == EncodedFrame::AVC_B_FRAME || - type == EncodedFrame::AVC_CSD) { - frag = mVideoFragmentBuffer; - } else { - MOZ_ASSERT(0); - return NS_ERROR_FAILURE; - } - - frag->AddFrame(frame); - } - - // Encoder should send CSD (codec specific data) frame before sending the - // audio/video frames. When CSD data is ready, it is sufficient to generate a - // moov data. If encoder doesn't send CSD yet, muxer needs to wait before - // generating anything. - if (mType & Audio_Track && (!mAudioFragmentBuffer || - !mAudioFragmentBuffer->HasCSD())) { - return NS_OK; - } - if (mType & Video_Track && (!mVideoFragmentBuffer || - !mVideoFragmentBuffer->HasCSD())) { - return NS_OK; - } - - // Only one FrameType in EncodedFrameContainer so it doesn't need to be - // inside the for-loop. - if (frag && (aFlags & END_OF_STREAM)) { - frag->SetEndOfStream(); - } - - nsresult rv; - bool EOS; - if (ReadyToRunState(EOS)) { - // Because track encoder won't generate new data after EOS, it needs to make - // sure the state reaches MUXING_DONE when EOS is signaled. - do { - rv = RunState(); - } while (EOS && mState != MUXING_DONE); - NS_ENSURE_SUCCESS(rv, rv); - } - - return NS_OK; -} - -bool -ISOMediaWriter::ReadyToRunState(bool& aEOS) -{ - aEOS = false; - bool bReadyToMux = true; - if ((mType & Audio_Track) && (mType & Video_Track)) { - if (!mAudioFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (!mVideoFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - - if (mAudioFragmentBuffer->EOS() && mVideoFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } else if (mType == Audio_Track) { - if (!mAudioFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (mAudioFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } else if (mType == Video_Track) { - if (!mVideoFragmentBuffer->HasEnoughData()) { - bReadyToMux = false; - } - if (mVideoFragmentBuffer->EOS()) { - aEOS = true; - bReadyToMux = true; - } - } - - return bReadyToMux; -} - -nsresult -ISOMediaWriter::GetContainerData(nsTArray<nsTArray<uint8_t>>* aOutputBufs, - uint32_t aFlags) -{ - PROFILER_LABEL("ISOMediaWriter", "GetContainerData", - js::ProfileEntry::Category::OTHER); - if (mBlobReady) { - if (mState == MUXING_DONE) { - mIsWritingComplete = true; - } - mBlobReady = false; - return mControl->GetBufs(aOutputBufs); - } - return NS_OK; -} - -nsresult -ISOMediaWriter::SetMetadata(TrackMetadataBase* aMetadata) -{ - PROFILER_LABEL("ISOMediaWriter", "SetMetadata", - js::ProfileEntry::Category::OTHER); - if (aMetadata->GetKind() == TrackMetadataBase::METADATA_AAC || - aMetadata->GetKind() == TrackMetadataBase::METADATA_AMR || - aMetadata->GetKind() == TrackMetadataBase::METADATA_EVRC) { - mControl->SetMetadata(aMetadata); - mAudioFragmentBuffer = new FragmentBuffer(Audio_Track, FRAG_DURATION); - mControl->SetFragment(mAudioFragmentBuffer); - return NS_OK; - } - if (aMetadata->GetKind() == TrackMetadataBase::METADATA_AVC) { - mControl->SetMetadata(aMetadata); - mVideoFragmentBuffer = new FragmentBuffer(Video_Track, FRAG_DURATION); - mControl->SetFragment(mVideoFragmentBuffer); - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - -} // namespace mozilla |