WebMWriter.cpp (3815B)
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/. */ 5 6 #include "WebMWriter.h" 7 8 #include "EbmlComposer.h" 9 #include "OpusTrackEncoder.h" 10 #include "mozilla/ProfilerLabels.h" 11 12 namespace mozilla { 13 14 WebMWriter::WebMWriter() : mEbmlComposer(new EbmlComposer()) {} 15 16 WebMWriter::~WebMWriter() { 17 // Out-of-line dtor so mEbmlComposer UniquePtr can delete a complete type. 18 } 19 20 nsresult WebMWriter::WriteEncodedTrack( 21 const nsTArray<RefPtr<EncodedFrame>>& aData, uint32_t aFlags) { 22 AUTO_PROFILER_LABEL("WebMWriter::WriteEncodedTrack", OTHER); 23 for (uint32_t i = 0; i < aData.Length(); i++) { 24 nsresult rv = mEbmlComposer->WriteSimpleBlock(aData.ElementAt(i).get()); 25 NS_ENSURE_SUCCESS(rv, rv); 26 } 27 return NS_OK; 28 } 29 30 nsresult WebMWriter::GetContainerData(nsTArray<nsTArray<uint8_t>>* aOutputBufs, 31 uint32_t aFlags) { 32 AUTO_PROFILER_LABEL("WebMWriter::GetContainerData", OTHER); 33 mEbmlComposer->ExtractBuffer(aOutputBufs, aFlags); 34 if (aFlags & ContainerWriter::FLUSH_NEEDED) { 35 mIsWritingComplete = true; 36 } 37 return NS_OK; 38 } 39 40 nsresult WebMWriter::SetMetadata( 41 const nsTArray<RefPtr<TrackMetadataBase>>& aMetadata) { 42 AUTO_PROFILER_LABEL("WebMWriter::SetMetadata", OTHER); 43 MOZ_DIAGNOSTIC_ASSERT(!aMetadata.IsEmpty()); 44 45 // Integrity checks 46 bool bad = false; 47 for (const RefPtr<TrackMetadataBase>& metadata : aMetadata) { 48 MOZ_ASSERT(metadata); 49 50 if (metadata->GetKind() == TrackMetadataBase::METADATA_VP8) { 51 VP8Metadata* meta = static_cast<VP8Metadata*>(metadata.get()); 52 if (meta->mWidth == 0 || meta->mHeight == 0 || meta->mDisplayWidth == 0 || 53 meta->mDisplayHeight == 0) { 54 bad = true; 55 } 56 } 57 58 if (metadata->GetKind() == TrackMetadataBase::METADATA_VORBIS) { 59 VorbisMetadata* meta = static_cast<VorbisMetadata*>(metadata.get()); 60 if (meta->mSamplingFrequency == 0 || meta->mChannels == 0 || 61 meta->mData.IsEmpty()) { 62 bad = true; 63 } 64 } 65 66 if (metadata->GetKind() == TrackMetadataBase::METADATA_OPUS) { 67 OpusMetadata* meta = static_cast<OpusMetadata*>(metadata.get()); 68 if (meta->mSamplingFrequency == 0 || meta->mChannels == 0 || 69 meta->mIdHeader.IsEmpty()) { 70 bad = true; 71 } 72 } 73 } 74 if (bad) { 75 return NS_ERROR_FAILURE; 76 } 77 78 // Storing 79 DebugOnly<bool> hasAudio = false; 80 DebugOnly<bool> hasVideo = false; 81 for (const RefPtr<TrackMetadataBase>& metadata : aMetadata) { 82 MOZ_ASSERT(metadata); 83 84 if (metadata->GetKind() == TrackMetadataBase::METADATA_VP8) { 85 MOZ_ASSERT(!hasVideo); 86 VP8Metadata* meta = static_cast<VP8Metadata*>(metadata.get()); 87 mEbmlComposer->SetVideoConfig(meta->mWidth, meta->mHeight, 88 meta->mDisplayWidth, meta->mDisplayHeight); 89 hasVideo = true; 90 } 91 92 if (metadata->GetKind() == TrackMetadataBase::METADATA_VORBIS) { 93 MOZ_ASSERT(!hasAudio); 94 VorbisMetadata* meta = static_cast<VorbisMetadata*>(metadata.get()); 95 mEbmlComposer->SetAudioConfig(meta->mSamplingFrequency, meta->mChannels); 96 mEbmlComposer->SetAudioCodecPrivateData(meta->mData); 97 hasAudio = true; 98 } 99 100 if (metadata->GetKind() == TrackMetadataBase::METADATA_OPUS) { 101 MOZ_ASSERT(!hasAudio); 102 OpusMetadata* meta = static_cast<OpusMetadata*>(metadata.get()); 103 mEbmlComposer->SetAudioConfig(meta->mSamplingFrequency, meta->mChannels); 104 mEbmlComposer->SetAudioCodecPrivateData(meta->mIdHeader); 105 hasAudio = true; 106 } 107 } 108 mEbmlComposer->GenerateHeader(); 109 return NS_OK; 110 } 111 112 } // namespace mozilla