summaryrefslogtreecommitdiffstats
path: root/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp')
-rw-r--r--dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
new file mode 100644
index 0000000000..3f136c4ac8
--- /dev/null
+++ b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WidevineVideoFrame.h"
+#include "GMPLog.h"
+#include "WidevineUtils.h"
+#include "mozilla/CheckedInt.h"
+#include "mozilla/IntegerPrintfMacros.h"
+
+namespace mozilla {
+
+WidevineVideoFrame::WidevineVideoFrame()
+ : mFormat(cdm::VideoFormat::kUnknownVideoFormat),
+ mSize{0, 0},
+ mBuffer(nullptr),
+ mTimestamp(0) {
+ MOZ_ASSERT(mSize.height == 0 && mSize.width == 0, "Size should be zeroed");
+ GMP_LOG_DEBUG("WidevineVideoFrame::WidevineVideoFrame() this=%p", this);
+ memset(mPlaneOffsets, 0, sizeof(mPlaneOffsets));
+ memset(mPlaneStrides, 0, sizeof(mPlaneStrides));
+}
+
+WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&& aOther)
+ : mFormat(aOther.mFormat),
+ mSize(aOther.mSize),
+ mBuffer(aOther.mBuffer),
+ mTimestamp(aOther.mTimestamp) {
+ GMP_LOG_DEBUG(
+ "WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&&) "
+ "this=%p, other=%p",
+ this, &aOther);
+ memcpy(mPlaneOffsets, aOther.mPlaneOffsets, sizeof(mPlaneOffsets));
+ memcpy(mPlaneStrides, aOther.mPlaneStrides, sizeof(mPlaneStrides));
+ aOther.mBuffer = nullptr;
+}
+
+WidevineVideoFrame::~WidevineVideoFrame() {
+ if (mBuffer) {
+ mBuffer->Destroy();
+ mBuffer = nullptr;
+ }
+}
+
+void WidevineVideoFrame::SetFormat(cdm::VideoFormat aFormat) {
+ GMP_LOG_DEBUG("WidevineVideoFrame::SetFormat(%d) this=%p", aFormat, this);
+ mFormat = aFormat;
+}
+
+cdm::VideoFormat WidevineVideoFrame::Format() const { return mFormat; }
+
+void WidevineVideoFrame::SetSize(cdm::Size aSize) {
+ GMP_LOG_DEBUG("WidevineVideoFrame::SetSize(%d,%d) this=%p", aSize.width,
+ aSize.height, this);
+ mSize.width = aSize.width;
+ mSize.height = aSize.height;
+}
+
+cdm::Size WidevineVideoFrame::Size() const { return mSize; }
+
+void WidevineVideoFrame::SetFrameBuffer(cdm::Buffer* aFrameBuffer) {
+ GMP_LOG_DEBUG("WidevineVideoFrame::SetFrameBuffer(%p) this=%p", aFrameBuffer,
+ this);
+ MOZ_ASSERT(!mBuffer);
+ mBuffer = aFrameBuffer;
+}
+
+cdm::Buffer* WidevineVideoFrame::FrameBuffer() { return mBuffer; }
+
+void WidevineVideoFrame::SetPlaneOffset(cdm::VideoPlane aPlane,
+ uint32_t aOffset) {
+ GMP_LOG_DEBUG("WidevineVideoFrame::SetPlaneOffset(%d, %" PRIu32 ") this=%p",
+ aPlane, aOffset, this);
+ mPlaneOffsets[aPlane] = aOffset;
+}
+
+uint32_t WidevineVideoFrame::PlaneOffset(cdm::VideoPlane aPlane) {
+ return mPlaneOffsets[aPlane];
+}
+
+void WidevineVideoFrame::SetStride(cdm::VideoPlane aPlane, uint32_t aStride) {
+ GMP_LOG_DEBUG("WidevineVideoFrame::SetStride(%d, %" PRIu32 ") this=%p",
+ aPlane, aStride, this);
+ mPlaneStrides[aPlane] = aStride;
+}
+
+uint32_t WidevineVideoFrame::Stride(cdm::VideoPlane aPlane) {
+ return mPlaneStrides[aPlane];
+}
+
+void WidevineVideoFrame::SetTimestamp(int64_t timestamp) {
+ GMP_LOG_DEBUG("WidevineVideoFrame::SetTimestamp(%" PRId64 ") this=%p",
+ timestamp, this);
+ mTimestamp = timestamp;
+}
+
+int64_t WidevineVideoFrame::Timestamp() const { return mTimestamp; }
+
+bool WidevineVideoFrame::InitToBlack(int32_t aWidth, int32_t aHeight,
+ int64_t aTimeStamp) {
+ if (NS_WARN_IF(aWidth < 0 || aHeight < 0)) {
+ MOZ_ASSERT_UNREACHABLE("Frame dimensions should be positive");
+ return false;
+ }
+
+ const uint32_t halfWidth = (uint32_t(aWidth) + 1) / 2;
+ CheckedInt<size_t> ySizeChk = aWidth;
+ ySizeChk *= aHeight;
+ CheckedInt<size_t> uSizeChk = halfWidth;
+ uSizeChk *= (uint32_t(aHeight) + 1) / 2;
+ CheckedInt<size_t> yuSizeChk = ySizeChk + uSizeChk;
+ if (NS_WARN_IF(!yuSizeChk.isValid())) {
+ return false;
+ }
+
+ WidevineBuffer* buffer = new WidevineBuffer(yuSizeChk.value());
+ const size_t ySize = ySizeChk.value();
+ const size_t uSize = uSizeChk.value();
+ // Black in YCbCr is (0,128,128).
+ memset(buffer->Data(), 0, ySize);
+ memset(buffer->Data() + ySize, 128, uSize);
+ if (mBuffer) {
+ mBuffer->Destroy();
+ mBuffer = nullptr;
+ }
+ SetFormat(cdm::VideoFormat::kI420);
+ SetSize(cdm::Size{aWidth, aHeight});
+ SetFrameBuffer(buffer);
+ SetPlaneOffset(cdm::VideoPlane::kYPlane, 0);
+ SetStride(cdm::VideoPlane::kYPlane, aWidth);
+ // Note: U and V planes are stored at the same place in order to
+ // save memory since their contents are the same.
+ SetPlaneOffset(cdm::VideoPlane::kUPlane, ySize);
+ SetStride(cdm::VideoPlane::kUPlane, halfWidth);
+ SetPlaneOffset(cdm::VideoPlane::kVPlane, ySize);
+ SetStride(cdm::VideoPlane::kVPlane, halfWidth);
+ SetTimestamp(aTimeStamp);
+ return true;
+}
+
+} // namespace mozilla