tor-browser

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

BlankDecoderModule.cpp (5619B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "BlankDecoderModule.h"
      8 
      9 #include "ImageContainer.h"
     10 #include "MediaData.h"
     11 #include "MediaInfo.h"
     12 #include "VideoUtils.h"
     13 #include "mozilla/CheckedInt.h"
     14 #include "mozilla/RefPtr.h"
     15 #include "mozilla/UniquePtrExtensions.h"
     16 #include "mozilla/gfx/Point.h"
     17 #include "mozilla/gfx/Rect.h"
     18 
     19 namespace mozilla {
     20 
     21 BlankVideoDataCreator::BlankVideoDataCreator(
     22    uint32_t aFrameWidth, uint32_t aFrameHeight,
     23    layers::ImageContainer* aImageContainer)
     24    : mFrameWidth(aFrameWidth),
     25      mFrameHeight(aFrameHeight),
     26      mImageContainer(aImageContainer) {
     27  mInfo.mDisplay = gfx::IntSize(mFrameWidth, mFrameHeight);
     28  mPicture = gfx::IntRect(0, 0, mFrameWidth, mFrameHeight);
     29 }
     30 
     31 already_AddRefed<MediaData> BlankVideoDataCreator::Create(
     32    MediaRawData* aSample) {
     33  // Create a fake YUV buffer in a 420 format. That is, an 8bpp Y plane,
     34  // with a U and V plane that are half the size of the Y plane, i.e 8 bit,
     35  // 2x2 subsampled. Have the data pointer of each frame point to the
     36  // first plane, they'll always be zero'd memory anyway.
     37  const CheckedUint32 size = CheckedUint32(mFrameWidth) * mFrameHeight;
     38  if (!size.isValid()) {
     39    // Overflow happened.
     40    return nullptr;
     41  }
     42  auto frame = MakeUniqueFallible<uint8_t[]>(size.value());
     43  if (!frame) {
     44    return nullptr;
     45  }
     46  memset(frame.get(), 0, mFrameWidth * mFrameHeight);
     47  VideoData::YCbCrBuffer buffer;
     48 
     49  // Y plane.
     50  buffer.mPlanes[0].mData = frame.get();
     51  buffer.mPlanes[0].mStride = mFrameWidth;
     52  buffer.mPlanes[0].mHeight = mFrameHeight;
     53  buffer.mPlanes[0].mWidth = mFrameWidth;
     54  buffer.mPlanes[0].mSkip = 0;
     55 
     56  // Cb plane.
     57  buffer.mPlanes[1].mData = frame.get();
     58  buffer.mPlanes[1].mStride = (mFrameWidth + 1) / 2;
     59  buffer.mPlanes[1].mHeight = (mFrameHeight + 1) / 2;
     60  buffer.mPlanes[1].mWidth = (mFrameWidth + 1) / 2;
     61  buffer.mPlanes[1].mSkip = 0;
     62 
     63  // Cr plane.
     64  buffer.mPlanes[2].mData = frame.get();
     65  buffer.mPlanes[2].mStride = (mFrameWidth + 1) / 2;
     66  buffer.mPlanes[2].mHeight = (mFrameHeight + 1) / 2;
     67  buffer.mPlanes[2].mWidth = (mFrameWidth + 1) / 2;
     68  buffer.mPlanes[2].mSkip = 0;
     69 
     70  buffer.mChromaSubsampling = gfx::ChromaSubsampling::HALF_WIDTH_AND_HEIGHT;
     71  buffer.mYUVColorSpace = gfx::YUVColorSpace::BT601;
     72  buffer.mColorPrimaries = gfx::ColorSpace2::BT709;
     73 
     74  Result<already_AddRefed<VideoData>, MediaResult> result =
     75      VideoData::CreateAndCopyData(mInfo, mImageContainer, aSample->mOffset,
     76                                   aSample->mTime, aSample->mDuration, buffer,
     77                                   aSample->mKeyframe, aSample->mTime, mPicture,
     78                                   nullptr);
     79  return result.unwrapOr(nullptr);
     80 }
     81 
     82 BlankAudioDataCreator::BlankAudioDataCreator(uint32_t aChannelCount,
     83                                             uint32_t aSampleRate)
     84    : mFrameSum(0), mChannelCount(aChannelCount), mSampleRate(aSampleRate) {}
     85 
     86 already_AddRefed<MediaData> BlankAudioDataCreator::Create(
     87    MediaRawData* aSample) {
     88  // Convert duration to frames. We add 1 to duration to account for
     89  // rounding errors, so we get a consistent tone.
     90  CheckedInt64 frames =
     91      UsecsToFrames(aSample->mDuration.ToMicroseconds() + 1, mSampleRate);
     92  if (!frames.isValid() || !mChannelCount || !mSampleRate ||
     93      frames.value() > (UINT32_MAX / mChannelCount)) {
     94    return nullptr;
     95  }
     96  AlignedAudioBuffer samples(frames.value() * mChannelCount);
     97  if (!samples) {
     98    return nullptr;
     99  }
    100  // Fill the sound buffer with an A4 tone.
    101  static const float pi = 3.14159265f;
    102  static const float noteHz = 440.0f;
    103  for (int i = 0; i < frames.value(); i++) {
    104    float f = sin(2 * pi * noteHz * mFrameSum / mSampleRate);
    105    for (unsigned c = 0; c < mChannelCount; c++) {
    106      samples[i * mChannelCount + c] = AudioDataValue(f);
    107    }
    108    mFrameSum++;
    109  }
    110  RefPtr<AudioData> data(new AudioData(aSample->mOffset, aSample->mTime,
    111                                       std::move(samples), mChannelCount,
    112                                       mSampleRate));
    113  return data.forget();
    114 }
    115 
    116 already_AddRefed<MediaDataDecoder> BlankDecoderModule::CreateVideoDecoder(
    117    const CreateDecoderParams& aParams) {
    118  const VideoInfo& config = aParams.VideoConfig();
    119  UniquePtr<DummyDataCreator> creator = MakeUnique<BlankVideoDataCreator>(
    120      config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer);
    121  RefPtr<MediaDataDecoder> decoder = new DummyMediaDataDecoder(
    122      std::move(creator), "blank media data decoder"_ns, aParams);
    123  return decoder.forget();
    124 }
    125 
    126 already_AddRefed<MediaDataDecoder> BlankDecoderModule::CreateAudioDecoder(
    127    const CreateDecoderParams& aParams) {
    128  const AudioInfo& config = aParams.AudioConfig();
    129  UniquePtr<DummyDataCreator> creator =
    130      MakeUnique<BlankAudioDataCreator>(config.mChannels, config.mRate);
    131  RefPtr<MediaDataDecoder> decoder = new DummyMediaDataDecoder(
    132      std::move(creator), "blank media data decoder"_ns, aParams);
    133  return decoder.forget();
    134 }
    135 
    136 media::DecodeSupportSet BlankDecoderModule::SupportsMimeType(
    137    const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const {
    138  return media::DecodeSupport::SoftwareDecode;
    139 }
    140 
    141 /* static */
    142 already_AddRefed<PlatformDecoderModule> BlankDecoderModule::Create() {
    143  return MakeAndAddRef<BlankDecoderModule>();
    144 }
    145 
    146 }  // namespace mozilla