Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: mojo/services/media/common/cpp/video_converter.cc

Issue 2068043005: Motown: Video renderer library code (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Fixes per feedback. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/services/media/common/cpp/video_converter.h"
6
7 namespace mojo {
8 namespace media {
9
10 VideoConverter::VideoConverter() {
11 BuildColorspaceTable();
12 }
13
14 VideoConverter::~VideoConverter() {}
15
16 namespace {
17
18 uint8_t ToByte(float f) {
19 if (f < 0.0f) {
20 return 0u;
21 }
22
23 if (f > 255.0f) {
24 return 255u;
25 }
26
27 return static_cast<uint8_t>(f);
28 }
29
30 size_t ColorspaceTableOffset(uint8_t y, uint8_t u, uint8_t v) {
31 return (y << 8u | u) << 8u | v;
32 }
33
34 } // namespace
35
36 void VideoConverter::BuildColorspaceTable() {
37 colorspace_table_.reset(new uint32_t[256 * 256 * 256]);
38
39 uint32_t* p = colorspace_table_.get();
40
41 for (size_t iy = 0; iy < 256; ++iy) {
42 for (size_t iu = 0; iu < 256; ++iu) {
43 for (size_t iv = 0; iv < 256; ++iv) {
44 float y = static_cast<float>(iy);
45 float u = static_cast<float>(iu);
46 float v = static_cast<float>(iv);
47
48 // R = 1.164(Y - 16) + 1.596(V - 128)
49 uint8_t r = ToByte(1.164f * (y - 16.0f) + 1.596f * (v - 128.0f));
50
51 // G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
52 uint8_t g = ToByte(1.164f * (y - 16.0f) - 0.813f * (v - 128.0f) -
53 0.391f * (u - 128.0f));
54
55 // B = 1.164(Y - 16) + 2.018(U - 128)
56 uint8_t b = ToByte(1.164f * (y - 16.0f) + 2.018f * (u - 128.0f));
57
58 *p = r | (g << 8u) | (b << 16u) | (255u << 24u);
59 ++p;
60 }
61 }
62 }
63 }
64
65 void VideoConverter::SetMediaType(const MediaTypePtr& media_type) {
66 MOJO_DCHECK(media_type);
67 MOJO_DCHECK(media_type->medium == MediaTypeMedium::VIDEO);
68 MOJO_DCHECK(media_type->encoding == MediaType::kVideoEncodingUncompressed);
69 MOJO_DCHECK(media_type->details);
70
71 const VideoMediaTypeDetailsPtr& details = media_type->details->get_video();
72 MOJO_DCHECK(details);
73 MOJO_DCHECK(details->pixel_format == PixelFormat::YV12)
74 << "only YV12 video conversion is currently implemented";
75
76 layout_ =
77 VideoPacketLayout(details->pixel_format, details->width, details->height,
78 details->coded_width, details->coded_height);
79
80 media_type_set_ = true;
81 }
82
83 void VideoConverter::ConvertFrame(uint8_t* rgba_buffer,
84 uint32_t view_width,
85 uint32_t view_height,
86 void* payload,
87 uint64_t payload_size) {
88 MOJO_DCHECK(rgba_buffer != nullptr);
89 MOJO_DCHECK(view_width != 0);
90 MOJO_DCHECK(view_height != 0);
91 MOJO_DCHECK(payload != nullptr);
92 MOJO_DCHECK(payload_size != 0);
93 MOJO_DCHECK(media_type_set_)
94 << "need to call SetMediaType before ConvertFrame";
95
96 uint32_t height = std::min(layout_.height(), view_height);
97 uint32_t width = std::min(layout_.width(), view_width);
98
99 // YV12 frames have three separate planes. The Y plane has 8-bit Y values for
100 // each pixel. The U and V planes have 8-bit U and V values for 2x2 grids of
101 // pixels, so those planes are each 1/4 the size of the Y plane. Both the
102 // inner and outer loops below are unrolled to deal with the 2x2 logic.
103
104 size_t dest_line_stride = view_width;
105 size_t y_line_stride =
106 layout_.line_stride_for_plane(VideoPacketLayout::kYPlaneIndex);
107 size_t u_line_stride =
108 layout_.line_stride_for_plane(VideoPacketLayout::kUPlaneIndex);
109 size_t v_line_stride =
110 layout_.line_stride_for_plane(VideoPacketLayout::kVPlaneIndex);
111
112 uint32_t* dest_line = reinterpret_cast<uint32_t*>(
113 rgba_buffer + dest_line_stride * (view_height - 1) * sizeof(uint32_t));
114 uint8_t* y_line =
115 reinterpret_cast<uint8_t*>(payload) +
116 layout_.plane_offset_for_plane(VideoPacketLayout::kYPlaneIndex);
117 uint8_t* u_line =
118 reinterpret_cast<uint8_t*>(payload) +
119 layout_.plane_offset_for_plane(VideoPacketLayout::kUPlaneIndex);
120 uint8_t* v_line =
121 reinterpret_cast<uint8_t*>(payload) +
122 layout_.plane_offset_for_plane(VideoPacketLayout::kVPlaneIndex);
123
124 for (uint32_t line = 0; line < height; ++line) {
125 ConvertLine(dest_line, y_line, u_line, v_line, width);
126
127 dest_line -= dest_line_stride;
128 y_line += y_line_stride;
129 // Notice we aren't updating u_line and v_line here.
130
131 // If we hadn't unrolled the loop, it would have ended here.
132 if (++line == height) {
133 break;
134 }
135
136 ConvertLine(dest_line, y_line, u_line, v_line, width);
137
138 dest_line -= dest_line_stride;
139 y_line += y_line_stride;
140 // Here, we ARE updating u_line and v_line, because we've moved vertically
141 // out of the 2x2 grid.
142 u_line += u_line_stride;
143 v_line += v_line_stride;
144 }
145 }
146
147 void VideoConverter::ConvertLine(uint32_t* dest_pixel,
148 uint8_t* y_pixel,
149 uint8_t* u_pixel,
150 uint8_t* v_pixel,
151 uint32_t width) {
152 for (uint32_t pixel = 0; pixel < width; ++pixel) {
153 *dest_pixel =
154 colorspace_table_
155 .get()[ColorspaceTableOffset(*y_pixel, *u_pixel, *v_pixel)];
156 ++dest_pixel;
157 ++y_pixel;
158 // Notice we aren't incrementing u_pixel and v_pixel here.
159
160 // If we hadn't unrolled the loop, it would have ended here.
161 if (++pixel == width) {
162 break;
163 }
164
165 *dest_pixel =
166 colorspace_table_
167 .get()[ColorspaceTableOffset(*y_pixel, *u_pixel, *v_pixel)];
168 ++dest_pixel;
169 ++y_pixel;
170 // Here, we ARE incrementing u_pixel and v_pixel, because we've moved
171 // horizontally out of the 2x2 grid.
172 ++u_pixel;
173 ++v_pixel;
174 }
175 }
176
177 } // namespace media
178 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/media/common/cpp/video_converter.h ('k') | mojo/services/media/common/cpp/video_packet_layout.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698