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

Side by Side Diff: content/common/gpu/media/v4l2_video_device.cc

Issue 882123004: Renamed v4l2_video_device.*->v4l2_device.* and generic_v4l2_video_device.*->generic_v4l2_device.* a… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changed the include to updated file name. Created 5 years, 10 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 2014 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 <libdrm/drm_fourcc.h>
6 #include <linux/videodev2.h>
7
8 #include "base/numerics/safe_conversions.h"
9 #include "content/common/gpu/media/generic_v4l2_video_device.h"
10 #if defined(ARCH_CPU_ARMEL)
11 #include "content/common/gpu/media/tegra_v4l2_video_device.h"
12 #endif
13
14 // TODO(posciak): remove this once V4L2 headers are updated.
15 #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0')
16 #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4')
17 #define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F')
18
19 namespace content {
20
21 V4L2Device::~V4L2Device() {
22 }
23
24 // static
25 scoped_refptr<V4L2Device> V4L2Device::Create(Type type) {
26 DVLOG(3) << __PRETTY_FUNCTION__;
27
28 scoped_refptr<GenericV4L2Device> generic_device(new GenericV4L2Device(type));
29 if (generic_device->Initialize())
30 return generic_device;
31
32 #if defined(ARCH_CPU_ARMEL)
33 scoped_refptr<TegraV4L2Device> tegra_device(new TegraV4L2Device(type));
34 if (tegra_device->Initialize())
35 return tegra_device;
36 #endif
37
38 LOG(ERROR) << "Failed to create V4L2Device";
39 return scoped_refptr<V4L2Device>();
40 }
41
42 // static
43 media::VideoFrame::Format V4L2Device::V4L2PixFmtToVideoFrameFormat(
44 uint32 pix_fmt) {
45 switch (pix_fmt) {
46 case V4L2_PIX_FMT_NV12:
47 case V4L2_PIX_FMT_NV12M:
48 return media::VideoFrame::NV12;
49
50 case V4L2_PIX_FMT_YUV420:
51 case V4L2_PIX_FMT_YUV420M:
52 return media::VideoFrame::I420;
53
54 case V4L2_PIX_FMT_RGB32:
55 return media::VideoFrame::ARGB;
56
57 default:
58 LOG(FATAL) << "Add more cases as needed";
59 return media::VideoFrame::UNKNOWN;
60 }
61 }
62
63 // static
64 uint32 V4L2Device::VideoFrameFormatToV4L2PixFmt(
65 media::VideoFrame::Format format) {
66 switch (format) {
67 case media::VideoFrame::NV12:
68 return V4L2_PIX_FMT_NV12M;
69
70 case media::VideoFrame::I420:
71 return V4L2_PIX_FMT_YUV420M;
72
73 default:
74 LOG(FATAL) << "Add more cases as needed";
75 return 0;
76 }
77 }
78
79 // static
80 uint32 V4L2Device::VideoCodecProfileToV4L2PixFmt(
81 media::VideoCodecProfile profile,
82 bool slice_based) {
83 if (profile >= media::H264PROFILE_MIN &&
84 profile <= media::H264PROFILE_MAX) {
85 if (slice_based)
86 return V4L2_PIX_FMT_H264_SLICE;
87 else
88 return V4L2_PIX_FMT_H264;
89 } else if (profile >= media::VP8PROFILE_MIN &&
90 profile <= media::VP8PROFILE_MAX) {
91 if (slice_based)
92 return V4L2_PIX_FMT_VP8_FRAME;
93 else
94 return V4L2_PIX_FMT_VP8;
95 } else if (profile >= media::VP9PROFILE_MIN &&
96 profile <= media::VP9PROFILE_MAX) {
97 return V4L2_PIX_FMT_VP9;
98 } else {
99 LOG(FATAL) << "Add more cases as needed";
100 return 0;
101 }
102 }
103
104 // static
105 uint32_t V4L2Device::V4L2PixFmtToDrmFormat(uint32_t format) {
106 switch (format) {
107 case V4L2_PIX_FMT_NV12:
108 case V4L2_PIX_FMT_NV12M:
109 return DRM_FORMAT_NV12;
110
111 case V4L2_PIX_FMT_YUV420:
112 case V4L2_PIX_FMT_YUV420M:
113 return DRM_FORMAT_YUV420;
114
115 case V4L2_PIX_FMT_RGB32:
116 return DRM_FORMAT_ARGB8888;
117
118 default:
119 DVLOG(1) << "Add more cases as needed";
120 return 0;
121 }
122 }
123
124 // static
125 gfx::Size V4L2Device::CodedSizeFromV4L2Format(struct v4l2_format format) {
126 gfx::Size coded_size;
127 gfx::Size visible_size;
128 media::VideoFrame::Format frame_format = media::VideoFrame::UNKNOWN;
129 size_t bytesperline = 0;
130 // Total bytes in the frame.
131 size_t sizeimage = 0;
132
133 if (V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
134 DCHECK_GT(format.fmt.pix_mp.num_planes, 0);
135 bytesperline =
136 base::checked_cast<int>(format.fmt.pix_mp.plane_fmt[0].bytesperline);
137 for (size_t i = 0; i < format.fmt.pix_mp.num_planes; ++i) {
138 sizeimage +=
139 base::checked_cast<int>(format.fmt.pix_mp.plane_fmt[i].sizeimage);
140 }
141 visible_size.SetSize(base::checked_cast<int>(format.fmt.pix_mp.width),
142 base::checked_cast<int>(format.fmt.pix_mp.height));
143 frame_format =
144 V4L2Device::V4L2PixFmtToVideoFrameFormat(format.fmt.pix_mp.pixelformat);
145 } else {
146 bytesperline = base::checked_cast<int>(format.fmt.pix.bytesperline);
147 sizeimage = base::checked_cast<int>(format.fmt.pix.sizeimage);
148 visible_size.SetSize(base::checked_cast<int>(format.fmt.pix.width),
149 base::checked_cast<int>(format.fmt.pix.height));
150 frame_format =
151 V4L2Device::V4L2PixFmtToVideoFrameFormat(format.fmt.pix.pixelformat);
152 }
153
154 // V4L2 does not provide per-plane bytesperline (bpl) when different
155 // components are sharing one physical plane buffer. In this case, it only
156 // provides bpl for the first component in the plane. So we can't depend on it
157 // for calculating height, because bpl may vary within one physical plane
158 // buffer. For example, YUV420 contains 3 components in one physical plane,
159 // with Y at 8 bits per pixel, and Cb/Cr at 4 bits per pixel per component,
160 // but we only get 8 pits per pixel from bytesperline in physical plane 0.
161 // So we need to get total frame bpp from elsewhere to calculate coded height.
162
163 // We need bits per pixel for one component only to calculate
164 // coded_width from bytesperline.
165 int plane_horiz_bits_per_pixel =
166 media::VideoFrame::PlaneHorizontalBitsPerPixel(frame_format, 0);
167
168 // Adding up bpp for each component will give us total bpp for all components.
169 int total_bpp = 0;
170 for (size_t i = 0; i < media::VideoFrame::NumPlanes(frame_format); ++i)
171 total_bpp += media::VideoFrame::PlaneBitsPerPixel(frame_format, i);
172
173 if (sizeimage == 0 || bytesperline == 0 || plane_horiz_bits_per_pixel == 0 ||
174 total_bpp == 0 || (bytesperline * 8) % plane_horiz_bits_per_pixel != 0) {
175 LOG(ERROR) << "Invalid format provided";
176 return coded_size;
177 }
178
179 // Coded width can be calculated by taking the first component's bytesperline,
180 // which in V4L2 always applies to the first component in physical plane
181 // buffer.
182 int coded_width = bytesperline * 8 / plane_horiz_bits_per_pixel;
183 // Sizeimage is coded_width * coded_height * total_bpp.
184 int coded_height = sizeimage * 8 / coded_width / total_bpp;
185
186 coded_size.SetSize(coded_width, coded_height);
187 // It's possible the driver gave us a slightly larger sizeimage than what
188 // would be calculated from coded size. This is technically not allowed, but
189 // some drivers (Exynos) like to have some additional alignment that is not a
190 // multiple of bytesperline. The best thing we can do is to compensate by
191 // aligning to next full row.
192 if (sizeimage > media::VideoFrame::AllocationSize(frame_format, coded_size))
193 coded_size.SetSize(coded_width, coded_height + 1);
194 DVLOG(3) << "coded_size=" << coded_size.ToString();
195
196 // Sanity checks. Calculated coded size has to contain given visible size
197 // and fulfill buffer byte size requirements.
198 DCHECK(gfx::Rect(coded_size).Contains(gfx::Rect(visible_size)));
199 DCHECK_LE(sizeimage,
200 media::VideoFrame::AllocationSize(frame_format, coded_size));
201
202 return coded_size;
203 }
204
205 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/v4l2_video_device.h ('k') | content/common/gpu/media/v4l2_video_encode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698