1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "WebMWriter.h"
7 #include "EbmlComposer.h"
8 #include "mozilla/ProfilerLabels.h"
9 #include "OpusTrackEncoder.h"
13 WebMWriter::WebMWriter() : mEbmlComposer(new EbmlComposer()) {}
15 WebMWriter::~WebMWriter() {
16 // Out-of-line dtor so mEbmlComposer UniquePtr can delete a complete type.
19 nsresult
WebMWriter::WriteEncodedTrack(
20 const nsTArray
<RefPtr
<EncodedFrame
>>& aData
, uint32_t aFlags
) {
21 AUTO_PROFILER_LABEL("WebMWriter::WriteEncodedTrack", OTHER
);
22 for (uint32_t i
= 0; i
< aData
.Length(); i
++) {
23 nsresult rv
= mEbmlComposer
->WriteSimpleBlock(aData
.ElementAt(i
).get());
24 NS_ENSURE_SUCCESS(rv
, rv
);
29 nsresult
WebMWriter::GetContainerData(nsTArray
<nsTArray
<uint8_t>>* aOutputBufs
,
31 AUTO_PROFILER_LABEL("WebMWriter::GetContainerData", OTHER
);
32 mEbmlComposer
->ExtractBuffer(aOutputBufs
, aFlags
);
33 if (aFlags
& ContainerWriter::FLUSH_NEEDED
) {
34 mIsWritingComplete
= true;
39 nsresult
WebMWriter::SetMetadata(
40 const nsTArray
<RefPtr
<TrackMetadataBase
>>& aMetadata
) {
41 AUTO_PROFILER_LABEL("WebMWriter::SetMetadata", OTHER
);
42 MOZ_DIAGNOSTIC_ASSERT(!aMetadata
.IsEmpty());
46 for (const RefPtr
<TrackMetadataBase
>& metadata
: aMetadata
) {
49 if (metadata
->GetKind() == TrackMetadataBase::METADATA_VP8
) {
50 VP8Metadata
* meta
= static_cast<VP8Metadata
*>(metadata
.get());
51 if (meta
->mWidth
== 0 || meta
->mHeight
== 0 || meta
->mDisplayWidth
== 0 ||
52 meta
->mDisplayHeight
== 0) {
57 if (metadata
->GetKind() == TrackMetadataBase::METADATA_VORBIS
) {
58 VorbisMetadata
* meta
= static_cast<VorbisMetadata
*>(metadata
.get());
59 if (meta
->mSamplingFrequency
== 0 || meta
->mChannels
== 0 ||
60 meta
->mData
.IsEmpty()) {
65 if (metadata
->GetKind() == TrackMetadataBase::METADATA_OPUS
) {
66 OpusMetadata
* meta
= static_cast<OpusMetadata
*>(metadata
.get());
67 if (meta
->mSamplingFrequency
== 0 || meta
->mChannels
== 0 ||
68 meta
->mIdHeader
.IsEmpty()) {
74 return NS_ERROR_FAILURE
;
78 DebugOnly
<bool> hasAudio
= false;
79 DebugOnly
<bool> hasVideo
= false;
80 for (const RefPtr
<TrackMetadataBase
>& metadata
: aMetadata
) {
83 if (metadata
->GetKind() == TrackMetadataBase::METADATA_VP8
) {
84 MOZ_ASSERT(!hasVideo
);
85 VP8Metadata
* meta
= static_cast<VP8Metadata
*>(metadata
.get());
86 mEbmlComposer
->SetVideoConfig(meta
->mWidth
, meta
->mHeight
,
87 meta
->mDisplayWidth
, meta
->mDisplayHeight
);
91 if (metadata
->GetKind() == TrackMetadataBase::METADATA_VORBIS
) {
92 MOZ_ASSERT(!hasAudio
);
93 VorbisMetadata
* meta
= static_cast<VorbisMetadata
*>(metadata
.get());
94 mEbmlComposer
->SetAudioConfig(meta
->mSamplingFrequency
, meta
->mChannels
);
95 mEbmlComposer
->SetAudioCodecPrivateData(meta
->mData
);
99 if (metadata
->GetKind() == TrackMetadataBase::METADATA_OPUS
) {
100 MOZ_ASSERT(!hasAudio
);
101 OpusMetadata
* meta
= static_cast<OpusMetadata
*>(metadata
.get());
102 mEbmlComposer
->SetAudioConfig(meta
->mSamplingFrequency
, meta
->mChannels
);
103 mEbmlComposer
->SetAudioCodecPrivateData(meta
->mIdHeader
);
107 mEbmlComposer
->GenerateHeader();
111 } // namespace mozilla