WidevineVideoFrame.cpp (4732B)
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 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "WidevineVideoFrame.h" 7 8 #include "GMPLog.h" 9 #include "WidevineUtils.h" 10 #include "mozilla/CheckedInt.h" 11 #include "mozilla/IntegerPrintfMacros.h" 12 13 namespace mozilla { 14 15 WidevineVideoFrame::WidevineVideoFrame() 16 : mFormat(cdm::VideoFormat::kUnknownVideoFormat), 17 mSize{0, 0}, 18 mBuffer(nullptr), 19 mTimestamp(0) { 20 MOZ_ASSERT(mSize.height == 0 && mSize.width == 0, "Size should be zeroed"); 21 GMP_LOG_DEBUG("WidevineVideoFrame::WidevineVideoFrame() this=%p", this); 22 memset(mPlaneOffsets, 0, sizeof(mPlaneOffsets)); 23 memset(mPlaneStrides, 0, sizeof(mPlaneStrides)); 24 } 25 26 WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&& aOther) 27 : mFormat(aOther.mFormat), 28 mSize(aOther.mSize), 29 mBuffer(aOther.mBuffer), 30 mTimestamp(aOther.mTimestamp) { 31 GMP_LOG_DEBUG( 32 "WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&&) " 33 "this=%p, other=%p", 34 this, &aOther); 35 memcpy(mPlaneOffsets, aOther.mPlaneOffsets, sizeof(mPlaneOffsets)); 36 memcpy(mPlaneStrides, aOther.mPlaneStrides, sizeof(mPlaneStrides)); 37 aOther.mBuffer = nullptr; 38 } 39 40 WidevineVideoFrame::~WidevineVideoFrame() { 41 if (mBuffer) { 42 mBuffer->Destroy(); 43 mBuffer = nullptr; 44 } 45 } 46 47 void WidevineVideoFrame::SetFormat(cdm::VideoFormat aFormat) { 48 GMP_LOG_DEBUG("WidevineVideoFrame::SetFormat(%d) this=%p", aFormat, this); 49 mFormat = aFormat; 50 } 51 52 cdm::VideoFormat WidevineVideoFrame::Format() const { return mFormat; } 53 54 void WidevineVideoFrame::SetSize(cdm::Size aSize) { 55 GMP_LOG_DEBUG("WidevineVideoFrame::SetSize(%d,%d) this=%p", aSize.width, 56 aSize.height, this); 57 mSize.width = aSize.width; 58 mSize.height = aSize.height; 59 } 60 61 cdm::Size WidevineVideoFrame::Size() const { return mSize; } 62 63 void WidevineVideoFrame::SetFrameBuffer(cdm::Buffer* aFrameBuffer) { 64 GMP_LOG_DEBUG("WidevineVideoFrame::SetFrameBuffer(%p) this=%p", aFrameBuffer, 65 this); 66 MOZ_ASSERT(!mBuffer); 67 mBuffer = aFrameBuffer; 68 } 69 70 cdm::Buffer* WidevineVideoFrame::FrameBuffer() { return mBuffer; } 71 72 void WidevineVideoFrame::SetPlaneOffset(cdm::VideoPlane aPlane, 73 uint32_t aOffset) { 74 GMP_LOG_DEBUG("WidevineVideoFrame::SetPlaneOffset(%d, %" PRIu32 ") this=%p", 75 aPlane, aOffset, this); 76 mPlaneOffsets[aPlane] = aOffset; 77 } 78 79 uint32_t WidevineVideoFrame::PlaneOffset(cdm::VideoPlane aPlane) { 80 return mPlaneOffsets[aPlane]; 81 } 82 83 void WidevineVideoFrame::SetStride(cdm::VideoPlane aPlane, uint32_t aStride) { 84 GMP_LOG_DEBUG("WidevineVideoFrame::SetStride(%d, %" PRIu32 ") this=%p", 85 aPlane, aStride, this); 86 mPlaneStrides[aPlane] = aStride; 87 } 88 89 uint32_t WidevineVideoFrame::Stride(cdm::VideoPlane aPlane) { 90 return mPlaneStrides[aPlane]; 91 } 92 93 void WidevineVideoFrame::SetTimestamp(int64_t timestamp) { 94 GMP_LOG_DEBUG("WidevineVideoFrame::SetTimestamp(%" PRId64 ") this=%p", 95 timestamp, this); 96 mTimestamp = timestamp; 97 } 98 99 int64_t WidevineVideoFrame::Timestamp() const { return mTimestamp; } 100 101 bool WidevineVideoFrame::InitToBlack(int32_t aWidth, int32_t aHeight, 102 int64_t aTimeStamp) { 103 if (NS_WARN_IF(aWidth < 0 || aHeight < 0)) { 104 MOZ_ASSERT_UNREACHABLE("Frame dimensions should be positive"); 105 return false; 106 } 107 108 const uint32_t halfWidth = (uint32_t(aWidth) + 1) / 2; 109 CheckedInt<size_t> ySizeChk = aWidth; 110 ySizeChk *= aHeight; 111 CheckedInt<size_t> uSizeChk = halfWidth; 112 uSizeChk *= (uint32_t(aHeight) + 1) / 2; 113 CheckedInt<size_t> yuSizeChk = ySizeChk + uSizeChk; 114 if (NS_WARN_IF(!yuSizeChk.isValid())) { 115 return false; 116 } 117 118 WidevineBuffer* buffer = new WidevineBuffer(yuSizeChk.value()); 119 const size_t ySize = ySizeChk.value(); 120 const size_t uSize = uSizeChk.value(); 121 // Black in YCbCr is (0,128,128). 122 memset(buffer->Data(), 0, ySize); 123 memset(buffer->Data() + ySize, 128, uSize); 124 if (mBuffer) { 125 mBuffer->Destroy(); 126 mBuffer = nullptr; 127 } 128 SetFormat(cdm::VideoFormat::kI420); 129 SetSize(cdm::Size{aWidth, aHeight}); 130 SetFrameBuffer(buffer); 131 SetPlaneOffset(cdm::kYPlane, 0); 132 SetStride(cdm::kYPlane, aWidth); 133 // Note: U and V planes are stored at the same place in order to 134 // save memory since their contents are the same. 135 SetPlaneOffset(cdm::kUPlane, ySize); 136 SetStride(cdm::kUPlane, halfWidth); 137 SetPlaneOffset(cdm::kVPlane, ySize); 138 SetStride(cdm::kVPlane, halfWidth); 139 SetTimestamp(aTimeStamp); 140 return true; 141 } 142 143 } // namespace mozilla