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

Unified Diff: content/common/gpu/media/v4l2_video_decode_accelerator.cc

Issue 874083005: Fix visible size for V4L2 VDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/media/v4l2_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/media/v4l2_video_decode_accelerator.cc
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
index 019446bbce6467a99384da6a8364142f6cec8f14..82acdce7f067c89172a01ae573a574a4bad219bf 100644
--- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc
+++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
@@ -21,6 +21,7 @@
#include "content/common/gpu/media/v4l2_video_decode_accelerator.h"
#include "media/base/media_switches.h"
#include "media/filters/h264_parser.h"
+#include "ui/gfx/geometry/rect.h"
#include "ui/gl/scoped_binders.h"
#define NOTIFY_ERROR(x) \
@@ -339,7 +340,7 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
// thread is waiting on pictures_assigned_.
DCHECK(free_output_buffers_.empty());
for (size_t i = 0; i < output_buffer_map_.size(); ++i) {
- DCHECK(buffers[i].size() == frame_buffer_size_);
+ DCHECK(buffers[i].size() == coded_size_);
OutputRecord& output_record = output_buffer_map_[i];
DCHECK(!output_record.at_device);
@@ -352,7 +353,7 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
EGLImageKHR egl_image = device_->CreateEGLImage(egl_display_,
egl_context_,
buffers[i].texture_id(),
- frame_buffer_size_,
+ coded_size_,
i,
output_format_fourcc_,
output_planes_count_);
@@ -729,8 +730,9 @@ bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(
// Check and see if we have format info yet.
struct v4l2_format format;
+ gfx::Size visible_size;
bool again = false;
- if (!GetFormatInfo(&format, &again))
+ if (!GetFormatInfo(&format, &visible_size, &again))
return false;
if (again) {
@@ -743,7 +745,7 @@ bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(
if (decoder_state_ == kInitialized) {
DVLOG(3) << "DecodeBufferInitial(): running initialization";
// Success! Setup our parameters.
- if (!CreateBuffersForFormat(format))
+ if (!CreateBuffersForFormat(format, visible_size))
return false;
// We expect to process the initial buffer once during stream init to
@@ -1085,7 +1087,7 @@ void V4L2VideoDecodeAccelerator::Dequeue() {
<< " as picture_id=" << output_record.picture_id;
const media::Picture& picture =
media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec,
- gfx::Rect(frame_buffer_size_), false);
+ gfx::Rect(visible_size_), false);
pending_picture_ready_.push(
PictureRecord(output_record.cleared, picture));
SendPictureReady();
@@ -1533,14 +1535,15 @@ void V4L2VideoDecodeAccelerator::FinishResolutionChange() {
struct v4l2_format format;
bool again;
- bool ret = GetFormatInfo(&format, &again);
+ gfx::Size visible_size;
+ bool ret = GetFormatInfo(&format, &visible_size, &again);
if (!ret || again) {
LOG(ERROR) << "Couldn't get format information after resolution change";
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
}
- if (!CreateBuffersForFormat(format)) {
+ if (!CreateBuffersForFormat(format, visible_size)) {
LOG(ERROR) << "Couldn't reallocate buffers after resolution change";
NOTIFY_ERROR(PLATFORM_FAILURE);
return;
@@ -1615,7 +1618,8 @@ void V4L2VideoDecodeAccelerator::SetErrorState(Error error) {
}
bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format,
- bool* again) {
+ gfx::Size* visible_size,
+ bool* again) {
DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
*again = false;
@@ -1639,17 +1643,22 @@ bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format,
return false;
}
+ gfx::Size coded_size(format->fmt.pix_mp.width, format->fmt.pix_mp.height);
+ if (!GetVisibleSize(coded_size, visible_size))
+ *visible_size = coded_size;
+
return true;
}
bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
- const struct v4l2_format& format) {
+ const struct v4l2_format& format,
+ const gfx::Size& visible_size) {
DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
output_planes_count_ = format.fmt.pix_mp.num_planes;
- frame_buffer_size_.SetSize(
- format.fmt.pix_mp.width, format.fmt.pix_mp.height);
+ coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height);
+ visible_size_ = visible_size;
DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
- << frame_buffer_size_.ToString();
+ << coded_size_.ToString();
if (!CreateOutputBuffers())
return false;
@@ -1657,6 +1666,40 @@ bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
return true;
}
+bool V4L2VideoDecodeAccelerator::GetVisibleSize(const gfx::Size& coded_size,
+ gfx::Size* visible_size) {
+ DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
+
+ struct v4l2_crop crop_arg;
+ memset(&crop_arg, 0, sizeof(crop_arg));
+ crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CROP, &crop_arg);
+
+ gfx::Rect rect(crop_arg.c.left, crop_arg.c.top, crop_arg.c.width,
+ crop_arg.c.height);
+ DVLOG(3) << "visible rectangle is " << rect.ToString();
+ if (!gfx::Rect(coded_size).Contains(rect)) {
+ DLOG(ERROR) << "visible rectangle " << rect.ToString()
+ << " is not inside coded size " << coded_size.ToString();
+ return false;
+ }
+ if (rect.IsEmpty()) {
+ DLOG(ERROR) << "visible size is empty";
+ return false;
+ }
+
+ // Chrome assume picture frame is coded at (0, 0).
+ if (!rect.origin().IsOrigin()) {
+ DLOG(ERROR) << "Unexpected visible rectangle " << rect.ToString()
+ << ", top-left is not origin";
+ return false;
+ }
+ *visible_size = rect.size();
+
+ return true;
+}
+
bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
DVLOG(3) << "CreateInputBuffers()";
// We always run this as we prepare to initialize.
@@ -1786,13 +1829,12 @@ bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() {
DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): "
<< "buffer_count=" << output_buffer_map_.size()
- << ", width=" << frame_buffer_size_.width()
- << ", height=" << frame_buffer_size_.height();
+ << ", coded_size=" << coded_size_.ToString();
child_message_loop_proxy_->PostTask(FROM_HERE,
base::Bind(&Client::ProvidePictureBuffers,
client_,
output_buffer_map_.size(),
- frame_buffer_size_,
+ coded_size_,
device_->GetTextureTarget()));
// Wait for the client to call AssignPictureBuffers() on the Child thread.
@@ -1965,15 +2007,16 @@ bool V4L2VideoDecodeAccelerator::IsResolutionChangeNecessary() {
return true;
}
struct v4l2_format format;
+ gfx::Size visible_size;
bool again = false;
- bool ret = GetFormatInfo(&format, &again);
+ bool ret = GetFormatInfo(&format, &visible_size, &again);
if (!ret || again) {
DVLOG(3) << "IsResolutionChangeNecessary(): GetFormatInfo() failed";
return false;
}
- gfx::Size new_size(base::checked_cast<int>(format.fmt.pix_mp.width),
- base::checked_cast<int>(format.fmt.pix_mp.height));
- if (frame_buffer_size_ != new_size) {
+ gfx::Size new_coded_size(base::checked_cast<int>(format.fmt.pix_mp.width),
+ base::checked_cast<int>(format.fmt.pix_mp.height));
+ if (coded_size_ != new_coded_size) {
DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected";
return true;
}
« no previous file with comments | « content/common/gpu/media/v4l2_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698