Chromium Code Reviews| 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 587da6bbc04ed5449ccadf7bf00f693f9273d3e4..683311fb13078dd4d623c36446f5b647dc6483f0 100644 |
| --- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc |
| +++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc |
| @@ -270,6 +270,8 @@ bool V4L2VideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
| format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; |
|
Pawel Osciak
2014/03/25 08:21:08
I think we discussed before that this should be fi
|
| IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format); |
| + memset(¤t_format_, 0, sizeof(current_format_)); |
| + |
| // Subscribe to the resolution change event. |
| struct v4l2_event_subscription sub; |
| memset(&sub, 0, sizeof(sub)); |
| @@ -360,9 +362,8 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers( |
| attrs[13] = output_record.fds[1]; |
| attrs[15] = 0; |
| attrs[17] = frame_buffer_size_.width(); |
| - |
| - EGLImageKHR egl_image = eglCreateImageKHR( |
| - egl_display_, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs); |
| + EGLImageKHR egl_image = device_->CreateEGLImage( |
| + egl_display_, attrs, buffers[i].texture_id(), i); |
| if (egl_image == EGL_NO_IMAGE_KHR) { |
| DLOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR"; |
| // Ownership of EGLImages allocated in previous iterations of this loop |
| @@ -372,9 +373,6 @@ void V4L2VideoDecodeAccelerator::AssignPictureBuffers( |
| return; |
| } |
| - glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id()); |
| - glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); |
| - |
| output_record.egl_image = egl_image; |
| output_record.picture_id = buffers[i].id(); |
| free_output_buffers_.push(i); |
| @@ -744,6 +742,7 @@ bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( |
| // Run this initialization only on first startup. |
| if (decoder_state_ == kInitialized) { |
| DVLOG(3) << "DecodeBufferInitial(): running initialization"; |
| + current_format_ = format; |
|
Pawel Osciak
2014/03/25 08:21:08
Please move this to the CreateBuffersForFormat cal
|
| // Success! Setup our parameters. |
| if (!CreateBuffersForFormat(format)) |
| return false; |
| @@ -1005,7 +1004,16 @@ void V4L2VideoDecodeAccelerator::DequeueEvents() { |
| if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) { |
| DVLOG(3) << "DequeueEvents(): got resolution change event."; |
| DCHECK(!resolution_change_pending_); |
| - resolution_change_pending_ = true; |
| + // Check if we already have current_format_ set or this is an event |
|
Pawel Osciak
2014/03/25 08:21:08
s/or this/or if this/
shivdasp
2014/03/25 10:36:40
Done.
|
| + // to trigger decoder initialization. |
| + if ((current_format_.fmt.pix_mp.width == 0) || |
|
Pawel Osciak
2014/03/25 08:21:08
Since you are using the format only for size, I th
shivdasp
2014/03/25 10:36:40
Done.
|
| + (current_format_.fmt.pix_mp.height == 0)) { |
| + DVLOG(3) << "DequeueEvents(): Decoder init through resolution change "; |
| + resolution_change_pending_ = true; |
| + } else if (IsResolutionChangeNecessary()) { |
|
Pawel Osciak
2014/03/25 08:21:08
Also, IsResolutionChangeNecessary() should handle
|
| + DVLOG(3) << "DequeueEvents(): Resolution change event detected "; |
| + resolution_change_pending_ = true; |
| + } |
| } else { |
| DLOG(FATAL) << "DequeueEvents(): got an event (" << ev.type |
| << ") we haven't subscribed to."; |
| @@ -1536,7 +1544,8 @@ void V4L2VideoDecodeAccelerator::FinishResolutionChange() { |
| NOTIFY_ERROR(PLATFORM_FAILURE); |
| return; |
| } |
| - |
| + // Store this new format. |
| + current_format_ = format; |
| if (!CreateBuffersForFormat(format)) { |
| DVLOG(3) << "Couldn't reallocate buffers after resolution change"; |
| NOTIFY_ERROR(PLATFORM_FAILURE); |
| @@ -1759,7 +1768,7 @@ bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() { |
| client_, |
| output_buffer_map_.size(), |
| frame_buffer_size_, |
| - GL_TEXTURE_EXTERNAL_OES)); |
| + device_->GetTextureTarget())); |
| // Wait for the client to call AssignPictureBuffers() on the Child thread. |
| // We do this, because if we continue decoding without finishing buffer |
| @@ -1926,4 +1935,31 @@ void V4L2VideoDecodeAccelerator::PictureCleared() { |
| SendPictureReady(); |
| } |
| +bool V4L2VideoDecodeAccelerator::IsResolutionChangeNecessary() { |
| + DVLOG(3) << "IsResolutionChangeNecessary() "; |
| + struct v4l2_control ctrl; |
| + memset(&ctrl, 0, sizeof(ctrl)); |
| + ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; |
| + IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_G_CTRL, &ctrl); |
| + if (ctrl.value != output_dpb_size_) |
| + return true; |
| + struct v4l2_format format; |
| + bool again = false; |
| + bool ret = GetFormatInfo(&format, &again); |
| + if (!ret || again) { |
| + DVLOG(3) << "IsResolutionChangeNecessary(): GetFormatInfo() failed"; |
| + NOTIFY_ERROR(PLATFORM_FAILURE); |
|
Pawel Osciak
2014/03/25 08:21:08
This means we will send NOTIFY_ERROR twice in case
shivdasp
2014/03/25 10:36:40
Since GetFormatInfo() does NOTIFY_ERROR already I
|
| + return false; |
| + } |
| + if ((format.fmt.pix_mp.width != current_format_.fmt.pix_mp.width) || |
| + (format.fmt.pix_mp.height != current_format_.fmt.pix_mp.height)) { |
| + DVLOG(3) << "IsResolutionChangeNecessary(): Resolution change detected"; |
| + current_format_ = format; |
|
Pawel Osciak
2014/03/25 08:21:08
If you are doing this here, then there is no need
|
| + return true; |
| + } else { |
| + DVLOG(3) << "IsResolutionChangeNecessary(): Dropping resolution change"; |
|
Pawel Osciak
2014/03/25 08:21:08
No need for the else clause, just move it out plea
shivdasp
2014/03/25 10:36:40
Done.
|
| + } |
| + return false; |
| +} |
| + |
| } // namespace content |