mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
chore: cherry-pick 38781b86f0 from chromium (#28051)
This commit is contained in:
@@ -150,3 +150,4 @@ disable_gpu_acceleration_on_all_mesa_software_rasterizers.patch
|
||||
websocket_don_t_clear_event_queue_on_destruction.patch
|
||||
cherry-pick-7e0e52df283c.patch
|
||||
cherry-pick-dea071d8b30f.patch
|
||||
mediarecorder_tolerate_non-gmb_nv12_frames_for_h264.patch
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Handell <handellm@google.com>
|
||||
Date: Tue, 23 Feb 2021 18:45:55 +0000
|
||||
Subject: MediaRecorder: tolerate non-GMB NV12 frames for H264.
|
||||
|
||||
The VPX video track recorders were updated to tolerate non-GMB NV12
|
||||
input in crrev/c/2425748, but the H264 encoder was left neglected,
|
||||
which hurts Mac users that have disabled hardware acceleration. This
|
||||
change adds that support to it.
|
||||
|
||||
[TBR landing because mcasas@chromium.org is OOO]
|
||||
|
||||
TBR=mcasas@chromium.org
|
||||
(cherry picked from commit de865890bf6a12c74ae9943ede6132d25c7a33dd)
|
||||
|
||||
Bug: 1177593
|
||||
Change-Id: I608c76b1de8261dcc44463fe896e3b63d5fd329e
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2694407
|
||||
Reviewed-by: ccameron <ccameron@chromium.org>
|
||||
Reviewed-by: Evan Shrubsole <eshr@google.com>
|
||||
Reviewed-by: Miguel Casas <mcasas@chromium.org>
|
||||
Commit-Queue: Markus Handell <handellm@google.com>
|
||||
Cr-Original-Commit-Position: refs/heads/master@{#854709}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2715222
|
||||
Cr-Commit-Position: refs/branch-heads/4389@{#1320}
|
||||
Cr-Branched-From: 9251c5db2b6d5a59fe4eac7aafa5fed37c139bb7-refs/heads/master@{#843830}
|
||||
|
||||
diff --git a/media/base/video_util.cc b/media/base/video_util.cc
|
||||
index 3daa1cb27d5705d56d0075e82a9ecd0bfb86c366..d5a0f1b578e22822089d704fcd7b98cbb26bb405 100644
|
||||
--- a/media/base/video_util.cc
|
||||
+++ b/media/base/video_util.cc
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/numerics/safe_math.h"
|
||||
#include "media/base/video_frame.h"
|
||||
#include "third_party/libyuv/include/libyuv.h"
|
||||
+#include "ui/gfx/gpu_memory_buffer.h"
|
||||
|
||||
namespace media {
|
||||
|
||||
@@ -424,6 +425,38 @@ void CopyRGBToVideoFrame(const uint8_t* source,
|
||||
region_in_frame.width(), region_in_frame.height());
|
||||
}
|
||||
|
||||
+scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame(
|
||||
+ scoped_refptr<VideoFrame> video_frame) {
|
||||
+ DCHECK(video_frame);
|
||||
+ DCHECK(video_frame->HasGpuMemoryBuffer());
|
||||
+ auto* gmb = video_frame->GetGpuMemoryBuffer();
|
||||
+ if (!gmb->Map())
|
||||
+ return nullptr;
|
||||
+ const size_t num_planes = VideoFrame::NumPlanes(video_frame->format());
|
||||
+ uint8_t* plane_addrs[VideoFrame::kMaxPlanes] = {};
|
||||
+ for (size_t i = 0; i < num_planes; i++)
|
||||
+ plane_addrs[i] = static_cast<uint8_t*>(gmb->memory(i));
|
||||
+ auto mapped_frame = VideoFrame::WrapExternalYuvDataWithLayout(
|
||||
+ video_frame->layout(), video_frame->visible_rect(),
|
||||
+ video_frame->natural_size(), plane_addrs[0], plane_addrs[1],
|
||||
+ plane_addrs[2], video_frame->timestamp());
|
||||
+ if (!mapped_frame) {
|
||||
+ gmb->Unmap();
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ mapped_frame->set_color_space(video_frame->ColorSpace());
|
||||
+ mapped_frame->metadata()->MergeMetadataFrom(video_frame->metadata());
|
||||
+ // Pass |video_frame| so that it outlives |mapped_frame| and the mapped buffer
|
||||
+ // is unmapped on destruction.
|
||||
+ mapped_frame->AddDestructionObserver(base::BindOnce(
|
||||
+ [](scoped_refptr<VideoFrame> frame) {
|
||||
+ DCHECK(frame->HasGpuMemoryBuffer());
|
||||
+ frame->GetGpuMemoryBuffer()->Unmap();
|
||||
+ },
|
||||
+ std::move(video_frame)));
|
||||
+ return mapped_frame;
|
||||
+}
|
||||
+
|
||||
scoped_refptr<VideoFrame> WrapAsI420VideoFrame(
|
||||
scoped_refptr<VideoFrame> frame) {
|
||||
DCHECK_EQ(VideoFrame::STORAGE_OWNED_MEMORY, frame->storage_type());
|
||||
diff --git a/media/base/video_util.h b/media/base/video_util.h
|
||||
index 42e060a25b711fca8bba3cef8ade9bbaa2092c55..2681163c55618ae8738d91987bb46a4e8bcc541b 100644
|
||||
--- a/media/base/video_util.h
|
||||
+++ b/media/base/video_util.h
|
||||
@@ -134,6 +134,12 @@ MEDIA_EXPORT gfx::Size GetRectSizeFromOrigin(const gfx::Rect& rect);
|
||||
MEDIA_EXPORT gfx::Size PadToMatchAspectRatio(const gfx::Size& size,
|
||||
const gfx::Size& target);
|
||||
|
||||
+// A helper function to map GpuMemoryBuffer-based VideoFrame. This function
|
||||
+// maps the given GpuMemoryBuffer of |frame| as-is without converting pixel
|
||||
+// format. The returned VideoFrame owns the |frame|.
|
||||
+MEDIA_EXPORT scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame(
|
||||
+ scoped_refptr<VideoFrame> frame);
|
||||
+
|
||||
// Copy an RGB bitmap into the specified |region_in_frame| of a YUV video frame.
|
||||
// Fills the regions outside |region_in_frame| with black.
|
||||
MEDIA_EXPORT void CopyRGBToVideoFrame(const uint8_t* source,
|
||||
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
|
||||
index 401e696e886f68fc4a9bb9ac0614959f0a8673a8..c323faab804ad421b1c8f8d7789222304c4d44e6 100644
|
||||
--- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
|
||||
@@ -54,9 +54,13 @@ void H264Encoder::EncodeOnEncodingTaskRunner(
|
||||
base::TimeTicks capture_timestamp) {
|
||||
TRACE_EVENT0("media", "H264Encoder::EncodeOnEncodingTaskRunner");
|
||||
DCHECK(encoding_task_runner_->BelongsToCurrentThread());
|
||||
+ DCHECK(frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_NV12 ||
|
||||
+ frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_I420 ||
|
||||
+ frame->format() == media::VideoPixelFormat::PIXEL_FORMAT_I420A);
|
||||
|
||||
- if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER)
|
||||
+ if (frame->format() == media::PIXEL_FORMAT_NV12)
|
||||
frame = ConvertToI420ForSoftwareEncoder(frame);
|
||||
+ DCHECK(frame->IsMappable());
|
||||
|
||||
const gfx::Size frame_size = frame->visible_rect().size();
|
||||
if (!openh264_encoder_ || configured_size_ != frame_size) {
|
||||
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
|
||||
index 0397c605efbb2a669e0235898e1b3029e3b4f0e8..7a7683092919b3712b2c09a86b06fd9c724f8aac 100644
|
||||
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
|
||||
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
|
||||
@@ -415,20 +415,17 @@ bool VideoTrackRecorderImpl::Encoder::CanEncodeAlphaChannel() {
|
||||
scoped_refptr<media::VideoFrame>
|
||||
VideoTrackRecorderImpl::Encoder::ConvertToI420ForSoftwareEncoder(
|
||||
scoped_refptr<media::VideoFrame> frame) {
|
||||
- DCHECK_EQ(frame->storage_type(),
|
||||
- media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER);
|
||||
- // NV12 is currently the only supported pixel format for GpuMemoryBuffer.
|
||||
DCHECK_EQ(frame->format(), media::VideoPixelFormat::PIXEL_FORMAT_NV12);
|
||||
|
||||
- auto* gmb = frame->GetGpuMemoryBuffer();
|
||||
- if (!gmb->Map())
|
||||
- return frame;
|
||||
+ if (frame->GetGpuMemoryBuffer())
|
||||
+ frame = media::ConvertToMemoryMappedFrame(frame);
|
||||
+
|
||||
scoped_refptr<media::VideoFrame> i420_frame = media::VideoFrame::CreateFrame(
|
||||
media::VideoPixelFormat::PIXEL_FORMAT_I420, frame->coded_size(),
|
||||
frame->visible_rect(), frame->natural_size(), frame->timestamp());
|
||||
auto ret = libyuv::NV12ToI420(
|
||||
- static_cast<const uint8_t*>(gmb->memory(0)), gmb->stride(0),
|
||||
- static_cast<const uint8_t*>(gmb->memory(1)), gmb->stride(1),
|
||||
+ static_cast<const uint8_t*>(frame->data(0)), frame->stride(0),
|
||||
+ static_cast<const uint8_t*>(frame->data(1)), frame->stride(1),
|
||||
i420_frame->data(media::VideoFrame::kYPlane),
|
||||
i420_frame->stride(media::VideoFrame::kYPlane),
|
||||
i420_frame->data(media::VideoFrame::kUPlane),
|
||||
@@ -436,7 +433,6 @@ VideoTrackRecorderImpl::Encoder::ConvertToI420ForSoftwareEncoder(
|
||||
i420_frame->data(media::VideoFrame::kVPlane),
|
||||
i420_frame->stride(media::VideoFrame::kVPlane),
|
||||
frame->coded_size().width(), frame->coded_size().height());
|
||||
- gmb->Unmap();
|
||||
if (ret)
|
||||
return frame;
|
||||
return i420_frame;
|
||||
Reference in New Issue
Block a user