blob: ee4d1bd509065c21a1cfeb191776a1e67a529ccd [file] [log] [blame]
// Copyright 2021 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.
#include "media/gpu/v4l2/v4l2_utils.h"
#include <sstream>
#include "media/base/video_types.h"
#include "ui/gfx/geometry/size.h"
namespace media {
const char* V4L2MemoryToString(const v4l2_memory memory) {
switch (memory) {
case V4L2_MEMORY_MMAP:
return "V4L2_MEMORY_MMAP";
case V4L2_MEMORY_USERPTR:
return "V4L2_MEMORY_USERPTR";
case V4L2_MEMORY_DMABUF:
return "V4L2_MEMORY_DMABUF";
case V4L2_MEMORY_OVERLAY:
return "V4L2_MEMORY_OVERLAY";
default:
return "UNKNOWN";
}
}
std::string V4L2FormatToString(const struct v4l2_format& format) {
std::ostringstream s;
s << "v4l2_format type: " << format.type;
if (format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
// single-planar
const struct v4l2_pix_format& pix = format.fmt.pix;
s << ", width_height: " << gfx::Size(pix.width, pix.height).ToString()
<< ", pixelformat: " << FourccToString(pix.pixelformat)
<< ", field: " << pix.field << ", bytesperline: " << pix.bytesperline
<< ", sizeimage: " << pix.sizeimage;
} else if (V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
const struct v4l2_pix_format_mplane& pix_mp = format.fmt.pix_mp;
// As long as num_planes's type is uint8_t, ostringstream treats it as a
// char instead of an integer, which is not what we want. Casting
// pix_mp.num_planes unsigned int solves the issue.
s << ", width_height: " << gfx::Size(pix_mp.width, pix_mp.height).ToString()
<< ", pixelformat: " << FourccToString(pix_mp.pixelformat)
<< ", field: " << pix_mp.field
<< ", num_planes: " << static_cast<unsigned int>(pix_mp.num_planes);
for (size_t i = 0; i < pix_mp.num_planes; ++i) {
const struct v4l2_plane_pix_format& plane_fmt = pix_mp.plane_fmt[i];
s << ", plane_fmt[" << i << "].sizeimage: " << plane_fmt.sizeimage
<< ", plane_fmt[" << i << "].bytesperline: " << plane_fmt.bytesperline;
}
} else {
s << " unsupported yet.";
}
return s.str();
}
std::string V4L2BufferToString(const struct v4l2_buffer& buffer) {
std::ostringstream s;
s << "v4l2_buffer type: " << buffer.type << ", memory: " << buffer.memory
<< ", index: " << buffer.index << " bytesused: " << buffer.bytesused
<< ", length: " << buffer.length;
if (buffer.type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
buffer.type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
// single-planar
if (buffer.memory == V4L2_MEMORY_MMAP) {
s << ", m.offset: " << buffer.m.offset;
} else if (buffer.memory == V4L2_MEMORY_USERPTR) {
s << ", m.userptr: " << buffer.m.userptr;
} else if (buffer.memory == V4L2_MEMORY_DMABUF) {
s << ", m.fd: " << buffer.m.fd;
}
} else if (V4L2_TYPE_IS_MULTIPLANAR(buffer.type)) {
for (size_t i = 0; i < buffer.length; ++i) {
const struct v4l2_plane& plane = buffer.m.planes[i];
s << ", m.planes[" << i << "](bytesused: " << plane.bytesused
<< ", length: " << plane.length
<< ", data_offset: " << plane.data_offset;
if (buffer.memory == V4L2_MEMORY_MMAP) {
s << ", m.mem_offset: " << plane.m.mem_offset;
} else if (buffer.memory == V4L2_MEMORY_USERPTR) {
s << ", m.userptr: " << plane.m.userptr;
} else if (buffer.memory == V4L2_MEMORY_DMABUF) {
s << ", m.fd: " << plane.m.fd;
}
s << ")";
}
} else {
s << " unsupported yet.";
}
return s.str();
}
} // namespace media