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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_RENDERERS_SKCANVAS_VIDEO_RENDERER_H_
#define MEDIA_RENDERERS_SKCANVAS_VIDEO_RENDERER_H_
#include <stddef.h>
#include <stdint.h>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "media/base/media_export.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_frame.h"
#include "media/base/video_rotation.h"
#include "media/filters/context_3d.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkRefCnt.h"
namespace gfx {
class RectF;
}
namespace media {
// TODO(enne): rename to PaintCanvasVideoRenderer
// Handles rendering of VideoFrames to PaintCanvases.
class MEDIA_EXPORT SkCanvasVideoRenderer {
public:
SkCanvasVideoRenderer();
~SkCanvasVideoRenderer();
// Paints |video_frame| on |canvas|, scaling and rotating the result to fit
// dimensions specified by |dest_rect|.
// If the format of |video_frame| is PIXEL_FORMAT_NATIVE_TEXTURE, |context_3d|
// must be provided.
//
// Black will be painted on |canvas| if |video_frame| is null.
void Paint(const scoped_refptr<VideoFrame>& video_frame,
cc::PaintCanvas* canvas,
const gfx::RectF& dest_rect,
cc::PaintFlags& flags,
VideoRotation video_rotation,
const Context3D& context_3d);
// Copy |video_frame| on |canvas|.
// If the format of |video_frame| is PIXEL_FORMAT_NATIVE_TEXTURE, |context_3d|
// must be provided.
void Copy(const scoped_refptr<VideoFrame>& video_frame,
cc::PaintCanvas* canvas,
const Context3D& context_3d);
// Convert the contents of |video_frame| to raw RGB pixels. |rgb_pixels|
// should point into a buffer large enough to hold as many 32 bit RGBA pixels
// as are in the visible_rect() area of the frame.
static void ConvertVideoFrameToRGBPixels(const media::VideoFrame* video_frame,
void* rgb_pixels,
size_t row_bytes);
// Copy the contents of texture of |video_frame| to texture |texture|.
// |level|, |internal_format|, |type| specify target texture |texture|.
// The format of |video_frame| must be VideoFrame::NATIVE_TEXTURE.
static void CopyVideoFrameSingleTextureToGLTexture(
gpu::gles2::GLES2Interface* gl,
VideoFrame* video_frame,
unsigned int texture,
unsigned int internal_format,
unsigned int type,
bool premultiply_alpha,
bool flip_y);
// Copy the contents of texture of |video_frame| to texture |texture| in
// context |destination_gl|.
// |level|, |internal_format|, |type| specify target texture |texture|.
// The format of |video_frame| must be VideoFrame::NATIVE_TEXTURE.
// |context_3d| has a GrContext that may be used during the copy.
// Returns true on success.
bool CopyVideoFrameTexturesToGLTexture(
const Context3D& context_3d,
gpu::gles2::GLES2Interface* destination_gl,
const scoped_refptr<VideoFrame>& video_frame,
unsigned int texture,
unsigned int internal_format,
unsigned int type,
bool premultiply_alpha,
bool flip_y);
// Converts unsigned 16-bit value to target |format| for Y16 format and
// calls WebGL texImage2D.
// |level|, |internal_format|, |format|, |type| are WebGL texImage2D
// parameters.
// Returns false if there is no implementation for given parameters.
static bool TexImage2D(unsigned target,
gpu::gles2::GLES2Interface* gl,
VideoFrame* video_frame,
int level,
int internalformat,
unsigned format,
unsigned type,
bool flip_y,
bool premultiply_alpha);
// Converts unsigned 16-bit value to target |format| for Y16 format and
// calls WebGL texSubImage2D.
// |level|, |format|, |type|, |xoffset| and |yoffset| are texSubImage2D
// parameters.
// Returns false if there is no implementation for given parameters.
static bool TexSubImage2D(unsigned target,
gpu::gles2::GLES2Interface* gl,
VideoFrame* video_frame,
int level,
unsigned format,
unsigned type,
int xoffset,
int yoffset,
bool flip_y,
bool premultiply_alpha);
// In general, We hold the most recently painted frame to increase the
// performance for the case that the same frame needs to be painted
// repeatedly. Call this function if you are sure the most recent frame will
// never be painted again, so we can release the resource.
void ResetCache();
void CorrectLastImageDimensions(const SkIRect& visible_rect);
// Used for unit test.
SkISize LastImageDimensionsForTesting();
private:
// Update the cache holding the most-recently-painted frame. Returns false
// if the image couldn't be updated.
bool UpdateLastImage(const scoped_refptr<VideoFrame>& video_frame,
const Context3D& context_3d);
// Last image used to draw to the canvas.
sk_sp<SkImage> last_image_;
// Timestamp of the videoframe used to generate |last_image_|.
base::TimeDelta last_timestamp_ = media::kNoTimestamp;
// If |last_image_| is not used for a while, it's deleted to save memory.
base::DelayTimer last_image_deleting_timer_;
// Used for DCHECKs to ensure method calls executed in the correct thread.
base::ThreadChecker thread_checker_;
// Used for unit test.
SkISize last_image_dimensions_for_testing_;
DISALLOW_COPY_AND_ASSIGN(SkCanvasVideoRenderer);
};
} // namespace media
#endif // MEDIA_RENDERERS_SKCANVAS_VIDEO_RENDERER_H_
|