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

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

Issue 22590009: EVDA: Add support for dynamic resolution change and MSE players. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 4 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <dlfcn.h> 5 #include <dlfcn.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <linux/videodev2.h> 8 #include <linux/videodev2.h>
9 #include <poll.h> 9 #include <poll.h>
10 #include <sys/eventfd.h> 10 #include <sys/eventfd.h>
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 do { \ 43 do { \
44 if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) { \ 44 if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) { \
45 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 45 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
46 NOTIFY_ERROR(PLATFORM_FAILURE); \ 46 NOTIFY_ERROR(PLATFORM_FAILURE); \
47 return false; \ 47 return false; \
48 } \ 48 } \
49 } while (0) 49 } while (0)
50 50
51 namespace { 51 namespace {
52 52
53 // TODO(posciak): remove once we update linux-headers.
54 #ifndef V4L2_EVENT_RESOLUTION_CHANGE
55 #define V4L2_EVENT_RESOLUTION_CHANGE 5
56 #endif
57
53 const char kExynosMfcDevice[] = "/dev/mfc-dec"; 58 const char kExynosMfcDevice[] = "/dev/mfc-dec";
54 const char kExynosGscDevice[] = "/dev/gsc1"; 59 const char kExynosGscDevice[] = "/dev/gsc1";
55 const char kMaliDriver[] = "libmali.so"; 60 const char kMaliDriver[] = "libmali.so";
56 61
57 typedef EGLBoolean (*MaliEglImageGetBufferExtPhandleFunc)(EGLImageKHR, EGLint*, 62 typedef EGLBoolean (*MaliEglImageGetBufferExtPhandleFunc)(EGLImageKHR, EGLint*,
58 void*); 63 void*);
59 64
60 void* libmali_handle = NULL; 65 void* libmali_handle = NULL;
61 MaliEglImageGetBufferExtPhandleFunc 66 MaliEglImageGetBufferExtPhandleFunc
62 mali_egl_image_get_buffer_ext_phandle = NULL; 67 mali_egl_image_get_buffer_ext_phandle = NULL;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 weak_this_(base::AsWeakPtr(this)), 210 weak_this_(base::AsWeakPtr(this)),
206 client_ptr_factory_(client), 211 client_ptr_factory_(client),
207 client_(client_ptr_factory_.GetWeakPtr()), 212 client_(client_ptr_factory_.GetWeakPtr()),
208 decoder_thread_("ExynosDecoderThread"), 213 decoder_thread_("ExynosDecoderThread"),
209 decoder_state_(kUninitialized), 214 decoder_state_(kUninitialized),
210 decoder_delay_bitstream_buffer_id_(-1), 215 decoder_delay_bitstream_buffer_id_(-1),
211 decoder_current_input_buffer_(-1), 216 decoder_current_input_buffer_(-1),
212 decoder_decode_buffer_tasks_scheduled_(0), 217 decoder_decode_buffer_tasks_scheduled_(0),
213 decoder_frames_at_client_(0), 218 decoder_frames_at_client_(0),
214 decoder_flushing_(false), 219 decoder_flushing_(false),
220 resolution_change_pending_(false),
221 resolution_change_reset_pending_(false),
215 decoder_partial_frame_pending_(false), 222 decoder_partial_frame_pending_(false),
216 mfc_fd_(-1), 223 mfc_fd_(-1),
217 mfc_input_streamon_(false), 224 mfc_input_streamon_(false),
218 mfc_input_buffer_queued_count_(0), 225 mfc_input_buffer_queued_count_(0),
219 mfc_output_streamon_(false), 226 mfc_output_streamon_(false),
220 mfc_output_buffer_queued_count_(0), 227 mfc_output_buffer_queued_count_(0),
221 mfc_output_buffer_pixelformat_(0), 228 mfc_output_buffer_pixelformat_(0),
222 mfc_output_dpb_size_(0), 229 mfc_output_dpb_size_(0),
223 gsc_fd_(-1), 230 gsc_fd_(-1),
224 gsc_input_streamon_(false), 231 gsc_input_streamon_(false),
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 if (!CreateMfcInputBuffers()) 379 if (!CreateMfcInputBuffers())
373 return false; 380 return false;
374 381
375 // MFC output format has to be setup before streaming starts. 382 // MFC output format has to be setup before streaming starts.
376 struct v4l2_format format; 383 struct v4l2_format format;
377 memset(&format, 0, sizeof(format)); 384 memset(&format, 0, sizeof(format));
378 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 385 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
379 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; 386 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16;
380 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format); 387 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format);
381 388
389 // Subscribe to the resolution change event.
390 struct v4l2_event_subscription sub;
391 memset(&sub, 0, sizeof(sub));
392 sub.type = V4L2_EVENT_RESOLUTION_CHANGE;
393 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub);
394
382 // Initialize format-specific bits. 395 // Initialize format-specific bits.
383 if (video_profile_ >= media::H264PROFILE_MIN && 396 if (video_profile_ >= media::H264PROFILE_MIN &&
384 video_profile_ <= media::H264PROFILE_MAX) { 397 video_profile_ <= media::H264PROFILE_MAX) {
385 decoder_h264_parser_.reset(new content::H264Parser()); 398 decoder_h264_parser_.reset(new content::H264Parser());
386 } 399 }
387 400
388 if (!decoder_thread_.Start()) { 401 if (!decoder_thread_.Start()) {
389 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; 402 DLOG(ERROR) << "Initialize(): decoder thread failed to start";
390 NOTIFY_ERROR(PLATFORM_FAILURE); 403 NOTIFY_ERROR(PLATFORM_FAILURE);
391 return false; 404 return false;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask"); 643 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask");
631 644
632 decoder_decode_buffer_tasks_scheduled_--; 645 decoder_decode_buffer_tasks_scheduled_--;
633 646
634 if (decoder_state_ == kResetting) { 647 if (decoder_state_ == kResetting) {
635 DVLOG(2) << "DecodeBufferTask(): early out: kResetting state"; 648 DVLOG(2) << "DecodeBufferTask(): early out: kResetting state";
636 return; 649 return;
637 } else if (decoder_state_ == kError) { 650 } else if (decoder_state_ == kError) {
638 DVLOG(2) << "DecodeBufferTask(): early out: kError state"; 651 DVLOG(2) << "DecodeBufferTask(): early out: kError state";
639 return; 652 return;
653 } else if (decoder_state_ == kChangingResolution) {
654 DVLOG(2) << "DecodeBufferTask(): early out: resolution change pending";
655 return;
640 } 656 }
641 657
642 if (decoder_current_bitstream_buffer_ == NULL) { 658 if (decoder_current_bitstream_buffer_ == NULL) {
643 if (decoder_input_queue_.empty()) { 659 if (decoder_input_queue_.empty()) {
644 // We're waiting for a new buffer -- exit without scheduling a new task. 660 // We're waiting for a new buffer -- exit without scheduling a new task.
645 return; 661 return;
646 } 662 }
647 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front(); 663 linked_ptr<BitstreamBufferRef>& buffer_ref = decoder_input_queue_.front();
648 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) { 664 if (decoder_delay_bitstream_buffer_id_ == buffer_ref->input_id) {
649 // We're asked to delay decoding on this and subsequent buffers. 665 // We're asked to delay decoding on this and subsequent buffers.
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 return true; 871 return true;
856 872
857 if (!FlushInputFrame()) 873 if (!FlushInputFrame())
858 return false; 874 return false;
859 875
860 // Recycle buffers. 876 // Recycle buffers.
861 DequeueMfc(); 877 DequeueMfc();
862 878
863 // Check and see if we have format info yet. 879 // Check and see if we have format info yet.
864 struct v4l2_format format; 880 struct v4l2_format format;
865 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 881 bool again = false;
866 if (ioctl(mfc_fd_, VIDIOC_G_FMT, &format) != 0) { 882 if (!GetFormatInfo(&format, &again))
867 if (errno == EINVAL) { 883 return false;
868 // We will get EINVAL if we haven't seen sufficient stream to decode the 884
869 // format. Return true and schedule the next buffer. 885 if (again) {
870 *endpos = size; 886 // Need more stream to decode format, return true and schedule next buffer.
871 return true; 887 *endpos = size;
872 } else { 888 return true;
873 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT";
874 NOTIFY_ERROR(PLATFORM_FAILURE);
875 return false;
876 }
877 } 889 }
878 890
879 // Run this initialization only on first startup. 891 // Run this initialization only on first startup.
880 if (decoder_state_ == kInitialized) { 892 if (decoder_state_ == kInitialized) {
881 DVLOG(3) << "DecodeBufferInitial(): running one-time initialization"; 893 DVLOG(3) << "DecodeBufferInitial(): running initialization";
882 // Success! Setup our parameters. 894 // Success! Setup our parameters.
883 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); 895 if (!CreateBuffersForFormat(format))
884 frame_buffer_size_.SetSize(
885 format.fmt.pix_mp.width, format.fmt.pix_mp.height);
886 mfc_output_buffer_size_[0] = format.fmt.pix_mp.plane_fmt[0].sizeimage;
887 mfc_output_buffer_size_[1] = format.fmt.pix_mp.plane_fmt[1].sizeimage;
888 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat;
889 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12MT_16X16);
890
891 // Create our other buffers.
892 if (!CreateMfcOutputBuffers() || !CreateGscInputBuffers() ||
893 !CreateGscOutputBuffers())
894 return false; 896 return false;
895 897
896 // MFC expects to process the initial buffer once during stream init to 898 // MFC expects to process the initial buffer once during stream init to
897 // configure stream parameters, but will not consume the steam data on that 899 // configure stream parameters, but will not consume the steam data on that
898 // iteration. Subsequent iterations (including after reset) do not require 900 // iteration. Subsequent iterations (including after reset) do not require
899 // the stream init step. 901 // the stream init step.
900 *endpos = 0; 902 *endpos = 0;
901 } else { 903 } else {
902 *endpos = size; 904 *endpos = size;
903 } 905 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 1059
1058 // Take ownership of the EGLImage and fd. 1060 // Take ownership of the EGLImage and fd.
1059 buffer.egl_image = EGL_NO_IMAGE_KHR; 1061 buffer.egl_image = EGL_NO_IMAGE_KHR;
1060 buffer.egl_image_fd = -1; 1062 buffer.egl_image_fd = -1;
1061 // And add this buffer to the free list. 1063 // And add this buffer to the free list.
1062 gsc_free_output_buffers_.push_back(i); 1064 gsc_free_output_buffers_.push_back(i);
1063 } 1065 }
1064 1066
1065 // We got buffers! Kick the GSC. 1067 // We got buffers! Kick the GSC.
1066 EnqueueGsc(); 1068 EnqueueGsc();
1069
1070 if (decoder_state_ == kChangingResolution)
1071 ResumeAfterResolutionChange();
1067 } 1072 }
1068 1073
1069 void ExynosVideoDecodeAccelerator::ServiceDeviceTask() { 1074 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) {
1070 DVLOG(3) << "ServiceDeviceTask()"; 1075 DVLOG(3) << "ServiceDeviceTask()";
1071 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1076 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1072 DCHECK_NE(decoder_state_, kUninitialized); 1077 DCHECK_NE(decoder_state_, kUninitialized);
1073 DCHECK_NE(decoder_state_, kInitialized); 1078 DCHECK_NE(decoder_state_, kInitialized);
1074 DCHECK_NE(decoder_state_, kAfterReset); 1079 DCHECK_NE(decoder_state_, kAfterReset);
1075 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask"); 1080 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask");
1076 1081
1077 if (decoder_state_ == kResetting) { 1082 if (decoder_state_ == kResetting) {
1078 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; 1083 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state";
1079 return; 1084 return;
1080 } else if (decoder_state_ == kError) { 1085 } else if (decoder_state_ == kError) {
1081 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; 1086 DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
1082 return; 1087 return;
1088 } else if (decoder_state_ == kChangingResolution) {
1089 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state";
1090 return;
1083 } 1091 }
1084 1092
1093 if (mfc_event_pending)
1094 DequeueMfcEvents();
1085 DequeueMfc(); 1095 DequeueMfc();
1086 DequeueGsc(); 1096 DequeueGsc();
1087 EnqueueMfc(); 1097 EnqueueMfc();
1088 EnqueueGsc(); 1098 EnqueueGsc();
1089 1099
1090 // Clear the interrupt fd. 1100 // Clear the interrupt fd.
1091 if (!ClearDevicePollInterrupt()) 1101 if (!ClearDevicePollInterrupt())
1092 return; 1102 return;
1093 1103
1094 unsigned int poll_fds = 0; 1104 unsigned int poll_fds = 0;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 << mfc_output_gsc_input_queue_.size() << " => GSC[" 1136 << mfc_output_gsc_input_queue_.size() << " => GSC["
1127 << gsc_free_input_buffers_.size() << "+" 1137 << gsc_free_input_buffers_.size() << "+"
1128 << gsc_input_buffer_queued_count_ << "/" 1138 << gsc_input_buffer_queued_count_ << "/"
1129 << gsc_input_buffer_map_.size() << "->" 1139 << gsc_input_buffer_map_.size() << "->"
1130 << gsc_free_output_buffers_.size() << "+" 1140 << gsc_free_output_buffers_.size() << "+"
1131 << gsc_output_buffer_queued_count_ << "/" 1141 << gsc_output_buffer_queued_count_ << "/"
1132 << gsc_output_buffer_map_.size() << "] => VDA[" 1142 << gsc_output_buffer_map_.size() << "] => VDA["
1133 << decoder_frames_at_client_ << "]"; 1143 << decoder_frames_at_client_ << "]";
1134 1144
1135 ScheduleDecodeBufferTaskIfNeeded(); 1145 ScheduleDecodeBufferTaskIfNeeded();
1146 StartResolutionChangeIfNeeded();
1136 } 1147 }
1137 1148
1138 void ExynosVideoDecodeAccelerator::EnqueueMfc() { 1149 void ExynosVideoDecodeAccelerator::EnqueueMfc() {
1139 DVLOG(3) << "EnqueueMfc()"; 1150 DVLOG(3) << "EnqueueMfc()";
1140 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1151 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1141 DCHECK_NE(decoder_state_, kUninitialized); 1152 DCHECK_NE(decoder_state_, kUninitialized);
1142 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc"); 1153 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc");
1143 1154
1144 // Drain the pipe of completed decode buffers. 1155 // Drain the pipe of completed decode buffers.
1145 const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_; 1156 const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_;
(...skipping 27 matching lines...) Expand all
1173 return; 1184 return;
1174 // Start VIDIOC_STREAMON if we haven't yet. 1185 // Start VIDIOC_STREAMON if we haven't yet.
1175 if (!mfc_output_streamon_) { 1186 if (!mfc_output_streamon_) {
1176 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1187 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1177 IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type); 1188 IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type);
1178 mfc_output_streamon_ = true; 1189 mfc_output_streamon_ = true;
1179 } 1190 }
1180 } 1191 }
1181 } 1192 }
1182 1193
1194 void ExynosVideoDecodeAccelerator::DequeueMfcEvents() {
1195 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1196 DCHECK_EQ(decoder_state_, kDecoding);
1197 DVLOG(3) << "DequeueMfcEvents()";
Ami GONE FROM CHROMIUM 2013/08/12 03:46:19 Is there some reason you (and your kind, who enjoy
Pawel Osciak 2013/08/12 04:07:45 I do enjoy those traces and they help a lot when d
sheu 2013/08/12 04:49:20 My fault. I just started doing it this way, and h
1198
1199 struct v4l2_event ev;
1200 memset(&ev, 0, sizeof(ev));
1201
1202 while (ioctl(mfc_fd_, VIDIOC_DQEVENT, &ev) == 0) {
1203 if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) {
1204 DVLOG(3) << "DequeueMfcEvents(): got resolution change event.";
1205 DCHECK(!resolution_change_pending_);
1206 resolution_change_pending_ = true;
1207 } else {
1208 DLOG(FATAL) << "DequeueMfcEvents(): got an event (" << ev.type
1209 << ") we haven't subscribed to.";
1210 }
1211 }
1212 }
1213
1183 void ExynosVideoDecodeAccelerator::DequeueMfc() { 1214 void ExynosVideoDecodeAccelerator::DequeueMfc() {
1184 DVLOG(3) << "DequeueMfc()"; 1215 DVLOG(3) << "DequeueMfc()";
1185 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1216 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1186 DCHECK_NE(decoder_state_, kUninitialized); 1217 DCHECK_NE(decoder_state_, kUninitialized);
1187 TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc"); 1218 TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc");
1188 1219
1189 // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free 1220 // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free
1190 // list. 1221 // list.
1191 struct v4l2_buffer dqbuf; 1222 struct v4l2_buffer dqbuf;
1192 struct v4l2_plane planes[2]; 1223 struct v4l2_plane planes[2];
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1531 << picture_buffer_id; 1562 << picture_buffer_id;
1532 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1563 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1533 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask"); 1564 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask");
1534 1565
1535 // We run ReusePictureBufferTask even if we're in kResetting. 1566 // We run ReusePictureBufferTask even if we're in kResetting.
1536 if (decoder_state_ == kError) { 1567 if (decoder_state_ == kError) {
1537 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state"; 1568 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state";
1538 return; 1569 return;
1539 } 1570 }
1540 1571
1572 if (decoder_state_ == kChangingResolution) {
1573 DVLOG(2) << "ReusePictureBufferTask(): early out: kChangingResolution";
1574 return;
1575 }
1576
1541 size_t index; 1577 size_t index;
1542 for (index = 0; index < gsc_output_buffer_map_.size(); ++index) 1578 for (index = 0; index < gsc_output_buffer_map_.size(); ++index)
1543 if (gsc_output_buffer_map_[index].picture_id == picture_buffer_id) 1579 if (gsc_output_buffer_map_[index].picture_id == picture_buffer_id)
1544 break; 1580 break;
1545 1581
1546 if (index >= gsc_output_buffer_map_.size()) { 1582 if (index >= gsc_output_buffer_map_.size()) {
1547 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not found"; 1583 DLOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not found";
1548 NOTIFY_ERROR(INVALID_ARGUMENT); 1584 NOTIFY_ERROR(INVALID_ARGUMENT);
1549 return; 1585 return;
1550 } 1586 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 decoder_delay_bitstream_buffer_id_) 1648 decoder_delay_bitstream_buffer_id_)
1613 return; 1649 return;
1614 } 1650 }
1615 if (decoder_current_input_buffer_ != -1) 1651 if (decoder_current_input_buffer_ != -1)
1616 return; 1652 return;
1617 if ((mfc_input_ready_queue_.size() + 1653 if ((mfc_input_ready_queue_.size() +
1618 mfc_input_buffer_queued_count_ + mfc_output_gsc_input_queue_.size() + 1654 mfc_input_buffer_queued_count_ + mfc_output_gsc_input_queue_.size() +
1619 gsc_input_buffer_queued_count_ + gsc_output_buffer_queued_count_ ) != 0) 1655 gsc_input_buffer_queued_count_ + gsc_output_buffer_queued_count_ ) != 0)
1620 return; 1656 return;
1621 1657
1658 // TODO(posciak): crbug.com/270039. MFC requires a streamoff-streamon
1659 // sequence after flush to continue, even if we are not resetting. This would
1660 // make sense, because we don't really want to resume from a non-resume point
1661 // (e.g. not from an IDR) if we are flushed.
1662 // MSE player however triggers a Flush() on chunk end, but never Reset(). One
1663 // could argue either way, or even say that Flush() is not needed/harmful when
1664 // transitioning to next chunk.
1665 // For now, do the streamoff-streamon cycle to satisfy MFC and not freeze when
1666 // doing MSE. This should be harmless otherwise.
1667 if (!StopDevicePoll(false))
1668 return;
1669
1670 if (!StartDevicePoll())
1671 return;
1672
1622 decoder_delay_bitstream_buffer_id_ = -1; 1673 decoder_delay_bitstream_buffer_id_ = -1;
1623 decoder_flushing_ = false; 1674 decoder_flushing_ = false;
1624 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; 1675 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush";
1625 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 1676 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1626 &Client::NotifyFlushDone, client_)); 1677 &Client::NotifyFlushDone, client_));
1627 1678
1628 // While we were flushing, we early-outed DecodeBufferTask()s. 1679 // While we were flushing, we early-outed DecodeBufferTask()s.
1629 ScheduleDecodeBufferTaskIfNeeded(); 1680 ScheduleDecodeBufferTaskIfNeeded();
1630 } 1681 }
1631 1682
1632 void ExynosVideoDecodeAccelerator::ResetTask() { 1683 void ExynosVideoDecodeAccelerator::ResetTask() {
1633 DVLOG(3) << "ResetTask()"; 1684 DVLOG(3) << "ResetTask()";
1634 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1685 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1635 TRACE_EVENT0("Video Decoder", "EVDA::ResetTask"); 1686 TRACE_EVENT0("Video Decoder", "EVDA::ResetTask");
1636 1687
1637 if (decoder_state_ == kError) { 1688 if (decoder_state_ == kError) {
1638 DVLOG(2) << "ResetTask(): early out: kError state"; 1689 DVLOG(2) << "ResetTask(): early out: kError state";
1639 return; 1690 return;
1640 } 1691 }
1641 1692
1642 // We stop streaming, but we _don't_ destroy our buffers. 1693 // If we are in the middle of switching resolutions, postpone reset until
1643 if (!StopDevicePoll()) 1694 // it's done. We don't have to worry about timing of this wrt to decoding,
1695 // because MFC input pipe is already stopped if we are changing resolution.
1696 // We will come back here after we are done with the resolution change.
1697 DCHECK(!resolution_change_reset_pending_);
1698 if (resolution_change_pending_ || decoder_state_ == kChangingResolution) {
1699 resolution_change_reset_pending_ = true;
1700 return;
1701 }
1702
1703 // We stop streaming and clear buffer tracking info (not preserving
1704 // MFC inputs).
1705 // StopDevicePoll() unconditionally does _not_ destroy buffers, however.
1706 if (!StopDevicePoll(false))
1644 return; 1707 return;
1645 1708
1709 DequeueMfcEvents();
1710
1711 resolution_change_pending_ = false;
1646 decoder_current_bitstream_buffer_.reset(); 1712 decoder_current_bitstream_buffer_.reset();
1647 decoder_input_queue_.clear(); 1713 decoder_input_queue_.clear();
1648 1714
1649 decoder_current_input_buffer_ = -1; 1715 decoder_current_input_buffer_ = -1;
1650 1716
1651 // If we were flushing, we'll never return any more BitstreamBuffers or 1717 // If we were flushing, we'll never return any more BitstreamBuffers or
1652 // PictureBuffers; they have all been dropped and returned by now. 1718 // PictureBuffers; they have all been dropped and returned by now.
1653 NotifyFlushDoneIfNeeded(); 1719 NotifyFlushDoneIfNeeded();
1654 1720
1655 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening 1721 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 ScheduleDecodeBufferTaskIfNeeded(); 1753 ScheduleDecodeBufferTaskIfNeeded();
1688 } 1754 }
1689 1755
1690 void ExynosVideoDecodeAccelerator::DestroyTask() { 1756 void ExynosVideoDecodeAccelerator::DestroyTask() {
1691 DVLOG(3) << "DestroyTask()"; 1757 DVLOG(3) << "DestroyTask()";
1692 TRACE_EVENT0("Video Decoder", "EVDA::DestroyTask"); 1758 TRACE_EVENT0("Video Decoder", "EVDA::DestroyTask");
1693 1759
1694 // DestroyTask() should run regardless of decoder_state_. 1760 // DestroyTask() should run regardless of decoder_state_.
1695 1761
1696 // Stop streaming and the device_poll_thread_. 1762 // Stop streaming and the device_poll_thread_.
1697 StopDevicePoll(); 1763 StopDevicePoll(false);
1698 1764
1699 decoder_current_bitstream_buffer_.reset(); 1765 decoder_current_bitstream_buffer_.reset();
1700 decoder_current_input_buffer_ = -1; 1766 decoder_current_input_buffer_ = -1;
1701 decoder_decode_buffer_tasks_scheduled_ = 0; 1767 decoder_decode_buffer_tasks_scheduled_ = 0;
1702 decoder_frames_at_client_ = 0; 1768 decoder_frames_at_client_ = 0;
1703 decoder_input_queue_.clear(); 1769 decoder_input_queue_.clear();
1704 decoder_flushing_ = false; 1770 decoder_flushing_ = false;
1705 1771
1706 // Set our state to kError. Just in case. 1772 // Set our state to kError. Just in case.
1707 decoder_state_ = kError; 1773 decoder_state_ = kError;
(...skipping 11 matching lines...) Expand all
1719 return false; 1785 return false;
1720 } 1786 }
1721 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1787 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1722 &ExynosVideoDecodeAccelerator::DevicePollTask, 1788 &ExynosVideoDecodeAccelerator::DevicePollTask,
1723 base::Unretained(this), 1789 base::Unretained(this),
1724 0)); 1790 0));
1725 1791
1726 return true; 1792 return true;
1727 } 1793 }
1728 1794
1729 bool ExynosVideoDecodeAccelerator::StopDevicePoll() { 1795 bool ExynosVideoDecodeAccelerator::StopDevicePoll(bool keep_mfc_input_state) {
1730 DVLOG(3) << "StopDevicePoll()"; 1796 DVLOG(3) << "StopDevicePoll()";
1731 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1797 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1732 1798
1733 // Signal the DevicePollTask() to stop, and stop the device poll thread. 1799 // Signal the DevicePollTask() to stop, and stop the device poll thread.
1734 if (!SetDevicePollInterrupt()) 1800 if (!SetDevicePollInterrupt())
1735 return false; 1801 return false;
1736 device_poll_thread_.Stop(); 1802 device_poll_thread_.Stop();
1737 // Clear the interrupt now, to be sure. 1803 // Clear the interrupt now, to be sure.
1738 if (!ClearDevicePollInterrupt()) 1804 if (!ClearDevicePollInterrupt())
1739 return false; 1805 return false;
1740 1806
1741 // Stop streaming. 1807 // Stop streaming.
1742 if (mfc_input_streamon_) { 1808 if (!keep_mfc_input_state) {
1743 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1809 if (mfc_input_streamon_) {
1744 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1810 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1811 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1812 }
1813 mfc_input_streamon_ = false;
1745 } 1814 }
1746 mfc_input_streamon_ = false;
1747 if (mfc_output_streamon_) { 1815 if (mfc_output_streamon_) {
1748 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1816 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1749 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1817 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type);
1750 } 1818 }
1751 mfc_output_streamon_ = false; 1819 mfc_output_streamon_ = false;
1752 if (gsc_input_streamon_) { 1820 if (gsc_input_streamon_) {
1753 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1821 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1754 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type); 1822 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
1755 } 1823 }
1756 gsc_input_streamon_ = false; 1824 gsc_input_streamon_ = false;
1757 if (gsc_output_streamon_) { 1825 if (gsc_output_streamon_) {
1758 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1826 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1759 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type); 1827 IOCTL_OR_ERROR_RETURN_FALSE(gsc_fd_, VIDIOC_STREAMOFF, &type);
1760 } 1828 }
1761 gsc_output_streamon_ = false; 1829 gsc_output_streamon_ = false;
1762 1830
1763 // Reset all our accounting info. 1831 // Reset all our accounting info.
1764 mfc_input_ready_queue_.clear(); 1832 if (!keep_mfc_input_state) {
1765 mfc_free_input_buffers_.clear(); 1833 mfc_input_ready_queue_.clear();
1766 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 1834 mfc_free_input_buffers_.clear();
1767 mfc_free_input_buffers_.push_back(i); 1835 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1768 mfc_input_buffer_map_[i].at_device = false; 1836 mfc_free_input_buffers_.push_back(i);
1769 mfc_input_buffer_map_[i].bytes_used = 0; 1837 mfc_input_buffer_map_[i].at_device = false;
1770 mfc_input_buffer_map_[i].input_id = -1; 1838 mfc_input_buffer_map_[i].bytes_used = 0;
1839 mfc_input_buffer_map_[i].input_id = -1;
1840 }
1841 mfc_input_buffer_queued_count_ = 0;
1771 } 1842 }
1772 mfc_input_buffer_queued_count_ = 0;
1773 mfc_free_output_buffers_.clear(); 1843 mfc_free_output_buffers_.clear();
1774 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 1844 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
1775 mfc_free_output_buffers_.push_back(i); 1845 mfc_free_output_buffers_.push_back(i);
1776 mfc_output_buffer_map_[i].at_device = false; 1846 mfc_output_buffer_map_[i].at_device = false;
1777 mfc_output_buffer_map_[i].input_id = -1; 1847 mfc_output_buffer_map_[i].input_id = -1;
1778 } 1848 }
1779 mfc_output_buffer_queued_count_ = 0; 1849 mfc_output_buffer_queued_count_ = 0;
1780 mfc_output_gsc_input_queue_.clear(); 1850 mfc_output_gsc_input_queue_.clear();
1781 gsc_free_input_buffers_.clear(); 1851 gsc_free_input_buffers_.clear();
1782 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) { 1852 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1823 return true; 1893 return true;
1824 } else { 1894 } else {
1825 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed"; 1895 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed";
1826 NOTIFY_ERROR(PLATFORM_FAILURE); 1896 NOTIFY_ERROR(PLATFORM_FAILURE);
1827 return false; 1897 return false;
1828 } 1898 }
1829 } 1899 }
1830 return true; 1900 return true;
1831 } 1901 }
1832 1902
1903 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() {
1904 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1905 DCHECK_EQ(decoder_state_, kDecoding);
1906
1907 if (!resolution_change_pending_)
1908 return;
1909
1910 if (!mfc_output_gsc_input_queue_.empty() ||
1911 gsc_input_buffer_queued_count_ + gsc_output_buffer_queued_count_ > 0) {
1912 DVLOG(3) << "StartResolutionChangeIfNeeded(): waiting for GSC to finish.";
1913 return;
1914 }
1915
1916 DVLOG(3) << "No more work for GSC, initiate resolution change";
1917
1918 // Keep MFC input queue.
1919 if (!StopDevicePoll(true))
1920 return;
1921
1922 decoder_state_ = kChangingResolution;
1923 DCHECK(resolution_change_pending_);
1924 resolution_change_pending_ = false;
1925
1926 // Post a task to clean up buffers on child thread. This will also ensure
1927 // that we won't accept ReusePictureBuffer() anymore after that.
1928 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1929 &ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers,
1930 weak_this_));
1931 }
1932
1933 void ExynosVideoDecodeAccelerator::FinishResolutionChange() {
1934 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1935 DVLOG(3) << "FinishResolutionChange()";
1936
1937 if (decoder_state_ == kError) {
1938 DVLOG(2) << "FinishResolutionChange(): early out: kError state";
1939 return;
1940 }
1941
1942 struct v4l2_format format;
1943 bool again;
1944 bool ret = GetFormatInfo(&format, &again);
1945 if (!ret || again) {
1946 DVLOG(3) << "Couldn't get format information after resolution change";
1947 NOTIFY_ERROR(PLATFORM_FAILURE);
1948 return;
1949 }
1950
1951 if (!CreateBuffersForFormat(format)) {
1952 DVLOG(3) << "Couldn't reallocate buffers after resolution change";
1953 NOTIFY_ERROR(PLATFORM_FAILURE);
1954 return;
1955 }
1956
1957 // From here we stay in kChangingResolution and wait for
1958 // AssignPictureBuffers() before we can resume.
1959 }
1960
1961 void ExynosVideoDecodeAccelerator::ResumeAfterResolutionChange() {
1962 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1963 DVLOG(3) << "ResumeAfterResolutionChange()";
1964
1965 decoder_state_ = kDecoding;
1966
1967 if (resolution_change_reset_pending_) {
1968 resolution_change_reset_pending_ = false;
1969 ResetTask();
1970 return;
1971 }
1972
1973 if (!StartDevicePoll())
1974 return;
1975
1976 EnqueueMfc();
1977 // Gsc will get enqueued in AssignPictureBuffersTask().
1978 ScheduleDecodeBufferTaskIfNeeded();
1979 }
1980
1833 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) { 1981 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) {
1834 DVLOG(3) << "DevicePollTask()"; 1982 DVLOG(3) << "DevicePollTask()";
1835 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); 1983 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
1836 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask"); 1984 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask");
1837 1985
1838 // This routine just polls the set of device fds, and schedules a 1986 // This routine just polls the set of device fds, and schedules a
1839 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur. 1987 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur.
1840 // Other threads may notify this task to return early by writing to 1988 // Other threads may notify this task to return early by writing to
1841 // device_poll_interrupt_fd_. 1989 // device_poll_interrupt_fd_.
1842 struct pollfd pollfds[3]; 1990 struct pollfd pollfds[3];
1843 nfds_t nfds; 1991 nfds_t nfds;
1992 int mfc_pollfd = -1;
1844 1993
1845 // Add device_poll_interrupt_fd_; 1994 // Add device_poll_interrupt_fd_;
1846 pollfds[0].fd = device_poll_interrupt_fd_; 1995 pollfds[0].fd = device_poll_interrupt_fd_;
1847 pollfds[0].events = POLLIN | POLLERR; 1996 pollfds[0].events = POLLIN | POLLERR;
1848 nfds = 1; 1997 nfds = 1;
1849 1998
1850 if (poll_fds & kPollMfc) { 1999 if (poll_fds & kPollMfc) {
1851 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set"; 2000 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set";
1852 pollfds[nfds].fd = mfc_fd_; 2001 pollfds[nfds].fd = mfc_fd_;
1853 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR; 2002 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI;
2003 mfc_pollfd = nfds;
1854 nfds++; 2004 nfds++;
1855 } 2005 }
1856 // Add GSC fd, if we should poll on it. 2006 // Add GSC fd, if we should poll on it.
1857 // GSC has to wait until both input and output buffers are queued. 2007 // GSC has to wait until both input and output buffers are queued.
1858 if (poll_fds & kPollGsc) { 2008 if (poll_fds & kPollGsc) {
1859 DVLOG(3) << "DevicePollTask(): adding GSC to poll() set"; 2009 DVLOG(3) << "DevicePollTask(): adding GSC to poll() set";
1860 pollfds[nfds].fd = gsc_fd_; 2010 pollfds[nfds].fd = gsc_fd_;
1861 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR; 2011 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR;
1862 nfds++; 2012 nfds++;
1863 } 2013 }
1864 2014
1865 // Poll it! 2015 // Poll it!
1866 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) { 2016 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) {
1867 DPLOG(ERROR) << "DevicePollTask(): poll() failed"; 2017 DPLOG(ERROR) << "DevicePollTask(): poll() failed";
1868 NOTIFY_ERROR(PLATFORM_FAILURE); 2018 NOTIFY_ERROR(PLATFORM_FAILURE);
1869 return; 2019 return;
1870 } 2020 }
1871 2021
2022 bool mfc_event_pending = (mfc_pollfd != -1 &&
2023 pollfds[mfc_pollfd].revents & POLLPRI);
2024
1872 // All processing should happen on ServiceDeviceTask(), since we shouldn't 2025 // All processing should happen on ServiceDeviceTask(), since we shouldn't
1873 // touch decoder state from this thread. 2026 // touch decoder state from this thread.
1874 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 2027 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1875 &ExynosVideoDecodeAccelerator::ServiceDeviceTask, 2028 &ExynosVideoDecodeAccelerator::ServiceDeviceTask,
1876 base::Unretained(this))); 2029 base::Unretained(this), mfc_event_pending));
1877 } 2030 }
1878 2031
1879 void ExynosVideoDecodeAccelerator::NotifyError(Error error) { 2032 void ExynosVideoDecodeAccelerator::NotifyError(Error error) {
1880 DVLOG(2) << "NotifyError()"; 2033 DVLOG(2) << "NotifyError()";
1881 2034
1882 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { 2035 if (!child_message_loop_proxy_->BelongsToCurrentThread()) {
1883 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 2036 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1884 &ExynosVideoDecodeAccelerator::NotifyError, weak_this_, error)); 2037 &ExynosVideoDecodeAccelerator::NotifyError, weak_this_, error));
1885 return; 2038 return;
1886 } 2039 }
(...skipping 12 matching lines...) Expand all
1899 if (decoder_thread_.message_loop() != NULL && 2052 if (decoder_thread_.message_loop() != NULL &&
1900 decoder_thread_.message_loop() != base::MessageLoop::current()) { 2053 decoder_thread_.message_loop() != base::MessageLoop::current()) {
1901 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 2054 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1902 &ExynosVideoDecodeAccelerator::SetDecoderState, 2055 &ExynosVideoDecodeAccelerator::SetDecoderState,
1903 base::Unretained(this), state)); 2056 base::Unretained(this), state));
1904 } else { 2057 } else {
1905 decoder_state_ = state; 2058 decoder_state_ = state;
1906 } 2059 }
1907 } 2060 }
1908 2061
2062 bool ExynosVideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format,
2063 bool* again) {
2064 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2065
2066 *again = false;
2067 memset(format, 0, sizeof(*format));
2068 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2069 if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_G_FMT, format)) != 0) {
2070 if (errno == EINVAL) {
2071 // EINVAL means we haven't seen sufficient stream to decode the format.
2072 *again = true;
2073 return true;
2074 } else {
2075 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT";
2076 NOTIFY_ERROR(PLATFORM_FAILURE);
2077 return false;
2078 }
2079 }
2080
2081 return true;
2082 }
2083
2084 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat(
2085 const struct v4l2_format& format) {
2086 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
2087 CHECK_EQ(format.fmt.pix_mp.num_planes, 2);
2088 frame_buffer_size_.SetSize(
2089 format.fmt.pix_mp.width, format.fmt.pix_mp.height);
2090 mfc_output_buffer_size_[0] = format.fmt.pix_mp.plane_fmt[0].sizeimage;
2091 mfc_output_buffer_size_[1] = format.fmt.pix_mp.plane_fmt[1].sizeimage;
2092 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat;
2093 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12MT_16X16);
2094 DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
2095 << frame_buffer_size_.ToString();
2096
2097 if (!CreateMfcOutputBuffers() || !CreateGscInputBuffers() ||
2098 !CreateGscOutputBuffers())
2099 return false;
2100
2101 return true;
2102 }
2103
1909 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() { 2104 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() {
1910 DVLOG(3) << "CreateMfcInputBuffers()"; 2105 DVLOG(3) << "CreateMfcInputBuffers()";
1911 // We always run this as we prepare to initialize. 2106 // We always run this as we prepare to initialize.
1912 DCHECK_EQ(decoder_state_, kUninitialized); 2107 DCHECK_EQ(decoder_state_, kUninitialized);
1913 DCHECK(!mfc_input_streamon_); 2108 DCHECK(!mfc_input_streamon_);
1914 DCHECK(mfc_input_buffer_map_.empty()); 2109 DCHECK(mfc_input_buffer_map_.empty());
1915 2110
1916 __u32 pixelformat = 0; 2111 __u32 pixelformat = 0;
1917 if (video_profile_ >= media::H264PROFILE_MIN && 2112 if (video_profile_ >= media::H264PROFILE_MIN &&
1918 video_profile_ <= media::H264PROFILE_MAX) { 2113 video_profile_ <= media::H264PROFILE_MAX) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 } 2157 }
1963 mfc_input_buffer_map_[i].address = address; 2158 mfc_input_buffer_map_[i].address = address;
1964 mfc_input_buffer_map_[i].length = buffer.m.planes[0].length; 2159 mfc_input_buffer_map_[i].length = buffer.m.planes[0].length;
1965 } 2160 }
1966 2161
1967 return true; 2162 return true;
1968 } 2163 }
1969 2164
1970 bool ExynosVideoDecodeAccelerator::CreateMfcOutputBuffers() { 2165 bool ExynosVideoDecodeAccelerator::CreateMfcOutputBuffers() {
1971 DVLOG(3) << "CreateMfcOutputBuffers()"; 2166 DVLOG(3) << "CreateMfcOutputBuffers()";
1972 DCHECK_EQ(decoder_state_, kInitialized); 2167 DCHECK(decoder_state_ == kInitialized ||
2168 decoder_state_ == kChangingResolution);
1973 DCHECK(!mfc_output_streamon_); 2169 DCHECK(!mfc_output_streamon_);
1974 DCHECK(mfc_output_buffer_map_.empty()); 2170 DCHECK(mfc_output_buffer_map_.empty());
1975 2171
1976 // Number of MFC output buffers we need. 2172 // Number of MFC output buffers we need.
1977 struct v4l2_control ctrl; 2173 struct v4l2_control ctrl;
1978 memset(&ctrl, 0, sizeof(ctrl)); 2174 memset(&ctrl, 0, sizeof(ctrl));
1979 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; 2175 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
1980 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_G_CTRL, &ctrl); 2176 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_G_CTRL, &ctrl);
1981 mfc_output_dpb_size_ = ctrl.value; 2177 mfc_output_dpb_size_ = ctrl.value;
1982 2178
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 mfc_output_buffer_map_[i].address[j] = address; 2215 mfc_output_buffer_map_[i].address[j] = address;
2020 mfc_output_buffer_map_[i].length[j] = buffer.m.planes[j].length; 2216 mfc_output_buffer_map_[i].length[j] = buffer.m.planes[j].length;
2021 } 2217 }
2022 } 2218 }
2023 2219
2024 return true; 2220 return true;
2025 } 2221 }
2026 2222
2027 bool ExynosVideoDecodeAccelerator::CreateGscInputBuffers() { 2223 bool ExynosVideoDecodeAccelerator::CreateGscInputBuffers() {
2028 DVLOG(3) << "CreateGscInputBuffers()"; 2224 DVLOG(3) << "CreateGscInputBuffers()";
2029 DCHECK_EQ(decoder_state_, kInitialized); 2225 DCHECK(decoder_state_ == kInitialized ||
2226 decoder_state_ == kChangingResolution);
2030 DCHECK(!gsc_input_streamon_); 2227 DCHECK(!gsc_input_streamon_);
2031 DCHECK(gsc_input_buffer_map_.empty()); 2228 DCHECK(gsc_input_buffer_map_.empty());
2032 2229
2033 struct v4l2_format format; 2230 struct v4l2_format format;
2034 memset(&format, 0, sizeof(format)); 2231 memset(&format, 0, sizeof(format));
2035 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 2232 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
2036 format.fmt.pix_mp.width = frame_buffer_size_.width(); 2233 format.fmt.pix_mp.width = frame_buffer_size_.width();
2037 format.fmt.pix_mp.height = frame_buffer_size_.height(); 2234 format.fmt.pix_mp.height = frame_buffer_size_.height();
2038 format.fmt.pix_mp.pixelformat = mfc_output_buffer_pixelformat_; 2235 format.fmt.pix_mp.pixelformat = mfc_output_buffer_pixelformat_;
2039 format.fmt.pix_mp.plane_fmt[0].sizeimage = mfc_output_buffer_size_[0]; 2236 format.fmt.pix_mp.plane_fmt[0].sizeimage = mfc_output_buffer_size_[0];
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) { 2279 for (size_t i = 0; i < gsc_input_buffer_map_.size(); ++i) {
2083 gsc_free_input_buffers_.push_back(i); 2280 gsc_free_input_buffers_.push_back(i);
2084 gsc_input_buffer_map_[i].mfc_output = -1; 2281 gsc_input_buffer_map_[i].mfc_output = -1;
2085 } 2282 }
2086 2283
2087 return true; 2284 return true;
2088 } 2285 }
2089 2286
2090 bool ExynosVideoDecodeAccelerator::CreateGscOutputBuffers() { 2287 bool ExynosVideoDecodeAccelerator::CreateGscOutputBuffers() {
2091 DVLOG(3) << "CreateGscOutputBuffers()"; 2288 DVLOG(3) << "CreateGscOutputBuffers()";
2092 DCHECK_EQ(decoder_state_, kInitialized); 2289 DCHECK(decoder_state_ == kInitialized ||
2290 decoder_state_ == kChangingResolution);
2093 DCHECK(!gsc_output_streamon_); 2291 DCHECK(!gsc_output_streamon_);
2094 DCHECK(gsc_output_buffer_map_.empty()); 2292 DCHECK(gsc_output_buffer_map_.empty());
2095 2293
2096 // GSC outputs into the EGLImages we create from the textures we are 2294 // GSC outputs into the EGLImages we create from the textures we are
2097 // assigned. Assume RGBA8888 format. 2295 // assigned. Assume RGBA8888 format.
2098 struct v4l2_format format; 2296 struct v4l2_format format;
2099 memset(&format, 0, sizeof(format)); 2297 memset(&format, 0, sizeof(format));
2100 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2298 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2101 format.fmt.pix_mp.width = frame_buffer_size_.width(); 2299 format.fmt.pix_mp.width = frame_buffer_size_.width();
2102 format.fmt.pix_mp.height = frame_buffer_size_.height(); 2300 format.fmt.pix_mp.height = frame_buffer_size_.height();
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 2407
2210 size_t i = 0; 2408 size_t i = 0;
2211 do { 2409 do {
2212 GscOutputRecord& output_record = gsc_output_buffer_map_[i]; 2410 GscOutputRecord& output_record = gsc_output_buffer_map_[i];
2213 if (output_record.fd != -1) 2411 if (output_record.fd != -1)
2214 HANDLE_EINTR(close(output_record.fd)); 2412 HANDLE_EINTR(close(output_record.fd));
2215 if (output_record.egl_image != EGL_NO_IMAGE_KHR) 2413 if (output_record.egl_image != EGL_NO_IMAGE_KHR)
2216 eglDestroyImageKHR(egl_display_, output_record.egl_image); 2414 eglDestroyImageKHR(egl_display_, output_record.egl_image);
2217 if (output_record.egl_sync != EGL_NO_SYNC_KHR) 2415 if (output_record.egl_sync != EGL_NO_SYNC_KHR)
2218 eglDestroySyncKHR(egl_display_, output_record.egl_sync); 2416 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
2219 if (client_) 2417 if (client_) {
2418 DVLOG(1) << "DestroyGscOutputBuffers(): "
2419 << "dismissing PictureBuffer id=" << output_record.picture_id;
2220 client_->DismissPictureBuffer(output_record.picture_id); 2420 client_->DismissPictureBuffer(output_record.picture_id);
2421 }
2221 ++i; 2422 ++i;
2222 } while (i < gsc_output_buffer_map_.size()); 2423 } while (i < gsc_output_buffer_map_.size());
2223 } 2424 }
2224 2425
2225 struct v4l2_requestbuffers reqbufs; 2426 struct v4l2_requestbuffers reqbufs;
2226 memset(&reqbufs, 0, sizeof(reqbufs)); 2427 memset(&reqbufs, 0, sizeof(reqbufs));
2227 reqbufs.count = 0; 2428 reqbufs.count = 0;
2228 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 2429 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
2229 reqbufs.memory = V4L2_MEMORY_DMABUF; 2430 reqbufs.memory = V4L2_MEMORY_DMABUF;
2230 if (ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) 2431 if (ioctl(gsc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
2231 DPLOG(ERROR) << "DestroyGscOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS"; 2432 DPLOG(ERROR) << "DestroyGscOutputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
2232 2433
2233 gsc_output_buffer_map_.clear(); 2434 gsc_output_buffer_map_.clear();
2234 gsc_free_output_buffers_.clear(); 2435 gsc_free_output_buffers_.clear();
2235 } 2436 }
2236 2437
2438 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
2439 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
2440 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
2441
2442 DestroyGscInputBuffers();
2443 DestroyGscOutputBuffers();
2444 DestroyMfcOutputBuffers();
2445
2446 // Finish resolution change on decoder thread.
2447 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
2448 &ExynosVideoDecodeAccelerator::FinishResolutionChange,
2449 base::Unretained(this)));
2450 }
2451
2237 } // namespace content 2452 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698