tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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