tor-browser

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

VideoSegment.cpp (6223B)


      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 "VideoSegment.h"
      7 
      8 #include "ImageContainer.h"
      9 #include "VideoUtils.h"
     10 #include "gfx2DGlue.h"
     11 #include "mozilla/UniquePtr.h"
     12 
     13 namespace mozilla {
     14 
     15 using namespace layers;
     16 
     17 VideoFrame::VideoFrame(already_AddRefed<Image> aImage,
     18                       const gfx::IntSize& aIntrinsicSize)
     19    : mImage(aImage),
     20      mIntrinsicSize(aIntrinsicSize),
     21      mForceBlack(false),
     22      mPrincipalHandle(PRINCIPAL_HANDLE_NONE) {}
     23 
     24 VideoFrame::VideoFrame()
     25    : mIntrinsicSize(0, 0),
     26      mForceBlack(false),
     27      mPrincipalHandle(PRINCIPAL_HANDLE_NONE) {}
     28 
     29 VideoFrame::~VideoFrame() = default;
     30 
     31 void VideoFrame::SetNull() {
     32  mImage = nullptr;
     33  mIntrinsicSize = gfx::IntSize(0, 0);
     34  mPrincipalHandle = PRINCIPAL_HANDLE_NONE;
     35 }
     36 
     37 void VideoFrame::TakeFrom(VideoFrame* aFrame) {
     38  mImage = std::move(aFrame->mImage);
     39  mIntrinsicSize = aFrame->mIntrinsicSize;
     40  mForceBlack = aFrame->GetForceBlack();
     41  mPrincipalHandle = aFrame->mPrincipalHandle;
     42 }
     43 
     44 /* static */
     45 already_AddRefed<Image> VideoFrame::CreateBlackImage(
     46    const gfx::IntSize& aSize) {
     47  RefPtr<ImageContainer> container = MakeAndAddRef<ImageContainer>(
     48      ImageUsageType::BlackImage, ImageContainer::ASYNCHRONOUS);
     49  RefPtr<PlanarYCbCrImage> image = container->CreatePlanarYCbCrImage();
     50  if (!image) {
     51    return nullptr;
     52  }
     53 
     54  gfx::IntSize cbcrSize((aSize.width + 1) / 2, (aSize.height + 1) / 2);
     55  int yLen = aSize.width * aSize.height;
     56  int cbcrLen = cbcrSize.width * cbcrSize.height;
     57 
     58  // Generate a black image.
     59  auto frame = MakeUnique<uint8_t[]>(yLen + 2 * cbcrLen);
     60  // Fill Y plane.
     61  memset(frame.get(), 0x10, yLen);
     62  // Fill Cb/Cr planes.
     63  memset(frame.get() + yLen, 0x80, 2 * cbcrLen);
     64 
     65  layers::PlanarYCbCrData data;
     66  data.mYChannel = frame.get();
     67  data.mYStride = aSize.width;
     68  data.mCbCrStride = cbcrSize.width;
     69  data.mCbChannel = frame.get() + yLen;
     70  data.mCrChannel = data.mCbChannel + cbcrLen;
     71  data.mPictureRect = gfx::IntRect(0, 0, aSize.width, aSize.height);
     72  data.mStereoMode = StereoMode::MONO;
     73  data.mYUVColorSpace = gfx::YUVColorSpace::BT601;
     74  // This could be made FULL once bug 1568745 is complete. A black pixel being
     75  // 0x00, 0x80, 0x80
     76  data.mColorRange = gfx::ColorRange::LIMITED;
     77  data.mChromaSubsampling = gfx::ChromaSubsampling::HALF_WIDTH_AND_HEIGHT;
     78 
     79  // Copies data, so we can free data.
     80  if (NS_FAILED(image->CopyData(data))) {
     81    return nullptr;
     82  }
     83 
     84  return image.forget();
     85 }
     86 
     87 void VideoSegment::AppendFrame(const VideoChunk& aChunk,
     88                               const Maybe<bool>& aForceBlack,
     89                               const Maybe<TimeStamp>& aTimeStamp) {
     90  VideoChunk* chunk = AppendChunk(0);
     91  chunk->mTimeStamp = aTimeStamp ? *aTimeStamp : aChunk.mTimeStamp;
     92  chunk->mProcessingDuration = aChunk.mProcessingDuration;
     93  chunk->mMediaTime = aChunk.mMediaTime;
     94  chunk->mWebrtcCaptureTime = aChunk.mWebrtcCaptureTime;
     95  chunk->mWebrtcReceiveTime = aChunk.mWebrtcReceiveTime;
     96  chunk->mRtpTimestamp = aChunk.mRtpTimestamp;
     97  VideoFrame frame(do_AddRef(aChunk.mFrame.GetImage()),
     98                   aChunk.mFrame.GetIntrinsicSize());
     99  MOZ_ASSERT_IF(!IsNull(), !aChunk.mTimeStamp.IsNull());
    100  frame.SetForceBlack(aForceBlack ? *aForceBlack
    101                                  : aChunk.mFrame.GetForceBlack());
    102  frame.SetPrincipalHandle(aChunk.mFrame.GetPrincipalHandle());
    103  chunk->mFrame.TakeFrom(&frame);
    104 }
    105 
    106 void VideoSegment::AppendFrame(already_AddRefed<Image>&& aImage,
    107                               const IntSize& aIntrinsicSize,
    108                               const PrincipalHandle& aPrincipalHandle,
    109                               bool aForceBlack, TimeStamp aTimeStamp,
    110                               media::TimeUnit aProcessingDuration,
    111                               media::TimeUnit aMediaTime) {
    112  VideoChunk* chunk = AppendChunk(0);
    113  chunk->mTimeStamp = aTimeStamp;
    114  chunk->mProcessingDuration = aProcessingDuration;
    115  chunk->mMediaTime = aMediaTime;
    116  VideoFrame frame(std::move(aImage), aIntrinsicSize);
    117  MOZ_ASSERT_IF(!IsNull(), !aTimeStamp.IsNull());
    118  frame.SetForceBlack(aForceBlack);
    119  frame.SetPrincipalHandle(aPrincipalHandle);
    120  chunk->mFrame.TakeFrom(&frame);
    121 }
    122 
    123 void VideoSegment::AppendWebrtcRemoteFrame(
    124    already_AddRefed<Image>&& aImage, const IntSize& aIntrinsicSize,
    125    const PrincipalHandle& aPrincipalHandle, bool aForceBlack,
    126    TimeStamp aTimeStamp, media::TimeUnit aProcessingDuration,
    127    uint32_t aRtpTimestamp, int64_t aWebrtcCaptureTimeNtp,
    128    int64_t aWebrtcReceiveTimeUs) {
    129  VideoChunk* chunk = AppendChunk(0);
    130  chunk->mTimeStamp = aTimeStamp;
    131  chunk->mProcessingDuration = aProcessingDuration;
    132  if (aWebrtcCaptureTimeNtp > 0) {
    133    chunk->mWebrtcCaptureTime = AsVariant(aWebrtcCaptureTimeNtp);
    134  }
    135  if (aWebrtcReceiveTimeUs > 0) {
    136    chunk->mWebrtcReceiveTime = Some(aWebrtcReceiveTimeUs);
    137  }
    138  chunk->mRtpTimestamp = Some(aRtpTimestamp);
    139  VideoFrame frame(std::move(aImage), aIntrinsicSize);
    140  MOZ_ASSERT_IF(!IsNull(), !aTimeStamp.IsNull());
    141  frame.SetForceBlack(aForceBlack);
    142  frame.SetPrincipalHandle(aPrincipalHandle);
    143  chunk->mFrame.TakeFrom(&frame);
    144 }
    145 
    146 void VideoSegment::AppendWebrtcLocalFrame(
    147    already_AddRefed<Image>&& aImage, const IntSize& aIntrinsicSize,
    148    const PrincipalHandle& aPrincipalHandle, bool aForceBlack,
    149    TimeStamp aTimeStamp, TimeStamp aWebrtcCaptureTime) {
    150  VideoChunk* chunk = AppendChunk(0);
    151  chunk->mTimeStamp = aTimeStamp;
    152  chunk->mWebrtcCaptureTime = AsVariant(aWebrtcCaptureTime);
    153  VideoFrame frame(std::move(aImage), aIntrinsicSize);
    154  MOZ_ASSERT_IF(!IsNull(), !aTimeStamp.IsNull());
    155  frame.SetForceBlack(aForceBlack);
    156  frame.SetPrincipalHandle(aPrincipalHandle);
    157  chunk->mFrame.TakeFrom(&frame);
    158 }
    159 
    160 VideoSegment::VideoSegment()
    161    : MediaSegmentBase<VideoSegment, VideoChunk>(VIDEO) {}
    162 
    163 VideoSegment::VideoSegment(VideoSegment&& aSegment)
    164    : MediaSegmentBase<VideoSegment, VideoChunk>(std::move(aSegment)) {}
    165 
    166 VideoSegment::~VideoSegment() = default;
    167 
    168 }  // namespace mozilla