Remove other gonk widget conditionals and unused files.

Tag #288.
This commit is contained in:
wolfbeast 2018-05-13 22:46:04 +02:00 committed by Roy Tam
commit 74df182488
232 changed files with 256 additions and 36730 deletions

View file

@ -1,84 +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 "ISOControl.h"
#include "ISOMediaBoxes.h"
#include "AMRBox.h"
#include "ISOTrackMetadata.h"
namespace mozilla {
nsresult
AMRSampleEntry::Generate(uint32_t* aBoxSize)
{
uint32_t box_size;
nsresult rv = amr_special_box->Generate(&box_size);
NS_ENSURE_SUCCESS(rv, rv);
size += box_size;
*aBoxSize = size;
return NS_OK;
}
nsresult
AMRSampleEntry::Write()
{
BoxSizeChecker checker(mControl, size);
nsresult rv;
rv = AudioSampleEntry::Write();
NS_ENSURE_SUCCESS(rv, rv);
rv = amr_special_box->Write();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
AMRSampleEntry::AMRSampleEntry(ISOControl* aControl)
: AudioSampleEntry(NS_LITERAL_CSTRING("samr"), aControl)
{
amr_special_box = new AMRSpecificBox(aControl);
MOZ_COUNT_CTOR(AMRSampleEntry);
}
AMRSampleEntry::~AMRSampleEntry()
{
MOZ_COUNT_DTOR(AMRSampleEntry);
}
nsresult
AMRSpecificBox::Generate(uint32_t* aBoxSize)
{
nsresult rv;
FragmentBuffer* frag = mControl->GetFragment(Audio_Track);
rv = frag->GetCSD(amrDecSpecInfo);
NS_ENSURE_SUCCESS(rv, rv);
size += amrDecSpecInfo.Length();
*aBoxSize = size;
return NS_OK;
}
nsresult
AMRSpecificBox::Write()
{
BoxSizeChecker checker(mControl, size);
Box::Write();
mControl->Write(amrDecSpecInfo.Elements(), amrDecSpecInfo.Length());
return NS_OK;
}
AMRSpecificBox::AMRSpecificBox(ISOControl* aControl)
: Box(NS_LITERAL_CSTRING("damr"), aControl)
{
MOZ_COUNT_CTOR(AMRSpecificBox);
}
AMRSpecificBox::~AMRSpecificBox()
{
MOZ_COUNT_DTOR(AMRSpecificBox);
}
}

View file

@ -1,50 +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/. */
#ifndef AMRBOX_h_
#define AMRBOX_h_
#include "nsTArray.h"
#include "MuxerOperation.h"
namespace mozilla {
class ISOControl;
// 3GPP TS 26.244 6.7 'AMRSpecificBox field for AMRSampleEntry box'
// Box type: 'damr'
class AMRSpecificBox : public Box {
public:
// 3GPP members
nsTArray<uint8_t> amrDecSpecInfo;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// AMRSpecificBox methods
AMRSpecificBox(ISOControl* aControl);
~AMRSpecificBox();
};
// 3GPP TS 26.244 6.5 'AMRSampleEntry box'
// Box type: 'sawb'
class AMRSampleEntry : public AudioSampleEntry {
public:
// 3GPP members
RefPtr<AMRSpecificBox> amr_special_box;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// AMRSampleEntry methods
AMRSampleEntry(ISOControl* aControl);
~AMRSampleEntry();
};
}
#endif // AMRBOX_h_

View file

@ -1,87 +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 <climits>
#include "ISOControl.h"
#include "ISOMediaBoxes.h"
#include "AVCBox.h"
namespace mozilla {
nsresult
AVCSampleEntry::Generate(uint32_t* aBoxSize)
{
uint32_t avc_box_size = 0;
nsresult rv;
rv = avcConfigBox->Generate(&avc_box_size);
NS_ENSURE_SUCCESS(rv, rv);
size += avc_box_size;
*aBoxSize = size;
return NS_OK;
}
nsresult
AVCSampleEntry::Write()
{
BoxSizeChecker checker(mControl, size);
nsresult rv;
rv = VisualSampleEntry::Write();
NS_ENSURE_SUCCESS(rv, rv);
rv = avcConfigBox->Write();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
AVCSampleEntry::AVCSampleEntry(ISOControl* aControl)
: VisualSampleEntry(NS_LITERAL_CSTRING("avc1"), aControl)
{
avcConfigBox = new AVCConfigurationBox(aControl);
MOZ_COUNT_CTOR(AVCSampleEntry);
}
AVCSampleEntry::~AVCSampleEntry()
{
MOZ_COUNT_DTOR(AVCSampleEntry);
}
AVCConfigurationBox::AVCConfigurationBox(ISOControl* aControl)
: Box(NS_LITERAL_CSTRING("avcC"), aControl)
{
MOZ_COUNT_CTOR(AVCConfigurationBox);
}
AVCConfigurationBox::~AVCConfigurationBox()
{
MOZ_COUNT_DTOR(AVCConfigurationBox);
}
nsresult
AVCConfigurationBox::Generate(uint32_t* aBoxSize)
{
nsresult rv;
FragmentBuffer* frag = mControl->GetFragment(Video_Track);
rv = frag->GetCSD(avcConfig);
NS_ENSURE_SUCCESS(rv, rv);
size += avcConfig.Length();
*aBoxSize = size;
return NS_OK;
}
nsresult
AVCConfigurationBox::Write()
{
BoxSizeChecker checker(mControl, size);
Box::Write();
mControl->Write(avcConfig.Elements(), avcConfig.Length());
return NS_OK;
}
}

View file

@ -1,59 +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/. */
#ifndef AVCBox_h_
#define AVCBox_h_
#include "nsTArray.h"
#include "ISOMediaBoxes.h"
namespace mozilla {
class ISOControl;
// 14496-12 8.5.2.2
#define resolution_72_dpi 0x00480000
#define video_depth 0x0018
// 14496-15 5.3.4.1 'Sample description name and format'
// Box type: 'avcC'
class AVCConfigurationBox : public Box {
public:
// ISO BMFF members
// avcConfig is CodecSpecificData from 14496-15 '5.3.4.1 Sample description
// name and format.
// These data are generated by encoder and we encapsulated the generated
// bitstream into box directly.
nsTArray<uint8_t> avcConfig;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// AVCConfigurationBox methods
AVCConfigurationBox(ISOControl* aControl);
~AVCConfigurationBox();
};
// 14496-15 5.3.4.1 'Sample description name and format'
// Box type: 'avc1'
class AVCSampleEntry : public VisualSampleEntry {
public:
// ISO BMFF members
RefPtr<AVCConfigurationBox> avcConfigBox;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// VisualSampleEntry methods
AVCSampleEntry(ISOControl* aControl);
~AVCSampleEntry();
};
}
#endif // AVCBox_h_

View file

@ -1,84 +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 "ISOControl.h"
#include "ISOMediaBoxes.h"
#include "EVRCBox.h"
#include "ISOTrackMetadata.h"
namespace mozilla {
nsresult
EVRCSampleEntry::Generate(uint32_t* aBoxSize)
{
uint32_t box_size;
nsresult rv = evrc_special_box->Generate(&box_size);
NS_ENSURE_SUCCESS(rv, rv);
size += box_size;
*aBoxSize = size;
return NS_OK;
}
nsresult
EVRCSampleEntry::Write()
{
BoxSizeChecker checker(mControl, size);
nsresult rv;
rv = AudioSampleEntry::Write();
NS_ENSURE_SUCCESS(rv, rv);
rv = evrc_special_box->Write();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
EVRCSampleEntry::EVRCSampleEntry(ISOControl* aControl)
: AudioSampleEntry(NS_LITERAL_CSTRING("sevc"), aControl)
{
evrc_special_box = new EVRCSpecificBox(aControl);
MOZ_COUNT_CTOR(EVRCSampleEntry);
}
EVRCSampleEntry::~EVRCSampleEntry()
{
MOZ_COUNT_DTOR(EVRCSampleEntry);
}
nsresult
EVRCSpecificBox::Generate(uint32_t* aBoxSize)
{
nsresult rv;
FragmentBuffer* frag = mControl->GetFragment(Audio_Track);
rv = frag->GetCSD(evrcDecSpecInfo);
NS_ENSURE_SUCCESS(rv, rv);
size += evrcDecSpecInfo.Length();
*aBoxSize = size;
return NS_OK;
}
nsresult
EVRCSpecificBox::Write()
{
BoxSizeChecker checker(mControl, size);
Box::Write();
mControl->Write(evrcDecSpecInfo.Elements(), evrcDecSpecInfo.Length());
return NS_OK;
}
EVRCSpecificBox::EVRCSpecificBox(ISOControl* aControl)
: Box(NS_LITERAL_CSTRING("devc"), aControl)
{
MOZ_COUNT_CTOR(EVRCSpecificBox);
}
EVRCSpecificBox::~EVRCSpecificBox()
{
MOZ_COUNT_DTOR(EVRCSpecificBox);
}
}

View file

@ -1,50 +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/. */
#ifndef EVRCBOX_h_
#define EVRCBOX_h_
#include "nsTArray.h"
#include "MuxerOperation.h"
namespace mozilla {
class ISOControl;
// 3GPP TS 26.244 6.7 'EVRCSpecificBox field for EVRCSampleEntry box'
// Box type: 'devc'
class EVRCSpecificBox : public Box {
public:
// 3GPP members
nsTArray<uint8_t> evrcDecSpecInfo;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// EVRCSpecificBox methods
EVRCSpecificBox(ISOControl* aControl);
~EVRCSpecificBox();
};
// 3GPP TS 26.244 6.5 'EVRCSampleEntry box'
// Box type: 'sevc'
class EVRCSampleEntry : public AudioSampleEntry {
public:
// 3GPP members
RefPtr<EVRCSpecificBox> evrc_special_box;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// EVRCSampleEntry methods
EVRCSampleEntry(ISOControl* aControl);
~EVRCSampleEntry();
};
}
#endif // EVRCBOX_h_

View file

@ -1,415 +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 <time.h>
#include "nsAutoPtr.h"
#include "ISOControl.h"
#include "ISOMediaBoxes.h"
#include "EncodedFrameContainer.h"
namespace mozilla {
// For MP4 creation_time and modification_time offset from January 1, 1904 to
// January 1, 1970.
#define iso_time_offset 2082844800
FragmentBuffer::FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration)
: mTrackType(aTrackType)
, mFragDuration(aFragDuration)
, mMediaStartTime(0)
, mFragmentNumber(0)
, mLastFrameTimeOfLastFragment(0)
, mEOS(false)
{
mFragArray.AppendElement();
MOZ_COUNT_CTOR(FragmentBuffer);
}
FragmentBuffer::~FragmentBuffer()
{
MOZ_COUNT_DTOR(FragmentBuffer);
}
bool
FragmentBuffer::HasEnoughData()
{
// Audio or video frame is enough to form a moof.
return (mFragArray.Length() > 1);
}
nsresult
FragmentBuffer::GetCSD(nsTArray<uint8_t>& aCSD)
{
if (!mCSDFrame) {
return NS_ERROR_FAILURE;
}
aCSD.AppendElements(mCSDFrame->GetFrameData().Elements(),
mCSDFrame->GetFrameData().Length());
return NS_OK;
}
nsresult
FragmentBuffer::AddFrame(EncodedFrame* aFrame)
{
// already EOS, it rejects all new data.
if (mEOS) {
MOZ_ASSERT(0);
return NS_OK;
}
EncodedFrame::FrameType type = aFrame->GetFrameType();
if (type == EncodedFrame::AAC_CSD || type == EncodedFrame::AVC_CSD ||
type == EncodedFrame::AMR_AUDIO_CSD || type == EncodedFrame::EVRC_AUDIO_CSD) {
mCSDFrame = aFrame;
// Use CSD's timestamp as the start time. Encoder should send CSD frame first
// and then data frames.
mMediaStartTime = aFrame->GetTimeStamp();
mFragmentNumber = 1;
return NS_OK;
}
// if the timestamp is incorrect, abort it.
if (aFrame->GetTimeStamp() < mMediaStartTime) {
MOZ_ASSERT(false);
return NS_ERROR_FAILURE;
}
mFragArray.LastElement().AppendElement(aFrame);
// check if current fragment is reach the fragment duration.
if ((aFrame->GetTimeStamp() - mMediaStartTime) >= (mFragDuration * mFragmentNumber)) {
mFragArray.AppendElement();
mFragmentNumber++;
}
return NS_OK;
}
nsresult
FragmentBuffer::GetFirstFragment(nsTArray<RefPtr<EncodedFrame>>& aFragment,
bool aFlush)
{
// It should be called only if there is a complete fragment in mFragArray.
if (mFragArray.Length() <= 1 && !mEOS) {
MOZ_ASSERT(false);
return NS_ERROR_FAILURE;
}
if (aFlush) {
aFragment.SwapElements(mFragArray.ElementAt(0));
mFragArray.RemoveElementAt(0);
} else {
aFragment.AppendElements(mFragArray.ElementAt(0));
}
return NS_OK;
}
uint32_t
FragmentBuffer::GetFirstFragmentSampleNumber()
{
return mFragArray.ElementAt(0).Length();
}
uint32_t
FragmentBuffer::GetFirstFragmentSampleSize()
{
uint32_t size = 0;
uint32_t len = mFragArray.ElementAt(0).Length();
for (uint32_t i = 0; i < len; i++) {
size += mFragArray.ElementAt(0).ElementAt(i)->GetFrameData().Length();
}
return size;
}
ISOControl::ISOControl(uint32_t aMuxingType)
: mMuxingType(aMuxingType)
, mAudioFragmentBuffer(nullptr)
, mVideoFragmentBuffer(nullptr)
, mFragNum(0)
, mOutputSize(0)
, mBitCount(0)
, mBit(0)
{
// Create a data array for first mp4 Box, ftyp.
mOutBuffers.SetLength(1);
MOZ_COUNT_CTOR(ISOControl);
}
ISOControl::~ISOControl()
{
MOZ_COUNT_DTOR(ISOControl);
}
uint32_t
ISOControl::GetNextTrackID()
{
return (mMetaArray.Length() + 1);
}
uint32_t
ISOControl::GetTrackID(TrackMetadataBase::MetadataKind aKind)
{
for (uint32_t i = 0; i < mMetaArray.Length(); i++) {
if (mMetaArray[i]->GetKind() == aKind) {
return (i + 1);
}
}
// Track ID shouldn't be 0. It must be something wrong here.
MOZ_ASSERT(0);
return 0;
}
nsresult
ISOControl::SetMetadata(TrackMetadataBase* aTrackMeta)
{
if (aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AAC ||
aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AMR ||
aTrackMeta->GetKind() == TrackMetadataBase::METADATA_AVC ||
aTrackMeta->GetKind() == TrackMetadataBase::METADATA_EVRC) {
mMetaArray.AppendElement(aTrackMeta);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
ISOControl::GetAudioMetadata(RefPtr<AudioTrackMetadata>& aAudMeta)
{
for (uint32_t i = 0; i < mMetaArray.Length() ; i++) {
if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AAC ||
mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AMR ||
mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_EVRC) {
aAudMeta = static_cast<AudioTrackMetadata*>(mMetaArray[i].get());
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
nsresult
ISOControl::GetVideoMetadata(RefPtr<VideoTrackMetadata>& aVidMeta)
{
for (uint32_t i = 0; i < mMetaArray.Length() ; i++) {
if (mMetaArray[i]->GetKind() == TrackMetadataBase::METADATA_AVC) {
aVidMeta = static_cast<VideoTrackMetadata*>(mMetaArray[i].get());
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
bool
ISOControl::HasAudioTrack()
{
RefPtr<AudioTrackMetadata> audMeta;
GetAudioMetadata(audMeta);
return audMeta;
}
bool
ISOControl::HasVideoTrack()
{
RefPtr<VideoTrackMetadata> vidMeta;
GetVideoMetadata(vidMeta);
return vidMeta;
}
nsresult
ISOControl::SetFragment(FragmentBuffer* aFragment)
{
if (aFragment->GetType() == Audio_Track) {
mAudioFragmentBuffer = aFragment;
} else {
mVideoFragmentBuffer = aFragment;
}
return NS_OK;
}
FragmentBuffer*
ISOControl::GetFragment(uint32_t aType)
{
if (aType == Audio_Track) {
return mAudioFragmentBuffer;
} else if (aType == Video_Track){
return mVideoFragmentBuffer;
}
MOZ_ASSERT(0);
return nullptr;
}
nsresult
ISOControl::GetBufs(nsTArray<nsTArray<uint8_t>>* aOutputBufs)
{
uint32_t len = mOutBuffers.Length();
for (uint32_t i = 0; i < len; i++) {
mOutBuffers[i].SwapElements(*aOutputBufs->AppendElement());
}
return FlushBuf();
}
nsresult
ISOControl::FlushBuf()
{
mOutBuffers.SetLength(1);
return NS_OK;
}
uint32_t
ISOControl::WriteAVData(nsTArray<uint8_t>& aArray)
{
MOZ_ASSERT(!mBitCount);
uint32_t len = aArray.Length();
if (!len) {
return 0;
}
mOutputSize += len;
// The last element already has data, allocated a new element for pointer
// swapping.
if (mOutBuffers.LastElement().Length()) {
mOutBuffers.AppendElement();
}
// Swap the video/audio data pointer.
mOutBuffers.LastElement().SwapElements(aArray);
// Following data could be boxes, so appending a new uint8_t array here.
mOutBuffers.AppendElement();
return len;
}
uint32_t
ISOControl::WriteBits(uint64_t aBits, size_t aNumBits)
{
uint8_t output_byte = 0;
MOZ_ASSERT(aNumBits <= 64);
// TODO: rewritten following with bitset?
for (size_t i = aNumBits; i > 0; i--) {
mBit |= (((aBits >> (i - 1)) & 1) << (8 - ++mBitCount));
if (mBitCount == 8) {
Write(&mBit, sizeof(uint8_t));
mBit = 0;
mBitCount = 0;
output_byte++;
}
}
return output_byte;
}
uint32_t
ISOControl::Write(uint8_t* aBuf, uint32_t aSize)
{
mOutBuffers.LastElement().AppendElements(aBuf, aSize);
mOutputSize += aSize;
return aSize;
}
uint32_t
ISOControl::Write(uint8_t aData)
{
MOZ_ASSERT(!mBitCount);
Write((uint8_t*)&aData, sizeof(uint8_t));
return sizeof(uint8_t);
}
uint32_t
ISOControl::GetBufPos()
{
uint32_t len = mOutBuffers.Length();
uint32_t pos = 0;
for (uint32_t i = 0; i < len; i++) {
pos += mOutBuffers.ElementAt(i).Length();
}
return pos;
}
uint32_t
ISOControl::WriteFourCC(const char* aType)
{
// Bit operation should be aligned to byte before writing any byte data.
MOZ_ASSERT(!mBitCount);
uint32_t size = strlen(aType);
if (size == 4) {
return Write((uint8_t*)aType, size);
}
return 0;
}
nsresult
ISOControl::GenerateFtyp()
{
nsresult rv;
uint32_t size;
nsAutoPtr<FileTypeBox> type_box(new FileTypeBox(this));
rv = type_box->Generate(&size);
NS_ENSURE_SUCCESS(rv, rv);
rv = type_box->Write();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
ISOControl::GenerateMoov()
{
nsresult rv;
uint32_t size;
nsAutoPtr<MovieBox> moov_box(new MovieBox(this));
rv = moov_box->Generate(&size);
NS_ENSURE_SUCCESS(rv, rv);
rv = moov_box->Write();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
ISOControl::GenerateMoof(uint32_t aTrackType)
{
mFragNum++;
nsresult rv;
uint32_t size;
uint64_t first_sample_offset = mOutputSize;
nsAutoPtr<MovieFragmentBox> moof_box(new MovieFragmentBox(aTrackType, this));
nsAutoPtr<MediaDataBox> mdat_box(new MediaDataBox(aTrackType, this));
rv = moof_box->Generate(&size);
NS_ENSURE_SUCCESS(rv, rv);
first_sample_offset += size;
rv = mdat_box->Generate(&size);
NS_ENSURE_SUCCESS(rv, rv);
first_sample_offset += mdat_box->FirstSampleOffsetInMediaDataBox();
// correct offset info
nsTArray<RefPtr<MuxerOperation>> tfhds;
rv = moof_box->Find(NS_LITERAL_CSTRING("tfhd"), tfhds);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t len = tfhds.Length();
for (uint32_t i = 0; i < len; i++) {
TrackFragmentHeaderBox* tfhd = (TrackFragmentHeaderBox*) tfhds.ElementAt(i).get();
rv = tfhd->UpdateBaseDataOffset(first_sample_offset);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = moof_box->Write();
NS_ENSURE_SUCCESS(rv, rv);
rv = mdat_box->Write();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
uint32_t
ISOControl::GetTime()
{
return (uint64_t)time(nullptr) + iso_time_offset;
}
}

View file

@ -1,250 +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/. */
#ifndef ISOCOMPOSITOR_H_
#define ISOCOMPOSITOR_H_
#include "mozilla/EndianUtils.h"
#include "nsTArray.h"
#include "ISOTrackMetadata.h"
#include "EncodedFrameContainer.h"
namespace mozilla {
class Box;
class ISOControl;
/**
* This class collects elementary stream data to form a fragment.
* ISOMediaWriter will check if the data is enough; if yes, the corresponding
* moof will be created and write to ISOControl.
* Each audio and video has its own fragment and only one during the whole
* life cycle, when a fragment is formed in ISOControl, Flush() needs to
* be called to reset it.
*/
class FragmentBuffer {
public:
// aTrackType: it could be Audio_Track or Video_Track.
// aFragDuration: it is the fragment duration. (microsecond per unit)
// Audio and video have the same fragment duration.
FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration);
~FragmentBuffer();
// Get samples of first fragment, that will swap all the elements in the
// mFragArray[0] when aFlush = true, and caller is responsible for drop
// EncodedFrame reference count.
nsresult GetFirstFragment(nsTArray<RefPtr<EncodedFrame>>& aFragment,
bool aFlush = false);
// Add sample frame to the last element fragment of mFragArray. If sample
// number is enough, it will append a new fragment element. And the new
// sample will be added to the new fragment element of mFragArray.
nsresult AddFrame(EncodedFrame* aFrame);
// Get total sample size of first complete fragment size.
uint32_t GetFirstFragmentSampleSize();
// Get sample number of first complete fragment.
uint32_t GetFirstFragmentSampleNumber();
// Check if it accumulates enough frame data.
// It returns true when data is enough to form a fragment.
bool HasEnoughData();
// Called by ISOMediaWriter when TrackEncoder has sent the last frame. The
// remains frame data will form the last moof and move the state machine to
// in ISOMediaWriter to last phrase.
nsresult SetEndOfStream() {
mEOS = true;
return NS_OK;
}
bool EOS() { return mEOS; }
// CSD (codec specific data), it is generated by encoder and the data depends
// on codec type. This data will be sent as a special frame from encoder to
// ISOMediaWriter and pass to this class via AddFrame().
nsresult GetCSD(nsTArray<uint8_t>& aCSD);
bool HasCSD() { return mCSDFrame; }
uint32_t GetType() { return mTrackType; }
void SetLastFragmentLastFrameTime(uint32_t aTime) {
mLastFrameTimeOfLastFragment = aTime;
}
uint32_t GetLastFragmentLastFrameTime() {
return mLastFrameTimeOfLastFragment;
}
private:
uint32_t mTrackType;
// Fragment duration, microsecond per unit.
uint32_t mFragDuration;
// Media start time, microsecond per unit.
// Together with mFragDuration, mFragmentNumber and EncodedFrame->GetTimeStamp(),
// when the difference between current frame time and mMediaStartTime is
// exceeded current fragment ceiling timeframe, that means current fragment has
// enough data and a new element in mFragArray will be added.
uint64_t mMediaStartTime;
// Current fragment number. It will be increase when a new element of
// mFragArray is created.
// Note:
// It only means the fragment number of current accumulated frames, not
// the current 'creating' fragment mFragNum in ISOControl.
uint32_t mFragmentNumber;
// The last frame time stamp of last fragment. It is for calculating the
// play duration of first frame in current fragment. The frame duration is
// defined as "current frame timestamp - last frame timestamp" here. So it
// needs to keep the last timestamp of last fragment.
uint32_t mLastFrameTimeOfLastFragment;
// Array of fragments, each element has enough samples to form a
// complete fragment.
nsTArray<nsTArray<RefPtr<EncodedFrame>>> mFragArray;
// Codec specific data frame, it will be generated by encoder and send to
// ISOMediaWriter through WriteEncodedTrack(). The data will be vary depends
// on codec type.
RefPtr<EncodedFrame> mCSDFrame;
// END_OF_STREAM from ContainerWriter
bool mEOS;
};
/**
* ISOControl will be carried to each box when box is created. It is the main
* bridge for box to output stream to ContainerWriter and retrieve information.
* ISOControl acts 3 different roles:
* 1. Holds the pointer of audio metadata, video metadata, fragment and
* pass them to boxes.
* 2. Provide the functions to generate the base structure of MP4; they are
* GenerateFtyp, GenerateMoov, GenerateMoof, and GenerateMfra.
* 3. The actually writer used by MuxOperation::Write() in each box. It provides
* writing methods for different kind of data; they are Write, WriteArray,
* WriteBits...etc.
*/
class ISOControl {
friend class Box;
public:
ISOControl(uint32_t aMuxingType);
~ISOControl();
nsresult GenerateFtyp();
nsresult GenerateMoov();
nsresult GenerateMoof(uint32_t aTrackType);
// Swap elementary stream pointer to output buffers.
uint32_t WriteAVData(nsTArray<uint8_t>& aArray);
uint32_t Write(uint8_t* aBuf, uint32_t aSize);
uint32_t Write(uint8_t aData);
template <typename T>
uint32_t Write(T aData) {
MOZ_ASSERT(!mBitCount);
aData = NativeEndian::swapToNetworkOrder(aData);
Write((uint8_t*)&aData, sizeof(T));
return sizeof(T);
}
template <typename T>
uint32_t WriteArray(const T &aArray, uint32_t aSize) {
MOZ_ASSERT(!mBitCount);
uint32_t size = 0;
for (uint32_t i = 0; i < aSize; i++) {
size += Write(aArray[i]);
}
return size;
}
uint32_t WriteFourCC(const char* aType);
// Bit writing. Note: it needs to be byte-boundary before using
// others non-bit writing function.
uint32_t WriteBits(uint64_t aBits, size_t aNumBits);
// This is called by GetContainerData and swap all the buffers to aOutputBuffers.
nsresult GetBufs(nsTArray<nsTArray<uint8_t>>* aOutputBufs);
// Presentation time in seconds since midnight, Jan. 1, 1904, in UTC time.
uint32_t GetTime();
// current fragment number
uint32_t GetCurFragmentNumber() { return mFragNum; }
nsresult SetFragment(FragmentBuffer* aFragment);
FragmentBuffer* GetFragment(uint32_t aType);
uint32_t GetMuxingType() { return mMuxingType; }
nsresult SetMetadata(TrackMetadataBase* aTrackMeta);
nsresult GetAudioMetadata(RefPtr<AudioTrackMetadata>& aAudMeta);
nsresult GetVideoMetadata(RefPtr<VideoTrackMetadata>& aVidMeta);
// Track ID is the Metadata index in mMetaArray. It allows only 1 audio
// track and 1 video track in this muxer. In this muxer, it is prohibt to have
// mutiple audio track or video track in the same file.
uint32_t GetTrackID(TrackMetadataBase::MetadataKind aKind);
uint32_t GetNextTrackID();
bool HasAudioTrack();
bool HasVideoTrack();
private:
uint32_t GetBufPos();
nsresult FlushBuf();
// One of value in TYPE_XXX, defined in ISOMediaWriter.
uint32_t mMuxingType;
// Audio and video fragments are owned by ISOMediaWriter.
// They don't need to worry about pointer going stale because ISOMediaWriter's
// lifetime is longer than ISOControl.
FragmentBuffer* mAudioFragmentBuffer;
FragmentBuffer* mVideoFragmentBuffer;
// Generated fragment number
uint32_t mFragNum;
// The (index + 1) will be the track ID.
nsTArray<RefPtr<TrackMetadataBase>> mMetaArray;
// Array of output buffers.
// To save memory usage, audio/video sample will be swapped into a new element
// of this array.
//
// For example,
// mOutBuffers[0] --> boxes (allocated by muxer)
// mOutBuffers[1] --> video raw data (allocated by encoder)
// mOutBuffers[2] --> video raw data (allocated by encoder)
// mOutBuffers[3] --> video raw data (allocated by encoder)
// mOutBuffers[4] --> boxes (allocated by muxer)
// mOutBuffers[5] --> audio raw data (allocated by encoder)
// ...etc.
//
nsTArray<nsTArray<uint8_t>> mOutBuffers;
// Accumulate output size from Write().
uint64_t mOutputSize;
// Bit writing operation. Note: the mBitCount should be 0 before any
// byte-boundary writing method be called (Write(uint32_t), Write(uint16_t)...etc);
// otherwise, there will be assertion on these functions.
uint8_t mBitCount;
uint8_t mBit;
};
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,781 +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/. */
#ifndef ISOMediaBoxes_h_
#define ISOMediaBoxes_h_
#include <bitset>
#include "nsString.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "MuxerOperation.h"
#include "mozilla/UniquePtr.h"
#define WRITE_FULLBOX(_compositor, _size) \
BoxSizeChecker checker(_compositor, _size); \
FullBox::Write();
#define FOURCC(a, b, c, d) ( ((a) << 24) | ((b) << 16) | ((c) << 8) | (d) )
namespace mozilla {
/**
* track type from spec 8.4.3.3
*/
#define Audio_Track 0x01
#define Video_Track 0x02
class AudioTrackMetadata;
class VideoTrackMetadata;
class ISOControl;
/**
* This is the base class for all ISO media format boxes.
* It provides the fields of box type(four CC) and size.
* The data members in the beginning of a Box (or its descendants)
* are the 14496-12 defined member. Other members prefix with 'm'
* are private control data.
*
* This class is for inherited only, it shouldn't be instanced directly.
*/
class Box : public MuxerOperation {
protected:
// ISO BMFF members
uint32_t size; // 14496-12 4-2 'Object Structure'. Size of this box.
nsCString boxType; // four CC name, all table names are listed in
// 14496-12 table 1.
public:
// MuxerOperation methods
nsresult Write() override;
nsresult Find(const nsACString& aType,
nsTArray<RefPtr<MuxerOperation>>& aOperations) override;
// This helper class will compare the written size in Write() and the size in
// Generate(). If their are not equal, it will assert.
class BoxSizeChecker {
public:
BoxSizeChecker(ISOControl* aControl, uint32_t aSize);
~BoxSizeChecker();
uint32_t ori_size;
uint32_t box_size;
ISOControl* mControl;
};
protected:
Box() = delete;
Box(const nsACString& aType, ISOControl* aControl);
ISOControl* mControl;
RefPtr<AudioTrackMetadata> mAudioMeta;
RefPtr<VideoTrackMetadata> mVideoMeta;
};
/**
* FullBox (and its descendants) is the box which contains the 'real' data
* members. It is the edge in the ISO box structure and it doesn't contain
* any box.
*
* This class is for inherited only, it shouldn't be instanced directly.
*/
class FullBox : public Box {
public:
// ISO BMFF members
uint8_t version; // 14496-12 4.2 'Object Structure'
std::bitset<24> flags; //
// MuxerOperation methods
nsresult Write() override;
protected:
// FullBox methods
FullBox(const nsACString& aType, uint8_t aVersion, uint32_t aFlags,
ISOControl* aControl);
FullBox() = delete;
};
/**
* The default implementation of the container box.
* Basically, the container box inherits this class and overrides the
* constructor only.
*
* According to 14496-12 3.1.1 'container box', a container box is
* 'box whose sole purpose is to contain and group a set of related boxes'
*
* This class is for inherited only, it shouldn't be instanced directly.
*/
class DefaultContainerImpl : public Box {
public:
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
nsresult Find(const nsACString& aType,
nsTArray<RefPtr<MuxerOperation>>& aOperations) override;
protected:
// DefaultContainerImpl methods
DefaultContainerImpl(const nsACString& aType, ISOControl* aControl);
DefaultContainerImpl() = delete;
nsTArray<RefPtr<MuxerOperation>> boxes;
};
// 14496-12 4.3 'File Type Box'
// Box type: 'ftyp'
class FileTypeBox : public Box {
public:
// ISO BMFF members
nsCString major_brand; // four chars
uint32_t minor_version;
nsTArray<nsCString> compatible_brands;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// FileTypeBox methods
FileTypeBox(ISOControl* aControl);
~FileTypeBox();
};
// 14496-12 8.2.1 'Movie Box'
// Box type: 'moov'
// MovieBox contains MovieHeaderBox, TrackBox and MovieExtendsBox.
class MovieBox : public DefaultContainerImpl {
public:
MovieBox(ISOControl* aControl);
~MovieBox();
};
// 14496-12 8.2.2 'Movie Header Box'
// Box type: 'mvhd'
class MovieHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t creation_time;
uint32_t modification_time;
uint32_t timescale;
uint32_t duration;
uint32_t rate;
uint16_t volume;
uint16_t reserved16;
uint32_t reserved32[2];
uint32_t matrix[9];
uint32_t pre_defined[6];
uint32_t next_track_ID;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MovieHeaderBox methods
MovieHeaderBox(ISOControl* aControl);
~MovieHeaderBox();
uint32_t GetTimeScale();
};
// 14496-12 8.4.2 'Media Header Box'
// Box type: 'mdhd'
class MediaHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t creation_time;
uint32_t modification_time;
uint32_t timescale;
uint32_t duration;
std::bitset<1> pad;
std::bitset<5> lang1;
std::bitset<5> lang2;
std::bitset<5> lang3;
uint16_t pre_defined;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MediaHeaderBox methods
MediaHeaderBox(uint32_t aType, ISOControl* aControl);
~MediaHeaderBox();
uint32_t GetTimeScale();
protected:
uint32_t mTrackType;
};
// 14496-12 8.3.1 'Track Box'
// Box type: 'trak'
// TrackBox contains TrackHeaderBox and MediaBox.
class TrackBox : public DefaultContainerImpl {
public:
TrackBox(uint32_t aTrackType, ISOControl* aControl);
~TrackBox();
};
// 14496-12 8.1.1 'Media Data Box'
// Box type: 'mdat'
class MediaDataBox : public Box {
public:
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MediaDataBox methods
uint32_t GetAllSampleSize() { return mAllSampleSize; }
uint32_t FirstSampleOffsetInMediaDataBox() { return mFirstSampleOffset; }
MediaDataBox(uint32_t aTrackType, ISOControl* aControl);
~MediaDataBox();
protected:
uint32_t mAllSampleSize; // All audio and video sample size in this box.
uint32_t mFirstSampleOffset; // The offset of first sample in this box from
// the beginning of this mp4 file.
uint32_t mTrackType;
};
// flags for TrackRunBox::flags, 14496-12 8.8.8.1.
#define flags_data_offset_present 0x000001
#define flags_first_sample_flags_present 0x000002
#define flags_sample_duration_present 0x000100
#define flags_sample_size_present 0x000200
#define flags_sample_flags_present 0x000400
#define flags_sample_composition_time_offsets_present 0x000800
// flag for TrackRunBox::tbl::sample_flags and TrackExtendsBox::default_sample_flags
// which is defined in 14496-12 8.8.3.1.
uint32_t set_sample_flags(bool aSync);
// 14496-12 8.8.8 'Track Fragment Run Box'
// Box type: 'trun'
class TrackRunBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t sample_duration;
uint32_t sample_size;
uint32_t sample_flags;
uint32_t sample_composition_time_offset;
} tbl;
uint32_t sample_count;
// the following are optional fields
uint32_t data_offset; // data offset exists when audio/video are present in file.
uint32_t first_sample_flags;
UniquePtr<tbl[]> sample_info_table;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackRunBox methods
uint32_t GetAllSampleSize() { return mAllSampleSize; }
nsresult SetDataOffset(uint32_t aOffset);
TrackRunBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl);
~TrackRunBox();
protected:
uint32_t fillSampleTable();
uint32_t mAllSampleSize;
uint32_t mTrackType;
};
// tf_flags in TrackFragmentHeaderBox, 14496-12 8.8.7.1.
#define base_data_offset_present 0x000001
#define sample_description_index_present 0x000002
#define default_sample_duration_present 0x000008
#define default_sample_size_present 0x000010
#define default_sample_flags_present 0x000020
#define duration_is_empty 0x010000
#define default_base_is_moof 0x020000
// 14496-12 8.8.7 'Track Fragment Header Box'
// Box type: 'tfhd'
class TrackFragmentHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t track_ID;
uint64_t base_data_offset;
uint32_t default_sample_duration;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackFragmentHeaderBox methods
nsresult UpdateBaseDataOffset(uint64_t aOffset); // The offset of the first
// sample in file.
TrackFragmentHeaderBox(uint32_t aType, uint32_t aFlags, ISOControl* aControl);
~TrackFragmentHeaderBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.6 'Track Fragment Box'
// Box type: 'traf'
// TrackFragmentBox cotains TrackFragmentHeaderBox and TrackRunBox.
class TrackFragmentBox : public DefaultContainerImpl {
public:
TrackFragmentBox(uint32_t aType, ISOControl* aControl);
~TrackFragmentBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.5 'Movie Fragment Header Box'
// Box type: 'mfhd'
class MovieFragmentHeaderBox : public FullBox {
public:
// ISO BMFF members
uint32_t sequence_number;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MovieFragmentHeaderBox methods
MovieFragmentHeaderBox(uint32_t aType, ISOControl* aControl);
~MovieFragmentHeaderBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.4 'Movie Fragment Box'
// Box type: 'moof'
// MovieFragmentBox contains MovieFragmentHeaderBox and TrackFragmentBox.
class MovieFragmentBox : public DefaultContainerImpl {
public:
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
// MovieFragmentBox methods
MovieFragmentBox(uint32_t aType, ISOControl* aControl);
~MovieFragmentBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.3 'Track Extends Box'
// Box type: 'trex'
class TrackExtendsBox : public FullBox {
public:
// ISO BMFF members
uint32_t track_ID;
uint32_t default_sample_description_index;
uint32_t default_sample_duration;
uint32_t default_sample_size;
uint32_t default_sample_flags;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackExtendsBox methods
TrackExtendsBox(uint32_t aType, ISOControl* aControl);
~TrackExtendsBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.8.1 'Movie Extends Box'
// Box type: 'mvex'
// MovieExtendsBox contains TrackExtendsBox.
class MovieExtendsBox : public DefaultContainerImpl {
public:
MovieExtendsBox(ISOControl* aControl);
~MovieExtendsBox();
};
// 14496-12 8.7.5 'Chunk Offset Box'
// Box type: 'stco'
class ChunkOffsetBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t chunk_offset;
} tbl;
uint32_t entry_count;
UniquePtr<tbl[]> sample_tbl;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// ChunkOffsetBox methods
ChunkOffsetBox(uint32_t aType, ISOControl* aControl);
~ChunkOffsetBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.7.4 'Sample To Chunk Box'
// Box type: 'stsc'
class SampleToChunkBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t first_chunk;
uint32_t sample_per_chunk;
uint32_t sample_description_index;
} tbl;
uint32_t entry_count;
UniquePtr<tbl[]> sample_tbl;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SampleToChunkBox methods
SampleToChunkBox(uint32_t aType, ISOControl* aControl);
~SampleToChunkBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.6.1.2 'Decoding Time to Sample Box'
// Box type: 'stts'
class TimeToSampleBox : public FullBox {
public:
// ISO BMFF members
typedef struct {
uint32_t sample_count;
uint32_t sample_delta;
} tbl;
uint32_t entry_count;
UniquePtr<tbl[]> sample_tbl;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TimeToSampleBox methods
TimeToSampleBox(uint32_t aType, ISOControl* aControl);
~TimeToSampleBox();
protected:
uint32_t mTrackType;
};
/**
* 14496-12 8.5.2 'Sample Description Box'
* This is the base class for VisualSampleEntry and AudioSampleEntry.
*
* This class is for inherited only, it shouldn't be instanced directly.
*
* The inhertied tree of a codec box should be:
*
* +--> AVCSampleEntry
* +--> VisualSampleEntryBox +
* | +--> ...
* SampleEntryBox +
* | +--> MP4AudioSampleEntry
* +--> AudioSampleEntryBox +
* +--> AMRSampleEntry
* +
* +--> ...
*
*/
class SampleEntryBox : public Box {
public:
// ISO BMFF members
uint8_t reserved[6];
uint16_t data_reference_index;
// sampleentrybox methods
SampleEntryBox(const nsACString& aFormat, ISOControl* aControl);
// MuxerOperation methods
nsresult Write() override;
protected:
SampleEntryBox() = delete;
};
// 14496-12 8.5.2 'Sample Description Box'
// Box type: 'stsd'
class SampleDescriptionBox : public FullBox {
public:
// ISO BMFF members
uint32_t entry_count;
RefPtr<SampleEntryBox> sample_entry_box;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SampleDescriptionBox methods
SampleDescriptionBox(uint32_t aType, ISOControl* aControl);
~SampleDescriptionBox();
protected:
nsresult CreateAudioSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry);
nsresult CreateVideoSampleEntry(RefPtr<SampleEntryBox>& aSampleEntry);
uint32_t mTrackType;
};
// 14496-12 8.5.2.2
// The base class for audio codec box.
// This class is for inherited only, it shouldn't be instanced directly.
class AudioSampleEntry : public SampleEntryBox {
public:
// ISO BMFF members
uint16_t sound_version;
uint8_t reserved2[6];
uint16_t channels;
uint16_t sample_size;
uint16_t compressionId;
uint16_t packet_size;
uint32_t timeScale; // (sample rate of media) <<16
// MuxerOperation methods
nsresult Write() override;
~AudioSampleEntry();
protected:
AudioSampleEntry(const nsACString& aFormat, ISOControl* aControl);
};
// 14496-12 8.5.2.2
// The base class for video codec box.
// This class is for inherited only, it shouldn't be instanced directly.
class VisualSampleEntry : public SampleEntryBox {
public:
// ISO BMFF members
uint8_t reserved[16];
uint16_t width;
uint16_t height;
uint32_t horizresolution; // 72 dpi
uint32_t vertresolution; // 72 dpi
uint32_t reserved2;
uint16_t frame_count; // 1, defined in 14496-12 8.5.2.2
uint8_t compressorName[32];
uint16_t depth; // 0x0018, defined in 14496-12 8.5.2.2;
uint16_t pre_defined; // -1, defined in 14496-12 8.5.2.2;
// MuxerOperation methods
nsresult Write() override;
// VisualSampleEntry methods
~VisualSampleEntry();
protected:
VisualSampleEntry(const nsACString& aFormat, ISOControl* aControl);
};
// 14496-12 8.7.3.2 'Sample Size Box'
// Box type: 'stsz'
class SampleSizeBox : public FullBox {
public:
// ISO BMFF members
uint32_t sample_size;
uint32_t sample_count;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SampleSizeBox methods
SampleSizeBox(ISOControl* aControl);
~SampleSizeBox();
};
// 14496-12 8.5.1 'Sample Table Box'
// Box type: 'stbl'
//
// SampleTableBox contains SampleDescriptionBox,
// TimeToSampleBox,
// SampleToChunkBox,
// SampleSizeBox and
// ChunkOffsetBox.
class SampleTableBox : public DefaultContainerImpl {
public:
SampleTableBox(uint32_t aType, ISOControl* aControl);
~SampleTableBox();
};
// 14496-12 8.7.2 'Data Reference Box'
// Box type: 'url '
class DataEntryUrlBox : public FullBox {
public:
// ISO BMFF members
// flags in DataEntryUrlBox::flags
const static uint16_t flags_media_at_the_same_file = 0x0001;
nsCString location;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// DataEntryUrlBox methods
DataEntryUrlBox();
DataEntryUrlBox(ISOControl* aControl);
DataEntryUrlBox(const DataEntryUrlBox& aBox);
~DataEntryUrlBox();
};
// 14496-12 8.7.2 'Data Reference Box'
// Box type: 'dref'
class DataReferenceBox : public FullBox {
public:
// ISO BMFF members
uint32_t entry_count;
nsTArray<nsAutoPtr<DataEntryUrlBox>> urls;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// DataReferenceBox methods
DataReferenceBox(ISOControl* aControl);
~DataReferenceBox();
};
// 14496-12 8.7.1 'Data Information Box'
// Box type: 'dinf'
// DataInformationBox contains DataReferenceBox.
class DataInformationBox : public DefaultContainerImpl {
public:
DataInformationBox(ISOControl* aControl);
~DataInformationBox();
};
// 14496-12 8.4.5.2 'Video Media Header Box'
// Box type: 'vmhd'
class VideoMediaHeaderBox : public FullBox {
public:
// ISO BMFF members
uint16_t graphicsmode;
uint16_t opcolor[3];
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// VideoMediaHeaderBox methods
VideoMediaHeaderBox(ISOControl* aControl);
~VideoMediaHeaderBox();
};
// 14496-12 8.4.5.3 'Sound Media Header Box'
// Box type: 'smhd'
class SoundMediaHeaderBox : public FullBox {
public:
// ISO BMFF members
uint16_t balance;
uint16_t reserved;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// SoundMediaHeaderBox methods
SoundMediaHeaderBox(ISOControl* aControl);
~SoundMediaHeaderBox();
};
// 14496-12 8.4.4 'Media Information Box'
// Box type: 'minf'
// MediaInformationBox contains SoundMediaHeaderBox, DataInformationBox and
// SampleTableBox.
class MediaInformationBox : public DefaultContainerImpl {
public:
MediaInformationBox(uint32_t aType, ISOControl* aControl);
~MediaInformationBox();
protected:
uint32_t mTrackType;
};
// flags for TrackHeaderBox::flags.
#define flags_track_enabled 0x000001
#define flags_track_in_movie 0x000002
#define flags_track_in_preview 0x000004
// 14496-12 8.3.2 'Track Header Box'
// Box type: 'tkhd'
class TrackHeaderBox : public FullBox {
public:
// ISO BMFF members
// version = 0
uint32_t creation_time;
uint32_t modification_time;
uint32_t track_ID;
uint32_t reserved;
uint32_t duration;
uint32_t reserved2[2];
uint16_t layer;
uint16_t alternate_group;
uint16_t volume;
uint16_t reserved3;
uint32_t matrix[9];
uint32_t width;
uint32_t height;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// TrackHeaderBox methods
TrackHeaderBox(uint32_t aType, ISOControl* aControl);
~TrackHeaderBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.4.3 'Handler Reference Box'
// Box type: 'hdlr'
class HandlerBox : public FullBox {
public:
// ISO BMFF members
uint32_t pre_defined;
uint32_t handler_type;
uint32_t reserved[3];
nsCString name;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// HandlerBox methods
HandlerBox(uint32_t aType, ISOControl* aControl);
~HandlerBox();
protected:
uint32_t mTrackType;
};
// 14496-12 8.4.1 'Media Box'
// Box type: 'mdia'
// MediaBox contains MediaHeaderBox, HandlerBox, and MediaInformationBox.
class MediaBox : public DefaultContainerImpl {
public:
MediaBox(uint32_t aType, ISOControl* aControl);
~MediaBox();
protected:
uint32_t mTrackType;
};
}
#endif // ISOMediaBoxes_h_

View file

@ -1,229 +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
#define LOG(args, ...)
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

View file

@ -1,108 +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/. */
#ifndef ISOMediaWriter_h_
#define ISOMediaWriter_h_
#include "ContainerWriter.h"
#include "nsAutoPtr.h"
#include "nsIRunnable.h"
namespace mozilla {
class ISOControl;
class FragmentBuffer;
class ISOMediaWriter : public ContainerWriter
{
public:
// Generate an fragmented MP4 stream, ISO/IEC 14496-12.
// Brand names in 'ftyp' box are 'isom' and 'mp42'.
const static uint32_t TYPE_FRAG_MP4 = 1 << 0;
// Generate an fragmented 3GP stream, 3GPP TS 26.244,
// '5.4.3 Basic profile'.
// Brand names in 'ftyp' box are '3gp9' and 'isom'.
const static uint32_t TYPE_FRAG_3GP = 1 << 1;
// Generate an fragmented 3G2 stream, 3GPP2 C.S0050-B
// Brand names in 'ftyp' box are '3g2c' and 'isom'
const static uint32_t TYPE_FRAG_3G2 = 1 << 2;
// aType is the combination of CREATE_AUDIO_TRACK and CREATE_VIDEO_TRACK.
// It is a hint to muxer that the output streaming contains audio, video
// or both.
//
// aHint is one of the value in TYPE_XXXXXXXX. It is a hint to muxer what kind
// of ISO format should be generated.
ISOMediaWriter(uint32_t aType, uint32_t aHint = TYPE_FRAG_MP4);
~ISOMediaWriter();
// ContainerWriter methods
nsresult WriteEncodedTrack(const EncodedFrameContainer &aData,
uint32_t aFlags = 0) override;
nsresult GetContainerData(nsTArray<nsTArray<uint8_t>>* aOutputBufs,
uint32_t aFlags = 0) override;
nsresult SetMetadata(TrackMetadataBase* aMetadata) override;
protected:
/**
* The state of each state will generate one or more blob.
* Each blob will be a moov, moof, moof... until receiving EOS.
* The generated sequence is:
*
* moov -> moof -> moof -> ... -> moof -> moof
*
* Following is the details of each state.
* MUXING_HEAD:
* It collects the metadata to generate a moov. The state transits to
* MUXING_HEAD after output moov blob.
*
* MUXING_FRAG:
* It collects enough audio/video data to generate a fragment blob. This
* will be repeated until END_OF_STREAM and then transiting to MUXING_DONE.
*
* MUXING_DONE:
* End of ISOMediaWriter life cycle.
*/
enum MuxState {
MUXING_HEAD,
MUXING_FRAG,
MUXING_DONE,
};
private:
nsresult RunState();
// True if one of following conditions hold:
// 1. Audio/Video accumulates enough data to generate a moof.
// 2. Get EOS signal.
// aEOS will be assigned to true if it gets EOS signal.
bool ReadyToRunState(bool& aEOS);
// The main class to generate and iso box. Its life time is same as
// ISOMediaWriter and deleted only if ISOMediaWriter is destroyed.
nsAutoPtr<ISOControl> mControl;
// Buffers to keep audio/video data frames, they are created when metadata is
// received. Only one instance for each media type is allowed and they will be
// deleted only if ISOMediaWriter is destroyed.
nsAutoPtr<FragmentBuffer> mAudioFragmentBuffer;
nsAutoPtr<FragmentBuffer> mVideoFragmentBuffer;
MuxState mState;
// A flag to indicate the output buffer is ready to blob out.
bool mBlobReady;
// Combination of Audio_Track or Video_Track.
uint32_t mType;
};
} // namespace mozilla
#endif // ISOMediaWriter_h_

View file

@ -1,131 +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/. */
#ifndef ISOTrackMetadata_h_
#define ISOTrackMetadata_h_
#include "TrackMetadataBase.h"
namespace mozilla {
class AACTrackMetadata : public AudioTrackMetadata {
public:
// AudioTrackMetadata members
uint32_t GetAudioFrameDuration() override { return mFrameDuration; }
uint32_t GetAudioFrameSize() override { return mFrameSize; }
uint32_t GetAudioSampleRate() override { return mSampleRate; }
uint32_t GetAudioChannels() override { return mChannels; }
// TrackMetadataBase member
MetadataKind GetKind() const override { return METADATA_AAC; }
// AACTrackMetadata members
AACTrackMetadata()
: mSampleRate(0)
, mFrameDuration(0)
, mFrameSize(0)
, mChannels(0) {
MOZ_COUNT_CTOR(AACTrackMetadata);
}
~AACTrackMetadata() { MOZ_COUNT_DTOR(AACTrackMetadata); }
uint32_t mSampleRate; // From 14496-3 table 1.16, it could be 7350 ~ 96000.
uint32_t mFrameDuration; // Audio frame duration based on SampleRate.
uint32_t mFrameSize; // Audio frame size, 0 is variant size.
uint32_t mChannels; // Channel number, it should be 1 or 2.
};
// AVC clock rate is 90k Hz.
#define AVC_CLOCK_RATE 90000
class AVCTrackMetadata : public VideoTrackMetadata {
public:
// VideoTrackMetadata members
uint32_t GetVideoHeight() override { return mHeight; }
uint32_t GetVideoWidth() override {return mWidth; }
uint32_t GetVideoDisplayHeight() override { return mDisplayHeight; }
uint32_t GetVideoDisplayWidth() override { return mDisplayWidth; }
uint32_t GetVideoClockRate() override { return AVC_CLOCK_RATE; }
uint32_t GetVideoFrameRate() override { return mFrameRate; }
// TrackMetadataBase member
MetadataKind GetKind() const override { return METADATA_AVC; }
// AVCTrackMetadata
AVCTrackMetadata()
: mHeight(0)
, mWidth(0)
, mDisplayHeight(0)
, mDisplayWidth(0)
, mFrameRate(0) {
MOZ_COUNT_CTOR(AVCTrackMetadata);
}
~AVCTrackMetadata() { MOZ_COUNT_DTOR(AVCTrackMetadata); }
uint32_t mHeight;
uint32_t mWidth;
uint32_t mDisplayHeight;
uint32_t mDisplayWidth;
uint32_t mFrameRate; // frames per second
};
// AMR sample rate is 8000 samples/s.
#define AMR_SAMPLE_RATE 8000
// Channel number is always 1.
#define AMR_CHANNELS 1
// AMR speech codec, 3GPP TS 26.071. Encoder and continer support AMR-NB only
// currently.
class AMRTrackMetadata : public AudioTrackMetadata {
public:
// AudioTrackMetadata members
//
// The number of sample sets generates by encoder is variant. So the
// frame duration and frame size are both 0.
uint32_t GetAudioFrameDuration() override { return 0; }
uint32_t GetAudioFrameSize() override { return 0; }
uint32_t GetAudioSampleRate() override { return AMR_SAMPLE_RATE; }
uint32_t GetAudioChannels() override { return AMR_CHANNELS; }
// TrackMetadataBase member
MetadataKind GetKind() const override { return METADATA_AMR; }
// AMRTrackMetadata members
AMRTrackMetadata() { MOZ_COUNT_CTOR(AMRTrackMetadata); }
~AMRTrackMetadata() { MOZ_COUNT_DTOR(AMRTrackMetadata); }
};
// EVRC sample rate is 8000 samples/s.
#define EVRC_SAMPLE_RATE 8000
class EVRCTrackMetadata : public AudioTrackMetadata {
public:
// AudioTrackMetadata members
//
// The number of sample sets generates by encoder is variant. So the
// frame duration and frame size are both 0.
uint32_t GetAudioFrameDuration() override { return 0; }
uint32_t GetAudioFrameSize() override { return 0; }
uint32_t GetAudioSampleRate() override { return EVRC_SAMPLE_RATE; }
uint32_t GetAudioChannels() override { return mChannels; }
// TrackMetadataBase member
MetadataKind GetKind() const override { return METADATA_EVRC; }
// EVRCTrackMetadata members
EVRCTrackMetadata()
: mChannels(0) {
MOZ_COUNT_CTOR(EVRCTrackMetadata);
}
~EVRCTrackMetadata() { MOZ_COUNT_DTOR(EVRCTrackMetadata); }
uint32_t mChannels; // Channel number, it should be 1 or 2.
};
}
#endif // ISOTrackMetadata_h_

View file

@ -1,138 +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 <climits>
#include "ISOControl.h"
#include "ISOMediaBoxes.h"
#include "MP4ESDS.h"
namespace mozilla {
nsresult
MP4AudioSampleEntry::Generate(uint32_t* aBoxSize)
{
uint32_t box_size;
nsresult rv = es->Generate(&box_size);
NS_ENSURE_SUCCESS(rv, rv);
size += box_size;
*aBoxSize = size;
return NS_OK;
}
nsresult
MP4AudioSampleEntry::Write()
{
BoxSizeChecker checker(mControl, size);
nsresult rv;
rv = AudioSampleEntry::Write();
NS_ENSURE_SUCCESS(rv, rv);
rv = es->Write();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
MP4AudioSampleEntry::MP4AudioSampleEntry(ISOControl* aControl)
: AudioSampleEntry(NS_LITERAL_CSTRING("mp4a"), aControl)
{
es = new ESDBox(aControl);
MOZ_COUNT_CTOR(MP4AudioSampleEntry);
}
MP4AudioSampleEntry::~MP4AudioSampleEntry()
{
MOZ_COUNT_DTOR(MP4AudioSampleEntry);
}
nsresult
ESDBox::Generate(uint32_t* aBoxSize)
{
uint32_t box_size;
es_descriptor->Generate(&box_size);
size += box_size;
*aBoxSize = size;
return NS_OK;
}
nsresult
ESDBox::Write()
{
WRITE_FULLBOX(mControl, size)
es_descriptor->Write();
return NS_OK;
}
ESDBox::ESDBox(ISOControl* aControl)
: FullBox(NS_LITERAL_CSTRING("esds"), 0, 0, aControl)
{
es_descriptor = new ES_Descriptor(aControl);
MOZ_COUNT_CTOR(ESDBox);
}
ESDBox::~ESDBox()
{
MOZ_COUNT_DTOR(ESDBox);
}
nsresult
ES_Descriptor::Find(const nsACString& aType,
nsTArray<RefPtr<MuxerOperation>>& aOperations)
{
// ES_Descriptor is not a real ISOMediaBox, so we return nothing here.
return NS_OK;
}
nsresult
ES_Descriptor::Write()
{
mControl->Write(tag);
mControl->Write(length);
mControl->Write(ES_ID);
mControl->WriteBits(streamDependenceFlag.to_ulong(), streamDependenceFlag.size());
mControl->WriteBits(URL_Flag.to_ulong(), URL_Flag.size());
mControl->WriteBits(reserved.to_ulong(), reserved.size());
mControl->WriteBits(streamPriority.to_ulong(), streamPriority.size());
mControl->Write(DecodeSpecificInfo.Elements(), DecodeSpecificInfo.Length());
return NS_OK;
}
nsresult
ES_Descriptor::Generate(uint32_t* aBoxSize)
{
nsresult rv;
// 14496-1 '8.3.4 DecoderConfigDescriptor'
// 14496-1 '10.2.3 SL Packet Header Configuration'
FragmentBuffer* frag = mControl->GetFragment(Audio_Track);
rv = frag->GetCSD(DecodeSpecificInfo);
NS_ENSURE_SUCCESS(rv, rv);
length = sizeof(ES_ID) + 1;
length += DecodeSpecificInfo.Length();
*aBoxSize = sizeof(tag) + sizeof(length) + length;
return NS_OK;
}
ES_Descriptor::ES_Descriptor(ISOControl* aControl)
: tag(ESDescrTag)
, length(0)
, ES_ID(0)
, streamDependenceFlag(0)
, URL_Flag(0)
, reserved(0)
, streamPriority(0)
, mControl(aControl)
{
MOZ_COUNT_CTOR(ES_Descriptor);
}
ES_Descriptor::~ES_Descriptor()
{
MOZ_COUNT_DTOR(ES_Descriptor);
}
}

View file

@ -1,87 +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/. */
#ifndef MP4ESDS_h_
#define MP4ESDS_h_
#include "nsTArray.h"
#include "MuxerOperation.h"
namespace mozilla {
class ISOControl;
/**
* ESDS tag
*/
#define ESDescrTag 0x03
/**
* 14496-1 '8.3.3 ES_Descriptor'.
* It will get DecoderConfigDescriptor and SLConfigDescriptor from
* AAC CSD data.
*/
class ES_Descriptor : public MuxerOperation {
public:
// ISO BMFF members
uint8_t tag; // ESDescrTag
uint8_t length;
uint16_t ES_ID;
std::bitset<1> streamDependenceFlag;
std::bitset<1> URL_Flag;
std::bitset<1> reserved;
std::bitset<5> streamPriority;
nsTArray<uint8_t> DecodeSpecificInfo;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
nsresult Find(const nsACString& aType,
nsTArray<RefPtr<MuxerOperation>>& aOperations) override;
// ES_Descriptor methods
ES_Descriptor(ISOControl* aControl);
~ES_Descriptor();
protected:
ISOControl* mControl;
};
// 14496-14 5.6 'Sample Description Boxes'
// Box type: 'esds'
class ESDBox : public FullBox {
public:
// ISO BMFF members
RefPtr<ES_Descriptor> es_descriptor;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// ESDBox methods
ESDBox(ISOControl* aControl);
~ESDBox();
};
// 14496-14 5.6 'Sample Description Boxes'
// Box type: 'mp4a'
class MP4AudioSampleEntry : public AudioSampleEntry {
public:
// ISO BMFF members
RefPtr<ESDBox> es;
// MuxerOperation methods
nsresult Generate(uint32_t* aBoxSize) override;
nsresult Write() override;
// MP4AudioSampleEntry methods
MP4AudioSampleEntry(ISOControl* aControl);
~MP4AudioSampleEntry();
};
}
#endif // MP4ESDS_h_

View file

@ -1,57 +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 "nsString.h"
#include "nsTArray.h"
#ifndef MuxerOperation_h_
#define MuxerOperation_h_
namespace mozilla {
/**
* The interface for ISO box. All Boxes inherit from this interface.
* Generate() and Write() are needed to be called to produce a complete box.
*
* Generate() will generate all the data structures and their size.
*
* Write() will write all data into muxing output stream (ISOControl actually)
* and update the data which can't be known at Generate() (for example, the
* offset of the video data in mp4 file).
*
* ISO base media format is composed of several container boxes and the contained
* boxes. The container boxes hold a list of MuxerOperation which is implemented
* by contained boxes. The contained boxes will be called via the list.
* For example:
* MovieBox (container) ---> boxes (array of MuxerOperation)
* |---> MovieHeaderBox (full box)
* |---> TrakBox (container)
* |---> MovieExtendsBox (container)
*
* The complete box structure can be found at 14496-12 E.2 "Theisombrand".
*/
class MuxerOperation {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MuxerOperation)
// Generate data of this box and its contained box, and calculate box size.
virtual nsresult Generate(uint32_t* aBoxSize) = 0;
// Write data to stream.
virtual nsresult Write() = 0;
// Find the box type via its name (name is the box type defined in 14496-12;
// for example, 'moov' is the name of MovieBox).
// It can only look child boxes including itself and the box in the boxes
// list if exists. It can't look parent boxes.
virtual nsresult Find(const nsACString& aType,
nsTArray<RefPtr<MuxerOperation>>& aOperations) = 0;
protected:
virtual ~MuxerOperation() {}
};
}
#endif

View file

@ -1,22 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS += [
'ISOMediaWriter.h',
'ISOTrackMetadata.h',
]
UNIFIED_SOURCES += [
'AMRBox.cpp',
'AVCBox.cpp',
'EVRCBox.cpp',
'ISOControl.cpp',
'ISOMediaBoxes.cpp',
'ISOMediaWriter.cpp',
'MP4ESDS.cpp',
]
FINAL_LIBRARY = 'xul'

View file

@ -7,9 +7,6 @@
with Files('*'):
BUG_COMPONENT = ('Core', 'Video/Audio: Recording')
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['fmp4_muxer']
EXPORTS += [
'ContainerWriter.h',
'EncodedFrameContainer.h',
@ -37,16 +34,6 @@ FINAL_LIBRARY = 'xul'
# These includes are from Android JB, for use of MediaCodec.
LOCAL_INCLUDES += ['/ipc/chromium/src']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['ANDROID_VERSION'] > '15':
LOCAL_INCLUDES += [
'%' + '%s/%s' % (CONFIG['ANDROID_SOURCE'], d) for d in [
'frameworks/av/include/media',
'frameworks/native/include',
'frameworks/native/opengl/include',
]
]
include('/ipc/chromium/chromium-config.mozbuild')
# Suppress some GCC warnings being treated as errors: