1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
media / renderers / video_frame_shared_image_cache.cc [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/renderers/video_frame_shared_image_cache.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "components/viz/common/resources/shared_image_format.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/common/sync_token.h"
namespace media {
namespace {
// Returns multiplanar format equivalent of a VideoPixelFormat.
viz::SharedImageFormat VideoPixelFormatToSharedImageFormat(
VideoPixelFormat video_format) {
switch (video_format) {
case PIXEL_FORMAT_NV12:
return viz::MultiPlaneFormat::kNV12;
case PIXEL_FORMAT_NV16:
return viz::MultiPlaneFormat::kNV16;
case PIXEL_FORMAT_NV24:
return viz::MultiPlaneFormat::kNV24;
case PIXEL_FORMAT_NV12A:
return viz::MultiPlaneFormat::kNV12A;
case PIXEL_FORMAT_P010LE:
return viz::MultiPlaneFormat::kP010;
case PIXEL_FORMAT_P210LE:
return viz::MultiPlaneFormat::kP210;
case PIXEL_FORMAT_P410LE:
return viz::MultiPlaneFormat::kP410;
case PIXEL_FORMAT_I420:
return viz::MultiPlaneFormat::kI420;
case PIXEL_FORMAT_I420A:
return viz::MultiPlaneFormat::kI420A;
default:
NOTREACHED();
}
}
} // namespace
VideoFrameSharedImageCache::VideoFrameSharedImageCache() = default;
VideoFrameSharedImageCache::~VideoFrameSharedImageCache() {
ReleaseCachedData();
}
void VideoFrameSharedImageCache::ReleaseCachedData() {
// Don't destroy shared image we don't own.
if (!shared_image_) {
return;
}
auto* sii = provider_->SharedImageInterface();
DCHECK(sii);
if (shared_image_) {
sii->DestroySharedImage(sync_token_, std::move(shared_image_));
}
}
VideoFrameSharedImageCache::CachedData
VideoFrameSharedImageCache::GetSharedImage(
const VideoFrame* video_frame,
viz::RasterContextProvider* raster_context_provider,
gpu::SharedImageUsageSet usage) {
viz::SharedImageFormat format =
VideoPixelFormatToSharedImageFormat(video_frame->format());
CHECK(format.is_multi_plane());
if (shared_image_ && provider_ == raster_context_provider) {
// Return the cached shared image if it is the same video frame.
if (video_frame_id_ == video_frame->unique_id()) {
return {shared_image_, sync_token_, Status::kMatchedVideoFrameId};
}
// Return the cached shared image if the video frame data matches the shared
// image data.
if (video_frame->coded_size() == shared_image_->size() &&
video_frame->ColorSpace() == shared_image_->color_space() &&
format == shared_image_->format() && usage == shared_image_->usage()) {
return {shared_image_, sync_token_, Status::kMatchedSharedImageMetaData};
}
}
// If we have cached shared image but the provider or video has changed we
// need to release shared image created on the old context and recreate them.
ReleaseCachedData();
provider_ = raster_context_provider;
CHECK(provider_);
auto* sii = provider_->SharedImageInterface();
CHECK(sii);
// Create a multiplanar shared image to upload the data to.
shared_image_ = sii->CreateSharedImage(
{format, video_frame->coded_size(), video_frame->ColorSpace(),
kTopLeft_GrSurfaceOrigin, kUnpremul_SkAlphaType, usage, "VideoFrameYUV"},
gpu::kNullSurfaceHandle);
CHECK(shared_image_);
video_frame_id_ = video_frame->unique_id();
sync_token_ = sii->GenUnverifiedSyncToken();
return {shared_image_, sync_token_, Status::kCreatedNewSharedImage};
}
void VideoFrameSharedImageCache::UpdateSyncToken(
const gpu::SyncToken& sync_token) {
sync_token_ = sync_token;
}
VideoFrameSharedImageCache::CachedData::CachedData(
scoped_refptr<gpu::ClientSharedImage> shared_image,
const gpu::SyncToken& sync_token,
Status status)
: shared_image(std::move(shared_image)),
sync_token(sync_token),
status(status) {}
VideoFrameSharedImageCache::CachedData::~CachedData() = default;
} // namespace media