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

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

Issue 104713014: VDA: Restructure EVDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 12 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 <libdrm/drm_fourcc.h> 8 #include <libdrm/drm_fourcc.h>
9 #include <linux/videodev2.h> 9 #include <linux/videodev2.h>
10 #include <poll.h> 10 #include <poll.h>
(...skipping 15 matching lines...) Expand all
26 26
27 #define NOTIFY_ERROR(x) \ 27 #define NOTIFY_ERROR(x) \
28 do { \ 28 do { \
29 SetDecoderState(kError); \ 29 SetDecoderState(kError); \
30 DLOG(ERROR) << "calling NotifyError(): " << x; \ 30 DLOG(ERROR) << "calling NotifyError(): " << x; \
31 NotifyError(x); \ 31 NotifyError(x); \
32 } while (0) 32 } while (0)
33 33
34 #define IOCTL_OR_ERROR_RETURN(fd, type, arg) \ 34 #define IOCTL_OR_ERROR_RETURN(fd, type, arg) \
35 do { \ 35 do { \
36 if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) { \ 36 if (HANDLE_EINTR(device->dev_ioctl(fd, type, arg) != 0)) { \
Pawel Osciak 2013/12/24 03:45:24 Please ensure device isn't NULL.
37 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 37 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
38 NOTIFY_ERROR(PLATFORM_FAILURE); \ 38 NOTIFY_ERROR(PLATFORM_FAILURE); \
39 return; \ 39 return; \
40 } \ 40 } \
41 } while (0) 41 } while (0)
42 42
43 #define IOCTL_OR_ERROR_RETURN_FALSE(fd, type, arg) \ 43 #define IOCTL_OR_ERROR_RETURN_FALSE(fd, type, arg) \
44 do { \ 44 do { \
45 if (HANDLE_EINTR(ioctl(fd, type, arg) != 0)) { \ 45 if (HANDLE_EINTR(device->dev_ioctl(fd, type, arg) != 0)) { \
46 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \ 46 DPLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
47 NOTIFY_ERROR(PLATFORM_FAILURE); \ 47 NOTIFY_ERROR(PLATFORM_FAILURE); \
48 return false; \ 48 return false; \
49 } \ 49 } \
50 } while (0) 50 } while (0)
51 51
52 namespace { 52 namespace {
53 53
54 // TODO(posciak): remove once we update linux-headers. 54 // TODO(posciak): remove once we update linux-headers.
55 #ifndef V4L2_EVENT_RESOLUTION_CHANGE 55 #ifndef V4L2_EVENT_RESOLUTION_CHANGE
56 #define V4L2_EVENT_RESOLUTION_CHANGE 5 56 #define V4L2_EVENT_RESOLUTION_CHANGE 5
57 #endif 57 #endif
58 58
59 const char kExynosMfcDevice[] = "/dev/mfc-dec"; 59 const char kExynosMfcDevice[] = "/dev/mfc-dec";
Pawel Osciak 2013/12/24 03:45:24 This should be a property of the ExynosV4L2Device
60 60
61 } // anonymous namespace 61 } // anonymous namespace
62 62
63 struct ExynosVideoDecodeAccelerator::BitstreamBufferRef { 63 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_open (const char *fd,
Pawel Osciak 2013/12/24 03:45:24 Extract to separate file. Also style (spacing, ind
64 int flags) {
65 return HANDLE_EINTR(open(fd,flags));
66 }
67
68 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_ioctl (int fd,
69 int flags, void *arg) {
70 return ioctl(fd, flags, arg);
Pawel Osciak 2013/12/24 03:45:24 HANDLE_EINTR?
71 }
72
73 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_close (int fd) {
74 return close(fd);
75 }
76
77 int V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_poll (
78 struct pollfd *fds, nfds_t nfds, int n) {
79 return poll(fds, nfds, n);
Pawel Osciak 2013/12/24 03:45:24 HANDLE_EINTR?
80 }
81
82 void* V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_mmap (void *addr,
83 unsigned int len, int prot, int flags, int fd, unsigned int offset) {
84 return mmap(addr, len, prot, flags, fd, offset);
85 }
86
87 void V4L2VideoDecodeAccelerator :: ExynosV4L2Device :: dev_munmap (void *addr,
88 unsigned int len) {
89 munmap(addr,len);
90 }
91
92 struct V4L2VideoDecodeAccelerator::BitstreamBufferRef {
64 BitstreamBufferRef( 93 BitstreamBufferRef(
65 base::WeakPtr<Client>& client, 94 base::WeakPtr<Client>& client,
66 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, 95 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
67 base::SharedMemory* shm, 96 base::SharedMemory* shm,
68 size_t size, 97 size_t size,
69 int32 input_id); 98 int32 input_id);
70 ~BitstreamBufferRef(); 99 ~BitstreamBufferRef();
71 const base::WeakPtr<Client> client; 100 const base::WeakPtr<Client> client;
72 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy; 101 const scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy;
73 const scoped_ptr<base::SharedMemory> shm; 102 const scoped_ptr<base::SharedMemory> shm;
74 const size_t size; 103 const size_t size;
75 off_t bytes_used; 104 off_t bytes_used;
76 const int32 input_id; 105 const int32 input_id;
77 }; 106 };
78 107
79 struct ExynosVideoDecodeAccelerator::PictureBufferArrayRef { 108 struct V4L2VideoDecodeAccelerator::PictureBufferArrayRef {
80 PictureBufferArrayRef(EGLDisplay egl_display); 109 PictureBufferArrayRef(EGLDisplay egl_display);
81 ~PictureBufferArrayRef(); 110 ~PictureBufferArrayRef();
82 111
83 struct PictureBufferRef { 112 struct PictureBufferRef {
84 PictureBufferRef(EGLImageKHR egl_image, int32 picture_id) 113 PictureBufferRef(EGLImageKHR egl_image, int32 picture_id)
85 : egl_image(egl_image), picture_id(picture_id) {} 114 : egl_image(egl_image), picture_id(picture_id) {}
86 EGLImageKHR egl_image; 115 EGLImageKHR egl_image;
87 int32 picture_id; 116 int32 picture_id;
88 }; 117 };
89 118
90 EGLDisplay const egl_display; 119 EGLDisplay const egl_display;
91 std::vector<PictureBufferRef> picture_buffers; 120 std::vector<PictureBufferRef> picture_buffers;
92 }; 121 };
93 122
94 struct ExynosVideoDecodeAccelerator::EGLSyncKHRRef { 123 struct V4L2VideoDecodeAccelerator::EGLSyncKHRRef {
95 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync); 124 EGLSyncKHRRef(EGLDisplay egl_display, EGLSyncKHR egl_sync);
96 ~EGLSyncKHRRef(); 125 ~EGLSyncKHRRef();
97 EGLDisplay const egl_display; 126 EGLDisplay const egl_display;
98 EGLSyncKHR egl_sync; 127 EGLSyncKHR egl_sync;
99 }; 128 };
100 129
101 struct ExynosVideoDecodeAccelerator::PictureRecord { 130 struct V4L2VideoDecodeAccelerator::PictureRecord {
102 PictureRecord(bool cleared, const media::Picture& picture); 131 PictureRecord(bool cleared, const media::Picture& picture);
103 ~PictureRecord(); 132 ~PictureRecord();
104 bool cleared; // Whether the texture is cleared and safe to render from. 133 bool cleared; // Whether the texture is cleared and safe to render from.
105 media::Picture picture; // The decoded picture. 134 media::Picture picture; // The decoded picture.
106 }; 135 };
107 136
108 ExynosVideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef( 137 V4L2VideoDecodeAccelerator::BitstreamBufferRef::BitstreamBufferRef(
109 base::WeakPtr<Client>& client, 138 base::WeakPtr<Client>& client,
110 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy, 139 scoped_refptr<base::MessageLoopProxy>& client_message_loop_proxy,
111 base::SharedMemory* shm, size_t size, int32 input_id) 140 base::SharedMemory* shm, size_t size, int32 input_id)
112 : client(client), 141 : client(client),
113 client_message_loop_proxy(client_message_loop_proxy), 142 client_message_loop_proxy(client_message_loop_proxy),
114 shm(shm), 143 shm(shm),
115 size(size), 144 size(size),
116 bytes_used(0), 145 bytes_used(0),
117 input_id(input_id) { 146 input_id(input_id) {
118 } 147 }
119 148
120 ExynosVideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() { 149 V4L2VideoDecodeAccelerator::BitstreamBufferRef::~BitstreamBufferRef() {
121 if (input_id >= 0) { 150 if (input_id >= 0) {
122 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind( 151 client_message_loop_proxy->PostTask(FROM_HERE, base::Bind(
123 &Client::NotifyEndOfBitstreamBuffer, client, input_id)); 152 &Client::NotifyEndOfBitstreamBuffer, client, input_id));
124 } 153 }
125 } 154 }
126 155
127 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef( 156 V4L2VideoDecodeAccelerator::PictureBufferArrayRef::PictureBufferArrayRef(
128 EGLDisplay egl_display) 157 EGLDisplay egl_display)
129 : egl_display(egl_display) {} 158 : egl_display(egl_display) {}
130 159
131 ExynosVideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() { 160 V4L2VideoDecodeAccelerator::PictureBufferArrayRef::~PictureBufferArrayRef() {
132 for (size_t i = 0; i < picture_buffers.size(); ++i) { 161 for (size_t i = 0; i < picture_buffers.size(); ++i) {
133 EGLImageKHR egl_image = picture_buffers[i].egl_image; 162 EGLImageKHR egl_image = picture_buffers[i].egl_image;
134 if (egl_image != EGL_NO_IMAGE_KHR) 163 if (egl_image != EGL_NO_IMAGE_KHR)
135 eglDestroyImageKHR(egl_display, egl_image); 164 eglDestroyImageKHR(egl_display, egl_image);
136 } 165 }
137 } 166 }
138 167
139 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef( 168 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::EGLSyncKHRRef(
140 EGLDisplay egl_display, EGLSyncKHR egl_sync) 169 EGLDisplay egl_display, EGLSyncKHR egl_sync)
141 : egl_display(egl_display), 170 : egl_display(egl_display),
142 egl_sync(egl_sync) { 171 egl_sync(egl_sync) {
143 } 172 }
144 173
145 ExynosVideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() { 174 V4L2VideoDecodeAccelerator::EGLSyncKHRRef::~EGLSyncKHRRef() {
146 if (egl_sync != EGL_NO_SYNC_KHR) 175 if (egl_sync != EGL_NO_SYNC_KHR)
147 eglDestroySyncKHR(egl_display, egl_sync); 176 eglDestroySyncKHR(egl_display, egl_sync);
148 } 177 }
149 178
150 ExynosVideoDecodeAccelerator::MfcInputRecord::MfcInputRecord() 179 V4L2VideoDecodeAccelerator::MfcInputRecord::MfcInputRecord()
151 : at_device(false), 180 : at_device(false),
152 address(NULL), 181 address(NULL),
153 length(0), 182 length(0),
154 bytes_used(0), 183 bytes_used(0),
155 input_id(-1) { 184 input_id(-1) {
156 } 185 }
157 186
158 ExynosVideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() { 187 V4L2VideoDecodeAccelerator::MfcInputRecord::~MfcInputRecord() {
159 } 188 }
160 189
161 ExynosVideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord() 190 V4L2VideoDecodeAccelerator::MfcOutputRecord::MfcOutputRecord()
162 : at_device(false), 191 : at_device(false),
163 at_client(false), 192 at_client(false),
164 egl_image(EGL_NO_IMAGE_KHR), 193 egl_image(EGL_NO_IMAGE_KHR),
165 egl_sync(EGL_NO_SYNC_KHR), 194 egl_sync(EGL_NO_SYNC_KHR),
166 picture_id(-1), 195 picture_id(-1),
167 cleared(false) { 196 cleared(false) {
168 for (size_t i = 0; i < arraysize(fds); ++i) 197 for (size_t i = 0; i < arraysize(fds); ++i)
169 fds[i] = -1; 198 fds[i] = -1;
170 } 199 }
171 200
172 ExynosVideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {} 201 V4L2VideoDecodeAccelerator::MfcOutputRecord::~MfcOutputRecord() {}
173 202
174 ExynosVideoDecodeAccelerator::PictureRecord::PictureRecord( 203 V4L2VideoDecodeAccelerator::PictureRecord::PictureRecord(
175 bool cleared, 204 bool cleared,
176 const media::Picture& picture) 205 const media::Picture& picture)
177 : cleared(cleared), picture(picture) {} 206 : cleared(cleared), picture(picture) {}
178 207
179 ExynosVideoDecodeAccelerator::PictureRecord::~PictureRecord() {} 208 V4L2VideoDecodeAccelerator::PictureRecord::~PictureRecord() {}
180 209
181 ExynosVideoDecodeAccelerator::ExynosVideoDecodeAccelerator( 210 V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator(
182 EGLDisplay egl_display, 211 EGLDisplay egl_display,
183 EGLContext egl_context,
184 Client* client, 212 Client* client,
185 const base::WeakPtr<Client>& io_client, 213 const base::WeakPtr<Client>& io_client,
186 const base::Callback<bool(void)>& make_context_current, 214 const base::Callback<bool(void)>& make_context_current,
187 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy) 215 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy)
188 : child_message_loop_proxy_(base::MessageLoopProxy::current()), 216 : child_message_loop_proxy_(base::MessageLoopProxy::current()),
189 io_message_loop_proxy_(io_message_loop_proxy), 217 io_message_loop_proxy_(io_message_loop_proxy),
190 weak_this_(base::AsWeakPtr(this)), 218 weak_this_(base::AsWeakPtr(this)),
191 client_ptr_factory_(client), 219 client_ptr_factory_(client),
192 client_(client_ptr_factory_.GetWeakPtr()), 220 client_(client_ptr_factory_.GetWeakPtr()),
193 io_client_(io_client), 221 io_client_(io_client),
194 decoder_thread_("ExynosDecoderThread"), 222 decoder_thread_("V4L2DecoderThread"),
195 decoder_state_(kUninitialized), 223 decoder_state_(kUninitialized),
196 decoder_delay_bitstream_buffer_id_(-1), 224 decoder_delay_bitstream_buffer_id_(-1),
197 decoder_current_input_buffer_(-1), 225 decoder_current_input_buffer_(-1),
198 decoder_decode_buffer_tasks_scheduled_(0), 226 decoder_decode_buffer_tasks_scheduled_(0),
199 decoder_frames_at_client_(0), 227 decoder_frames_at_client_(0),
200 decoder_flushing_(false), 228 decoder_flushing_(false),
201 resolution_change_pending_(false), 229 resolution_change_pending_(false),
202 resolution_change_reset_pending_(false), 230 resolution_change_reset_pending_(false),
203 decoder_partial_frame_pending_(false), 231 decoder_partial_frame_pending_(false),
204 mfc_fd_(-1), 232 videodec_fd_(-1),
205 mfc_input_streamon_(false), 233 mfc_input_streamon_(false),
206 mfc_input_buffer_queued_count_(0), 234 mfc_input_buffer_queued_count_(0),
207 mfc_output_streamon_(false), 235 mfc_output_streamon_(false),
208 mfc_output_buffer_queued_count_(0), 236 mfc_output_buffer_queued_count_(0),
209 mfc_output_buffer_pixelformat_(0), 237 mfc_output_buffer_pixelformat_(0),
210 mfc_output_dpb_size_(0), 238 mfc_output_dpb_size_(0),
211 picture_clearing_count_(0), 239 picture_clearing_count_(0),
212 device_poll_thread_("ExynosDevicePollThread"), 240 device_poll_thread_("V4L2DevicePollThread"),
213 device_poll_interrupt_fd_(-1), 241 device_poll_interrupt_fd_(-1),
214 make_context_current_(make_context_current), 242 make_context_current_(make_context_current),
215 egl_display_(egl_display), 243 egl_display_(egl_display),
216 egl_context_(egl_context),
217 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {} 244 video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN) {}
218 245
219 ExynosVideoDecodeAccelerator::~ExynosVideoDecodeAccelerator() { 246 V4L2VideoDecodeAccelerator::~V4L2VideoDecodeAccelerator() {
220 DCHECK(!decoder_thread_.IsRunning()); 247 DCHECK(!decoder_thread_.IsRunning());
221 DCHECK(!device_poll_thread_.IsRunning()); 248 DCHECK(!device_poll_thread_.IsRunning());
222 249
223 if (device_poll_interrupt_fd_ != -1) { 250 if (device_poll_interrupt_fd_ != -1) {
224 close(device_poll_interrupt_fd_); 251 device->dev_close(device_poll_interrupt_fd_);
Pawel Osciak 2013/12/24 03:45:24 What if device has never been allocated (before In
225 device_poll_interrupt_fd_ = -1; 252 device_poll_interrupt_fd_ = -1;
226 } 253 }
227 if (mfc_fd_ != -1) { 254 if (videodec_fd_ != -1) {
228 DestroyMfcInputBuffers(); 255 DestroyMfcInputBuffers();
229 DestroyMfcOutputBuffers(); 256 DestroyMfcOutputBuffers();
230 close(mfc_fd_); 257 device->dev_close(videodec_fd_);
231 mfc_fd_ = -1; 258 videodec_fd_ = -1;
232 } 259 }
233 260
234 // These maps have members that should be manually destroyed, e.g. file 261 // These maps have members that should be manually destroyed, e.g. file
235 // descriptors, mmap() segments, etc. 262 // descriptors, mmap() segments, etc.
236 DCHECK(mfc_input_buffer_map_.empty()); 263 DCHECK(mfc_input_buffer_map_.empty());
237 DCHECK(mfc_output_buffer_map_.empty()); 264 DCHECK(mfc_output_buffer_map_.empty());
238 } 265 }
239 266
240 bool ExynosVideoDecodeAccelerator::Initialize( 267 bool V4L2VideoDecodeAccelerator::Initialize(
241 media::VideoCodecProfile profile) { 268 media::VideoCodecProfile profile) {
242 DVLOG(3) << "Initialize()"; 269 DVLOG(3) << "Initialize()";
243 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 270 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
244 DCHECK_EQ(decoder_state_, kUninitialized); 271 DCHECK_EQ(decoder_state_, kUninitialized);
245 272
246 switch (profile) { 273 switch (profile) {
247 case media::H264PROFILE_BASELINE: 274 case media::H264PROFILE_BASELINE:
248 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE"; 275 DVLOG(2) << "Initialize(): profile H264PROFILE_BASELINE";
249 break; 276 break;
250 case media::H264PROFILE_MAIN: 277 case media::H264PROFILE_MAIN:
(...skipping 10 matching lines...) Expand all
261 return false; 288 return false;
262 }; 289 };
263 video_profile_ = profile; 290 video_profile_ = profile;
264 291
265 if (egl_display_ == EGL_NO_DISPLAY) { 292 if (egl_display_ == EGL_NO_DISPLAY) {
266 DLOG(ERROR) << "Initialize(): could not get EGLDisplay"; 293 DLOG(ERROR) << "Initialize(): could not get EGLDisplay";
267 NOTIFY_ERROR(PLATFORM_FAILURE); 294 NOTIFY_ERROR(PLATFORM_FAILURE);
268 return false; 295 return false;
269 } 296 }
270 297
271 if (egl_context_ == EGL_NO_CONTEXT) {
272 DLOG(ERROR) << "Initialize(): could not get EGLContext";
273 NOTIFY_ERROR(PLATFORM_FAILURE);
274 return false;
275 }
276
277 // We need the context to be initialized to query extensions. 298 // We need the context to be initialized to query extensions.
278 if (!make_context_current_.Run()) { 299 if (!make_context_current_.Run()) {
279 DLOG(ERROR) << "Initialize(): could not make context current"; 300 DLOG(ERROR) << "Initialize(): could not make context current";
280 NOTIFY_ERROR(PLATFORM_FAILURE); 301 NOTIFY_ERROR(PLATFORM_FAILURE);
281 return false; 302 return false;
282 } 303 }
283 304
284 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) { 305 if (!gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
285 DLOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync"; 306 DLOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync";
286 NOTIFY_ERROR(PLATFORM_FAILURE); 307 NOTIFY_ERROR(PLATFORM_FAILURE);
287 return false; 308 return false;
288 } 309 }
289 310
290 // Open the video devices. 311 // Open the video devices.
291 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice; 312 DVLOG(2) << "Initialize(): opening MFC device: " << kExynosMfcDevice;
Pawel Osciak 2013/12/24 03:45:24 Please scrub Exynos from this class.
292 mfc_fd_ = HANDLE_EINTR(open(kExynosMfcDevice, 313 device = new ExynosV4L2Device;
Pawel Osciak 2013/12/24 03:45:24 I don't see this being freed anywhere.? In any cas
293 O_RDWR | O_NONBLOCK | O_CLOEXEC)); 314
294 if (mfc_fd_ == -1) { 315 videodec_fd_ = device->dev_open(kExynosMfcDevice,
316 O_RDWR | O_NONBLOCK | O_CLOEXEC);
317
318 if (videodec_fd_ == -1) {
295 DPLOG(ERROR) << "Initialize(): could not open MFC device: " 319 DPLOG(ERROR) << "Initialize(): could not open MFC device: "
296 << kExynosMfcDevice; 320 << kExynosMfcDevice;
297 NOTIFY_ERROR(PLATFORM_FAILURE); 321 NOTIFY_ERROR(PLATFORM_FAILURE);
298 return false; 322 return false;
299 } 323 }
300 324
301 // Create the interrupt fd. 325 // Create the interrupt fd.
302 DCHECK_EQ(device_poll_interrupt_fd_, -1); 326 DCHECK_EQ(device_poll_interrupt_fd_, -1);
303 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 327 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
Pawel Osciak 2013/12/24 03:45:24 This could be extracted as well I think?
304 if (device_poll_interrupt_fd_ == -1) { 328 if (device_poll_interrupt_fd_ == -1) {
305 DPLOG(ERROR) << "Initialize(): eventfd() failed"; 329 DPLOG(ERROR) << "Initialize(): eventfd() failed";
306 NOTIFY_ERROR(PLATFORM_FAILURE); 330 NOTIFY_ERROR(PLATFORM_FAILURE);
307 return false; 331 return false;
308 } 332 }
309 333
310 // Capabilities check. 334 // Capabilities check.
311 struct v4l2_capability caps; 335 struct v4l2_capability caps;
312 const __u32 kCapsRequired = 336 const __u32 kCapsRequired =
313 V4L2_CAP_VIDEO_CAPTURE_MPLANE | 337 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
314 V4L2_CAP_VIDEO_OUTPUT_MPLANE | 338 V4L2_CAP_VIDEO_OUTPUT_MPLANE |
315 V4L2_CAP_STREAMING; 339 V4L2_CAP_STREAMING;
316 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYCAP, &caps); 340 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QUERYCAP, &caps);
317 if ((caps.capabilities & kCapsRequired) != kCapsRequired) { 341 if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
318 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP" 342 DLOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
319 ", caps check failed: 0x" << std::hex << caps.capabilities; 343 ", caps check failed: 0x" << std::hex << caps.capabilities;
320 NOTIFY_ERROR(PLATFORM_FAILURE); 344 NOTIFY_ERROR(PLATFORM_FAILURE);
321 return false; 345 return false;
322 } 346 }
323 347
324 if (!CreateMfcInputBuffers()) 348 if (!CreateMfcInputBuffers())
325 return false; 349 return false;
326 350
327 // MFC output format has to be setup before streaming starts. 351 // MFC output format has to be setup before streaming starts.
328 struct v4l2_format format; 352 struct v4l2_format format;
329 memset(&format, 0, sizeof(format)); 353 memset(&format, 0, sizeof(format));
330 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 354 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
331 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; 355 format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
332 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format); 356 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_S_FMT, &format);
333 357
334 // Subscribe to the resolution change event. 358 // Subscribe to the resolution change event.
335 struct v4l2_event_subscription sub; 359 struct v4l2_event_subscription sub;
336 memset(&sub, 0, sizeof(sub)); 360 memset(&sub, 0, sizeof(sub));
337 sub.type = V4L2_EVENT_RESOLUTION_CHANGE; 361 sub.type = V4L2_EVENT_RESOLUTION_CHANGE;
338 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub); 362 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_SUBSCRIBE_EVENT, &sub);
339 363
340 // Initialize format-specific bits. 364 // Initialize format-specific bits.
341 if (video_profile_ >= media::H264PROFILE_MIN && 365 if (video_profile_ >= media::H264PROFILE_MIN &&
342 video_profile_ <= media::H264PROFILE_MAX) { 366 video_profile_ <= media::H264PROFILE_MAX) {
343 decoder_h264_parser_.reset(new content::H264Parser()); 367 decoder_h264_parser_.reset(new content::H264Parser());
344 } 368 }
345 369
346 if (!decoder_thread_.Start()) { 370 if (!decoder_thread_.Start()) {
347 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; 371 DLOG(ERROR) << "Initialize(): decoder thread failed to start";
348 NOTIFY_ERROR(PLATFORM_FAILURE); 372 NOTIFY_ERROR(PLATFORM_FAILURE);
349 return false; 373 return false;
350 } 374 }
351 375
352 SetDecoderState(kInitialized); 376 SetDecoderState(kInitialized);
353 377
354 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 378 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
355 &Client::NotifyInitializeDone, client_)); 379 &Client::NotifyInitializeDone, client_));
356 return true; 380 return true;
357 } 381 }
358 382
359 void ExynosVideoDecodeAccelerator::Decode( 383 void V4L2VideoDecodeAccelerator::Decode(
360 const media::BitstreamBuffer& bitstream_buffer) { 384 const media::BitstreamBuffer& bitstream_buffer) {
361 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() 385 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
362 << ", size=" << bitstream_buffer.size(); 386 << ", size=" << bitstream_buffer.size();
363 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 387 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
364 388
365 // DecodeTask() will take care of running a DecodeBufferTask(). 389 // DecodeTask() will take care of running a DecodeBufferTask().
366 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 390 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
367 &ExynosVideoDecodeAccelerator::DecodeTask, base::Unretained(this), 391 &V4L2VideoDecodeAccelerator::DecodeTask, base::Unretained(this),
368 bitstream_buffer)); 392 bitstream_buffer));
369 } 393 }
370 394
371 void ExynosVideoDecodeAccelerator::AssignPictureBuffers( 395 void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
372 const std::vector<media::PictureBuffer>& buffers) { 396 const std::vector<media::PictureBuffer>& buffers) {
373 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size(); 397 DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
374 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 398 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
375 399
376 if (buffers.size() != mfc_output_buffer_map_.size()) { 400 if (buffers.size() != mfc_output_buffer_map_.size()) {
377 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture" 401 DLOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
378 " buffers. (Got " << buffers.size() 402 " buffers. (Got " << buffers.size()
379 << ", requested " << mfc_output_buffer_map_.size() << ")"; 403 << ", requested " << mfc_output_buffer_map_.size() << ")";
380 NOTIFY_ERROR(INVALID_ARGUMENT); 404 NOTIFY_ERROR(INVALID_ARGUMENT);
381 return; 405 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 return; 440 return;
417 } 441 }
418 442
419 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id()); 443 glBindTexture(GL_TEXTURE_EXTERNAL_OES, buffers[i].texture_id());
420 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image); 444 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image);
421 picture_buffers_ref->picture_buffers.push_back( 445 picture_buffers_ref->picture_buffers.push_back(
422 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id())); 446 PictureBufferArrayRef::PictureBufferRef(egl_image, buffers[i].id()));
423 } 447 }
424 decoder_thread_.message_loop()->PostTask( 448 decoder_thread_.message_loop()->PostTask(
425 FROM_HERE, 449 FROM_HERE,
426 base::Bind(&ExynosVideoDecodeAccelerator::AssignPictureBuffersTask, 450 base::Bind(&V4L2VideoDecodeAccelerator::AssignPictureBuffersTask,
427 base::Unretained(this), 451 base::Unretained(this),
428 base::Passed(&picture_buffers_ref))); 452 base::Passed(&picture_buffers_ref)));
429 } 453 }
430 454
431 void ExynosVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { 455 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) {
432 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id; 456 DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id;
433 // Must be run on child thread, as we'll insert a sync in the EGL context. 457 // Must be run on child thread, as we'll insert a sync in the EGL context.
434 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 458 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
435 459
436 if (!make_context_current_.Run()) { 460 if (!make_context_current_.Run()) {
437 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current"; 461 DLOG(ERROR) << "ReusePictureBuffer(): could not make context current";
438 NOTIFY_ERROR(PLATFORM_FAILURE); 462 NOTIFY_ERROR(PLATFORM_FAILURE);
439 return; 463 return;
440 } 464 }
441 465
442 EGLSyncKHR egl_sync = 466 EGLSyncKHR egl_sync =
443 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL); 467 eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
444 if (egl_sync == EGL_NO_SYNC_KHR) { 468 if (egl_sync == EGL_NO_SYNC_KHR) {
445 DLOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed"; 469 DLOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed";
446 NOTIFY_ERROR(PLATFORM_FAILURE); 470 NOTIFY_ERROR(PLATFORM_FAILURE);
447 return; 471 return;
448 } 472 }
449 473
450 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef( 474 scoped_ptr<EGLSyncKHRRef> egl_sync_ref(new EGLSyncKHRRef(
451 egl_display_, egl_sync)); 475 egl_display_, egl_sync));
452 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 476 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
453 &ExynosVideoDecodeAccelerator::ReusePictureBufferTask, 477 &V4L2VideoDecodeAccelerator::ReusePictureBufferTask,
454 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref))); 478 base::Unretained(this), picture_buffer_id, base::Passed(&egl_sync_ref)));
455 } 479 }
456 480
457 void ExynosVideoDecodeAccelerator::Flush() { 481 void V4L2VideoDecodeAccelerator::Flush() {
458 DVLOG(3) << "Flush()"; 482 DVLOG(3) << "Flush()";
459 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 483 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
460 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 484 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
461 &ExynosVideoDecodeAccelerator::FlushTask, base::Unretained(this))); 485 &V4L2VideoDecodeAccelerator::FlushTask, base::Unretained(this)));
462 } 486 }
463 487
464 void ExynosVideoDecodeAccelerator::Reset() { 488 void V4L2VideoDecodeAccelerator::Reset() {
465 DVLOG(3) << "Reset()"; 489 DVLOG(3) << "Reset()";
466 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 490 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
467 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 491 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
468 &ExynosVideoDecodeAccelerator::ResetTask, base::Unretained(this))); 492 &V4L2VideoDecodeAccelerator::ResetTask, base::Unretained(this)));
469 } 493 }
470 494
471 void ExynosVideoDecodeAccelerator::Destroy() { 495 void V4L2VideoDecodeAccelerator::Destroy() {
472 DVLOG(3) << "Destroy()"; 496 DVLOG(3) << "Destroy()";
473 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 497 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
474 498
475 // We're destroying; cancel all callbacks. 499 // We're destroying; cancel all callbacks.
476 client_ptr_factory_.InvalidateWeakPtrs(); 500 client_ptr_factory_.InvalidateWeakPtrs();
477 501
478 // If the decoder thread is running, destroy using posted task. 502 // If the decoder thread is running, destroy using posted task.
479 if (decoder_thread_.IsRunning()) { 503 if (decoder_thread_.IsRunning()) {
480 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 504 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
481 &ExynosVideoDecodeAccelerator::DestroyTask, base::Unretained(this))); 505 &V4L2VideoDecodeAccelerator::DestroyTask, base::Unretained(this)));
482 // DestroyTask() will cause the decoder_thread_ to flush all tasks. 506 // DestroyTask() will cause the decoder_thread_ to flush all tasks.
483 decoder_thread_.Stop(); 507 decoder_thread_.Stop();
484 } else { 508 } else {
485 // Otherwise, call the destroy task directly. 509 // Otherwise, call the destroy task directly.
486 DestroyTask(); 510 DestroyTask();
487 } 511 }
488 512
489 // Set to kError state just in case. 513 // Set to kError state just in case.
490 SetDecoderState(kError); 514 SetDecoderState(kError);
491 515
492 delete this; 516 delete this;
493 } 517 }
494 518
495 bool ExynosVideoDecodeAccelerator::CanDecodeOnIOThread() { return true; } 519 bool V4L2VideoDecodeAccelerator::CanDecodeOnIOThread() { return true; }
496 520
497 void ExynosVideoDecodeAccelerator::DecodeTask( 521 void V4L2VideoDecodeAccelerator::DecodeTask(
498 const media::BitstreamBuffer& bitstream_buffer) { 522 const media::BitstreamBuffer& bitstream_buffer) {
499 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id(); 523 DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
500 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 524 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
501 DCHECK_NE(decoder_state_, kUninitialized); 525 DCHECK_NE(decoder_state_, kUninitialized);
502 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id", 526 TRACE_EVENT1("Video Decoder", "EVDA::DecodeTask", "input_id",
503 bitstream_buffer.id()); 527 bitstream_buffer.id());
504 528
505 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef( 529 scoped_ptr<BitstreamBufferRef> bitstream_record(new BitstreamBufferRef(
506 io_client_, io_message_loop_proxy_, 530 io_client_, io_message_loop_proxy_,
507 new base::SharedMemory(bitstream_buffer.handle(), true), 531 new base::SharedMemory(bitstream_buffer.handle(), true),
(...skipping 17 matching lines...) Expand all
525 DVLOG(2) << "DecodeTask(): early out: kError state"; 549 DVLOG(2) << "DecodeTask(): early out: kError state";
526 return; 550 return;
527 } 551 }
528 552
529 decoder_input_queue_.push( 553 decoder_input_queue_.push(
530 linked_ptr<BitstreamBufferRef>(bitstream_record.release())); 554 linked_ptr<BitstreamBufferRef>(bitstream_record.release()));
531 decoder_decode_buffer_tasks_scheduled_++; 555 decoder_decode_buffer_tasks_scheduled_++;
532 DecodeBufferTask(); 556 DecodeBufferTask();
533 } 557 }
534 558
535 void ExynosVideoDecodeAccelerator::DecodeBufferTask() { 559 void V4L2VideoDecodeAccelerator::DecodeBufferTask() {
536 DVLOG(3) << "DecodeBufferTask()"; 560 DVLOG(3) << "DecodeBufferTask()";
537 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 561 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
538 DCHECK_NE(decoder_state_, kUninitialized); 562 DCHECK_NE(decoder_state_, kUninitialized);
539 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask"); 563 TRACE_EVENT0("Video Decoder", "EVDA::DecodeBufferTask");
540 564
541 decoder_decode_buffer_tasks_scheduled_--; 565 decoder_decode_buffer_tasks_scheduled_--;
542 566
543 if (decoder_state_ == kResetting) { 567 if (decoder_state_ == kResetting) {
544 DVLOG(2) << "DecodeBufferTask(): early out: kResetting state"; 568 DVLOG(2) << "DecodeBufferTask(): early out: kResetting state";
545 return; 569 return;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 // Our current bitstream buffer is done; return it. 670 // Our current bitstream buffer is done; return it.
647 int32 input_id = decoder_current_bitstream_buffer_->input_id; 671 int32 input_id = decoder_current_bitstream_buffer_->input_id;
648 DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id; 672 DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id;
649 // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer(). 673 // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer().
650 decoder_current_bitstream_buffer_.reset(); 674 decoder_current_bitstream_buffer_.reset();
651 } 675 }
652 ScheduleDecodeBufferTaskIfNeeded(); 676 ScheduleDecodeBufferTaskIfNeeded();
653 } 677 }
654 } 678 }
655 679
656 bool ExynosVideoDecodeAccelerator::AdvanceFrameFragment( 680 bool V4L2VideoDecodeAccelerator::AdvanceFrameFragment(
657 const uint8* data, 681 const uint8* data,
658 size_t size, 682 size_t size,
659 size_t* endpos) { 683 size_t* endpos) {
660 if (video_profile_ >= media::H264PROFILE_MIN && 684 if (video_profile_ >= media::H264PROFILE_MIN &&
661 video_profile_ <= media::H264PROFILE_MAX) { 685 video_profile_ <= media::H264PROFILE_MAX) {
662 // For H264, we need to feed HW one frame at a time. This is going to take 686 // For H264, we need to feed HW one frame at a time. This is going to take
663 // some parsing of our input stream. 687 // some parsing of our input stream.
664 decoder_h264_parser_->SetStream(data, size); 688 decoder_h264_parser_->SetStream(data, size);
665 content::H264NALU nalu; 689 content::H264NALU nalu;
666 content::H264Parser::Result result; 690 content::H264Parser::Result result;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 DCHECK_GE(video_profile_, media::VP8PROFILE_MIN); 750 DCHECK_GE(video_profile_, media::VP8PROFILE_MIN);
727 DCHECK_LE(video_profile_, media::VP8PROFILE_MAX); 751 DCHECK_LE(video_profile_, media::VP8PROFILE_MAX);
728 // For VP8, we can just dump the entire buffer. No fragmentation needed, 752 // For VP8, we can just dump the entire buffer. No fragmentation needed,
729 // and we never return a partial frame. 753 // and we never return a partial frame.
730 *endpos = size; 754 *endpos = size;
731 decoder_partial_frame_pending_ = false; 755 decoder_partial_frame_pending_ = false;
732 return true; 756 return true;
733 } 757 }
734 } 758 }
735 759
736 void ExynosVideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() { 760 void V4L2VideoDecodeAccelerator::ScheduleDecodeBufferTaskIfNeeded() {
737 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 761 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
738 762
739 // If we're behind on tasks, schedule another one. 763 // If we're behind on tasks, schedule another one.
740 int buffers_to_decode = decoder_input_queue_.size(); 764 int buffers_to_decode = decoder_input_queue_.size();
741 if (decoder_current_bitstream_buffer_ != NULL) 765 if (decoder_current_bitstream_buffer_ != NULL)
742 buffers_to_decode++; 766 buffers_to_decode++;
743 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) { 767 if (decoder_decode_buffer_tasks_scheduled_ < buffers_to_decode) {
744 decoder_decode_buffer_tasks_scheduled_++; 768 decoder_decode_buffer_tasks_scheduled_++;
745 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 769 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
746 &ExynosVideoDecodeAccelerator::DecodeBufferTask, 770 &V4L2VideoDecodeAccelerator::DecodeBufferTask,
747 base::Unretained(this))); 771 base::Unretained(this)));
748 } 772 }
749 } 773 }
750 774
751 bool ExynosVideoDecodeAccelerator::DecodeBufferInitial( 775 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(
752 const void* data, size_t size, size_t* endpos) { 776 const void* data, size_t size, size_t* endpos) {
753 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; 777 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size;
754 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 778 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
755 DCHECK_NE(decoder_state_, kUninitialized); 779 DCHECK_NE(decoder_state_, kUninitialized);
756 DCHECK_NE(decoder_state_, kDecoding); 780 DCHECK_NE(decoder_state_, kDecoding);
757 DCHECK(!device_poll_thread_.IsRunning()); 781 DCHECK(!device_poll_thread_.IsRunning());
758 // Initial decode. We haven't been able to get output stream format info yet. 782 // Initial decode. We haven't been able to get output stream format info yet.
759 // Get it, and start decoding. 783 // Get it, and start decoding.
760 784
761 // Copy in and send to HW. 785 // Copy in and send to HW.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 826
803 // StartDevicePoll will raise the error if there is one. 827 // StartDevicePoll will raise the error if there is one.
804 if (!StartDevicePoll()) 828 if (!StartDevicePoll())
805 return false; 829 return false;
806 830
807 decoder_state_ = kDecoding; 831 decoder_state_ = kDecoding;
808 ScheduleDecodeBufferTaskIfNeeded(); 832 ScheduleDecodeBufferTaskIfNeeded();
809 return true; 833 return true;
810 } 834 }
811 835
812 bool ExynosVideoDecodeAccelerator::DecodeBufferContinue( 836 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue(
813 const void* data, size_t size) { 837 const void* data, size_t size) {
814 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; 838 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size;
815 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 839 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
816 DCHECK_EQ(decoder_state_, kDecoding); 840 DCHECK_EQ(decoder_state_, kDecoding);
817 841
818 // Both of these calls will set kError state if they fail. 842 // Both of these calls will set kError state if they fail.
819 // Only flush the frame if it's complete. 843 // Only flush the frame if it's complete.
820 return (AppendToInputFrame(data, size) && 844 return (AppendToInputFrame(data, size) &&
821 (decoder_partial_frame_pending_ || FlushInputFrame())); 845 (decoder_partial_frame_pending_ || FlushInputFrame()));
822 } 846 }
823 847
824 bool ExynosVideoDecodeAccelerator::AppendToInputFrame( 848 bool V4L2VideoDecodeAccelerator::AppendToInputFrame(
825 const void* data, size_t size) { 849 const void* data, size_t size) {
826 DVLOG(3) << "AppendToInputFrame()"; 850 DVLOG(3) << "AppendToInputFrame()";
827 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 851 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
828 DCHECK_NE(decoder_state_, kUninitialized); 852 DCHECK_NE(decoder_state_, kUninitialized);
829 DCHECK_NE(decoder_state_, kResetting); 853 DCHECK_NE(decoder_state_, kResetting);
830 DCHECK_NE(decoder_state_, kError); 854 DCHECK_NE(decoder_state_, kError);
831 // This routine can handle data == NULL and size == 0, which occurs when 855 // This routine can handle data == NULL and size == 0, which occurs when
832 // we queue an empty buffer for the purposes of flushing the pipe. 856 // we queue an empty buffer for the purposes of flushing the pipe.
833 857
834 // Flush if we're too big 858 // Flush if we're too big
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 } 905 }
882 memcpy( 906 memcpy(
883 reinterpret_cast<uint8*>(input_record.address) + input_record.bytes_used, 907 reinterpret_cast<uint8*>(input_record.address) + input_record.bytes_used,
884 data, 908 data,
885 size); 909 size);
886 input_record.bytes_used += size; 910 input_record.bytes_used += size;
887 911
888 return true; 912 return true;
889 } 913 }
890 914
891 bool ExynosVideoDecodeAccelerator::FlushInputFrame() { 915 bool V4L2VideoDecodeAccelerator::FlushInputFrame() {
892 DVLOG(3) << "FlushInputFrame()"; 916 DVLOG(3) << "FlushInputFrame()";
893 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 917 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
894 DCHECK_NE(decoder_state_, kUninitialized); 918 DCHECK_NE(decoder_state_, kUninitialized);
895 DCHECK_NE(decoder_state_, kResetting); 919 DCHECK_NE(decoder_state_, kResetting);
896 DCHECK_NE(decoder_state_, kError); 920 DCHECK_NE(decoder_state_, kError);
897 921
898 if (decoder_current_input_buffer_ == -1) 922 if (decoder_current_input_buffer_ == -1)
899 return true; 923 return true;
900 924
901 MfcInputRecord& input_record = 925 MfcInputRecord& input_record =
(...skipping 17 matching lines...) Expand all
919 mfc_input_ready_queue_.push(decoder_current_input_buffer_); 943 mfc_input_ready_queue_.push(decoder_current_input_buffer_);
920 decoder_current_input_buffer_ = -1; 944 decoder_current_input_buffer_ = -1;
921 DVLOG(3) << "FlushInputFrame(): submitting input_id=" 945 DVLOG(3) << "FlushInputFrame(): submitting input_id="
922 << input_record.input_id; 946 << input_record.input_id;
923 // Kick the MFC once since there's new available input for it. 947 // Kick the MFC once since there's new available input for it.
924 EnqueueMfc(); 948 EnqueueMfc();
925 949
926 return (decoder_state_ != kError); 950 return (decoder_state_ != kError);
927 } 951 }
928 952
929 void ExynosVideoDecodeAccelerator::AssignPictureBuffersTask( 953 void V4L2VideoDecodeAccelerator::AssignPictureBuffersTask(
930 scoped_ptr<PictureBufferArrayRef> pic_buffers) { 954 scoped_ptr<PictureBufferArrayRef> pic_buffers) {
931 DVLOG(3) << "AssignPictureBuffersTask()"; 955 DVLOG(3) << "AssignPictureBuffersTask()";
932 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 956 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
933 DCHECK_NE(decoder_state_, kUninitialized); 957 DCHECK_NE(decoder_state_, kUninitialized);
934 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask"); 958 TRACE_EVENT0("Video Decoder", "EVDA::AssignPictureBuffersTask");
935 959
936 // We run AssignPictureBuffersTask even if we're in kResetting. 960 // We run AssignPictureBuffersTask even if we're in kResetting.
937 if (decoder_state_ == kError) { 961 if (decoder_state_ == kError) {
938 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state"; 962 DVLOG(2) << "AssignPictureBuffersTask(): early out: kError state";
939 return; 963 return;
(...skipping 19 matching lines...) Expand all
959 } 983 }
960 pic_buffers->picture_buffers.clear(); 984 pic_buffers->picture_buffers.clear();
961 985
962 // We got buffers! Kick the MFC. 986 // We got buffers! Kick the MFC.
963 EnqueueMfc(); 987 EnqueueMfc();
964 988
965 if (decoder_state_ == kChangingResolution) 989 if (decoder_state_ == kChangingResolution)
966 ResumeAfterResolutionChange(); 990 ResumeAfterResolutionChange();
967 } 991 }
968 992
969 void ExynosVideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) { 993 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool mfc_event_pending) {
970 DVLOG(3) << "ServiceDeviceTask()"; 994 DVLOG(3) << "ServiceDeviceTask()";
971 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 995 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
972 DCHECK_NE(decoder_state_, kUninitialized); 996 DCHECK_NE(decoder_state_, kUninitialized);
973 DCHECK_NE(decoder_state_, kInitialized); 997 DCHECK_NE(decoder_state_, kInitialized);
974 DCHECK_NE(decoder_state_, kAfterReset); 998 DCHECK_NE(decoder_state_, kAfterReset);
975 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask"); 999 TRACE_EVENT0("Video Decoder", "EVDA::ServiceDeviceTask");
976 1000
977 if (decoder_state_ == kResetting) { 1001 if (decoder_state_ == kResetting) {
978 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; 1002 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state";
979 return; 1003 return;
980 } else if (decoder_state_ == kError) { 1004 } else if (decoder_state_ == kError) {
981 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; 1005 DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
982 return; 1006 return;
983 } else if (decoder_state_ == kChangingResolution) { 1007 } else if (decoder_state_ == kChangingResolution) {
984 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; 1008 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state";
985 return; 1009 return;
986 } 1010 }
987 1011
988 if (mfc_event_pending) 1012 if (mfc_event_pending)
989 DequeueMfcEvents(); 1013 DequeueMfcEvents();
990 DequeueMfc(); 1014 DequeueMfc();
991 EnqueueMfc(); 1015 EnqueueMfc();
992 1016
993 // Clear the interrupt fd. 1017 // Clear the interrupt fd.
994 if (!ClearDevicePollInterrupt()) 1018 if (!device->ClearDevicePollInterrupt(device_poll_interrupt_fd_)) {
1019 NOTIFY_ERROR(PLATFORM_FAILURE);
995 return; 1020 return;
1021 }
996 1022
997 unsigned int poll_fds = 0; 1023 unsigned int poll_fds = 0;
998 // Add MFC fd, if we should poll on it. 1024 // Add MFC fd, if we should poll on it.
999 // MFC can be polled as soon as either input or output buffers are queued. 1025 // MFC can be polled as soon as either input or output buffers are queued.
1000 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0) 1026 if (mfc_input_buffer_queued_count_ + mfc_output_buffer_queued_count_ > 0)
1001 poll_fds |= kPollMfc; 1027 poll_fds |= kPollMfc;
1002 1028
1003 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(), 1029 // ServiceDeviceTask() should only ever be scheduled from DevicePollTask(),
1004 // so either: 1030 // so either:
1005 // * device_poll_thread_ is running normally 1031 // * device_poll_thread_ is running normally
1006 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask() 1032 // * device_poll_thread_ scheduled us, but then a ResetTask() or DestroyTask()
1007 // shut it down, in which case we're either in kResetting or kError states 1033 // shut it down, in which case we're either in kResetting or kError states
1008 // respectively, and we should have early-outed already. 1034 // respectively, and we should have early-outed already.
1009 DCHECK(device_poll_thread_.message_loop()); 1035 DCHECK(device_poll_thread_.message_loop());
1010 // Queue the DevicePollTask() now. 1036 // Queue the DevicePollTask() now.
1011 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1037 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1012 &ExynosVideoDecodeAccelerator::DevicePollTask, 1038 &V4L2VideoDecodeAccelerator::DevicePollTask,
1013 base::Unretained(this), 1039 base::Unretained(this),
1014 poll_fds)); 1040 poll_fds));
1015 1041
1016 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC[" 1042 DVLOG(1) << "ServiceDeviceTask(): buffer counts: DEC["
1017 << decoder_input_queue_.size() << "->" 1043 << decoder_input_queue_.size() << "->"
1018 << mfc_input_ready_queue_.size() << "] => MFC[" 1044 << mfc_input_ready_queue_.size() << "] => MFC["
1019 << mfc_free_input_buffers_.size() << "+" 1045 << mfc_free_input_buffers_.size() << "+"
1020 << mfc_input_buffer_queued_count_ << "/" 1046 << mfc_input_buffer_queued_count_ << "/"
1021 << mfc_input_buffer_map_.size() << "->" 1047 << mfc_input_buffer_map_.size() << "->"
1022 << mfc_free_output_buffers_.size() << "+" 1048 << mfc_free_output_buffers_.size() << "+"
1023 << mfc_output_buffer_queued_count_ << "/" 1049 << mfc_output_buffer_queued_count_ << "/"
1024 << mfc_output_buffer_map_.size() << "] => VDA[" 1050 << mfc_output_buffer_map_.size() << "] => VDA["
1025 << decoder_frames_at_client_ << "]"; 1051 << decoder_frames_at_client_ << "]";
1026 1052
1027 ScheduleDecodeBufferTaskIfNeeded(); 1053 ScheduleDecodeBufferTaskIfNeeded();
1028 StartResolutionChangeIfNeeded(); 1054 StartResolutionChangeIfNeeded();
1029 } 1055 }
1030 1056
1031 void ExynosVideoDecodeAccelerator::EnqueueMfc() { 1057 void V4L2VideoDecodeAccelerator::EnqueueMfc() {
1032 DVLOG(3) << "EnqueueMfc()"; 1058 DVLOG(3) << "EnqueueMfc()";
1033 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1059 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1034 DCHECK_NE(decoder_state_, kUninitialized); 1060 DCHECK_NE(decoder_state_, kUninitialized);
1035 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc"); 1061 TRACE_EVENT0("Video Decoder", "EVDA::EnqueueMfc");
1036 1062
1037 // Drain the pipe of completed decode buffers. 1063 // Drain the pipe of completed decode buffers.
1038 const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_; 1064 const int old_mfc_inputs_queued = mfc_input_buffer_queued_count_;
1039 while (!mfc_input_ready_queue_.empty()) { 1065 while (!mfc_input_ready_queue_.empty()) {
1040 if (!EnqueueMfcInputRecord()) 1066 if (!EnqueueMfcInputRecord())
1041 return; 1067 return;
1042 } 1068 }
1043 if (old_mfc_inputs_queued == 0 && mfc_input_buffer_queued_count_ != 0) { 1069 if (old_mfc_inputs_queued == 0 && mfc_input_buffer_queued_count_ != 0) {
1044 // We just started up a previously empty queue. 1070 // We just started up a previously empty queue.
1045 // Queue state changed; signal interrupt. 1071 // Queue state changed; signal interrupt.
1046 if (!SetDevicePollInterrupt()) 1072 if (!device->SetDevicePollInterrupt(device_poll_interrupt_fd_)) {
1073 NOTIFY_ERROR(PLATFORM_FAILURE);
1047 return; 1074 return;
1075 }
1048 // Start VIDIOC_STREAMON if we haven't yet. 1076 // Start VIDIOC_STREAMON if we haven't yet.
1049 if (!mfc_input_streamon_) { 1077 if (!mfc_input_streamon_) {
1050 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1078 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1051 IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type); 1079 IOCTL_OR_ERROR_RETURN(videodec_fd_, VIDIOC_STREAMON, &type);
1052 mfc_input_streamon_ = true; 1080 mfc_input_streamon_ = true;
1053 } 1081 }
1054 } 1082 }
1055 1083
1056 // Enqueue all the MFC outputs we can. 1084 // Enqueue all the MFC outputs we can.
1057 const int old_mfc_outputs_queued = mfc_output_buffer_queued_count_; 1085 const int old_mfc_outputs_queued = mfc_output_buffer_queued_count_;
1058 while (!mfc_free_output_buffers_.empty()) { 1086 while (!mfc_free_output_buffers_.empty()) {
1059 if (!EnqueueMfcOutputRecord()) 1087 if (!EnqueueMfcOutputRecord())
1060 return; 1088 return;
1061 } 1089 }
1062 if (old_mfc_outputs_queued == 0 && mfc_output_buffer_queued_count_ != 0) { 1090 if (old_mfc_outputs_queued == 0 && mfc_output_buffer_queued_count_ != 0) {
1063 // We just started up a previously empty queue. 1091 // We just started up a previously empty queue.
1064 // Queue state changed; signal interrupt. 1092 // Queue state changed; signal interrupt.
1065 if (!SetDevicePollInterrupt()) 1093 if (!device->SetDevicePollInterrupt(device_poll_interrupt_fd_)) {
1094 NOTIFY_ERROR(PLATFORM_FAILURE);
1066 return; 1095 return;
1096 }
1067 // Start VIDIOC_STREAMON if we haven't yet. 1097 // Start VIDIOC_STREAMON if we haven't yet.
1068 if (!mfc_output_streamon_) { 1098 if (!mfc_output_streamon_) {
1069 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1099 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1070 IOCTL_OR_ERROR_RETURN(mfc_fd_, VIDIOC_STREAMON, &type); 1100 IOCTL_OR_ERROR_RETURN(videodec_fd_, VIDIOC_STREAMON, &type);
1071 mfc_output_streamon_ = true; 1101 mfc_output_streamon_ = true;
1072 } 1102 }
1073 } 1103 }
1074 } 1104 }
1075 1105
1076 void ExynosVideoDecodeAccelerator::DequeueMfcEvents() { 1106 void V4L2VideoDecodeAccelerator::DequeueMfcEvents() {
1077 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1107 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1078 DCHECK_NE(decoder_state_, kUninitialized); 1108 DCHECK_NE(decoder_state_, kUninitialized);
1079 DVLOG(3) << "DequeueMfcEvents()"; 1109 DVLOG(3) << "DequeueMfcEvents()";
1080 1110
1081 struct v4l2_event ev; 1111 struct v4l2_event ev;
1082 memset(&ev, 0, sizeof(ev)); 1112 memset(&ev, 0, sizeof(ev));
1083 1113
1084 while (ioctl(mfc_fd_, VIDIOC_DQEVENT, &ev) == 0) { 1114 while (device->dev_ioctl(videodec_fd_, VIDIOC_DQEVENT, &ev) == 0) {
1085 if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) { 1115 if (ev.type == V4L2_EVENT_RESOLUTION_CHANGE) {
1086 DVLOG(3) << "DequeueMfcEvents(): got resolution change event."; 1116 DVLOG(3) << "DequeueMfcEvents(): got resolution change event.";
1087 DCHECK(!resolution_change_pending_); 1117 DCHECK(!resolution_change_pending_);
1088 resolution_change_pending_ = true; 1118 resolution_change_pending_ = true;
1089 } else { 1119 } else {
1090 DLOG(FATAL) << "DequeueMfcEvents(): got an event (" << ev.type 1120 DLOG(FATAL) << "DequeueMfcEvents(): got an event (" << ev.type
1091 << ") we haven't subscribed to."; 1121 << ") we haven't subscribed to.";
1092 } 1122 }
1093 } 1123 }
1094 } 1124 }
1095 1125
1096 void ExynosVideoDecodeAccelerator::DequeueMfc() { 1126 void V4L2VideoDecodeAccelerator::DequeueMfc() {
1097 DVLOG(3) << "DequeueMfc()"; 1127 DVLOG(3) << "DequeueMfc()";
1098 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1128 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1099 DCHECK_NE(decoder_state_, kUninitialized); 1129 DCHECK_NE(decoder_state_, kUninitialized);
1100 TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc"); 1130 TRACE_EVENT0("Video Decoder", "EVDA::DequeueMfc");
1101 1131
1102 // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free 1132 // Dequeue completed MFC input (VIDEO_OUTPUT) buffers, and recycle to the free
1103 // list. 1133 // list.
1104 struct v4l2_buffer dqbuf; 1134 struct v4l2_buffer dqbuf;
1105 struct v4l2_plane planes[2]; 1135 struct v4l2_plane planes[2];
1106 while (mfc_input_buffer_queued_count_ > 0) { 1136 while (mfc_input_buffer_queued_count_ > 0) {
1107 DCHECK(mfc_input_streamon_); 1137 DCHECK(mfc_input_streamon_);
1108 memset(&dqbuf, 0, sizeof(dqbuf)); 1138 memset(&dqbuf, 0, sizeof(dqbuf));
1109 memset(planes, 0, sizeof(planes)); 1139 memset(planes, 0, sizeof(planes));
1110 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1140 dqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1111 dqbuf.memory = V4L2_MEMORY_MMAP; 1141 dqbuf.memory = V4L2_MEMORY_MMAP;
1112 dqbuf.m.planes = planes; 1142 dqbuf.m.planes = planes;
1113 dqbuf.length = 1; 1143 dqbuf.length = 1;
1114 if (ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) { 1144 if (device->dev_ioctl(videodec_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1115 if (errno == EAGAIN) { 1145 if (errno == EAGAIN) {
1116 // EAGAIN if we're just out of buffers to dequeue. 1146 // EAGAIN if we're just out of buffers to dequeue.
1117 break; 1147 break;
1118 } 1148 }
1119 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; 1149 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
1120 NOTIFY_ERROR(PLATFORM_FAILURE); 1150 NOTIFY_ERROR(PLATFORM_FAILURE);
1121 return; 1151 return;
1122 } 1152 }
1123 MfcInputRecord& input_record = mfc_input_buffer_map_[dqbuf.index]; 1153 MfcInputRecord& input_record = mfc_input_buffer_map_[dqbuf.index];
1124 DCHECK(input_record.at_device); 1154 DCHECK(input_record.at_device);
1125 mfc_free_input_buffers_.push_back(dqbuf.index); 1155 mfc_free_input_buffers_.push_back(dqbuf.index);
1126 input_record.at_device = false; 1156 input_record.at_device = false;
1127 input_record.bytes_used = 0; 1157 input_record.bytes_used = 0;
1128 input_record.input_id = -1; 1158 input_record.input_id = -1;
1129 mfc_input_buffer_queued_count_--; 1159 mfc_input_buffer_queued_count_--;
1130 } 1160 }
1131 1161
1132 // Dequeue completed MFC output (VIDEO_CAPTURE) buffers, and queue to the 1162 // Dequeue completed MFC output (VIDEO_CAPTURE) buffers, and queue to the
1133 // completed queue. 1163 // completed queue.
1134 while (mfc_output_buffer_queued_count_ > 0) { 1164 while (mfc_output_buffer_queued_count_ > 0) {
1135 DCHECK(mfc_output_streamon_); 1165 DCHECK(mfc_output_streamon_);
1136 memset(&dqbuf, 0, sizeof(dqbuf)); 1166 memset(&dqbuf, 0, sizeof(dqbuf));
1137 memset(planes, 0, sizeof(planes)); 1167 memset(planes, 0, sizeof(planes));
1138 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1168 dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1139 dqbuf.memory = V4L2_MEMORY_MMAP; 1169 dqbuf.memory = V4L2_MEMORY_MMAP;
1140 dqbuf.m.planes = planes; 1170 dqbuf.m.planes = planes;
1141 dqbuf.length = 2; 1171 dqbuf.length = 2;
1142 if (ioctl(mfc_fd_, VIDIOC_DQBUF, &dqbuf) != 0) { 1172 if (device->dev_ioctl(videodec_fd_, VIDIOC_DQBUF, &dqbuf) != 0) {
1143 if (errno == EAGAIN) { 1173 if (errno == EAGAIN) {
1144 // EAGAIN if we're just out of buffers to dequeue. 1174 // EAGAIN if we're just out of buffers to dequeue.
1145 break; 1175 break;
1146 } 1176 }
1147 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF"; 1177 DPLOG(ERROR) << "DequeueMfc(): ioctl() failed: VIDIOC_DQBUF";
1148 NOTIFY_ERROR(PLATFORM_FAILURE); 1178 NOTIFY_ERROR(PLATFORM_FAILURE);
1149 return; 1179 return;
1150 } 1180 }
1151 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index]; 1181 MfcOutputRecord& output_record = mfc_output_buffer_map_[dqbuf.index];
1152 DCHECK(output_record.at_device); 1182 DCHECK(output_record.at_device);
(...skipping 16 matching lines...) Expand all
1169 SendPictureReady(); 1199 SendPictureReady();
1170 output_record.cleared = true; 1200 output_record.cleared = true;
1171 decoder_frames_at_client_++; 1201 decoder_frames_at_client_++;
1172 } 1202 }
1173 mfc_output_buffer_queued_count_--; 1203 mfc_output_buffer_queued_count_--;
1174 } 1204 }
1175 1205
1176 NotifyFlushDoneIfNeeded(); 1206 NotifyFlushDoneIfNeeded();
1177 } 1207 }
1178 1208
1179 bool ExynosVideoDecodeAccelerator::EnqueueMfcInputRecord() { 1209 bool V4L2VideoDecodeAccelerator::EnqueueMfcInputRecord() {
1180 DVLOG(3) << "EnqueueMfcInputRecord()"; 1210 DVLOG(3) << "EnqueueMfcInputRecord()";
1181 DCHECK(!mfc_input_ready_queue_.empty()); 1211 DCHECK(!mfc_input_ready_queue_.empty());
1182 1212
1183 // Enqueue a MFC input (VIDEO_OUTPUT) buffer. 1213 // Enqueue a MFC input (VIDEO_OUTPUT) buffer.
1184 const int buffer = mfc_input_ready_queue_.front(); 1214 const int buffer = mfc_input_ready_queue_.front();
1185 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer]; 1215 MfcInputRecord& input_record = mfc_input_buffer_map_[buffer];
1186 DCHECK(!input_record.at_device); 1216 DCHECK(!input_record.at_device);
1187 struct v4l2_buffer qbuf; 1217 struct v4l2_buffer qbuf;
1188 struct v4l2_plane qbuf_plane; 1218 struct v4l2_plane qbuf_plane;
1189 memset(&qbuf, 0, sizeof(qbuf)); 1219 memset(&qbuf, 0, sizeof(qbuf));
1190 memset(&qbuf_plane, 0, sizeof(qbuf_plane)); 1220 memset(&qbuf_plane, 0, sizeof(qbuf_plane));
1191 qbuf.index = buffer; 1221 qbuf.index = buffer;
1192 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1222 qbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1193 qbuf.timestamp.tv_sec = input_record.input_id; 1223 qbuf.timestamp.tv_sec = input_record.input_id;
1194 qbuf.memory = V4L2_MEMORY_MMAP; 1224 qbuf.memory = V4L2_MEMORY_MMAP;
1195 qbuf.m.planes = &qbuf_plane; 1225 qbuf.m.planes = &qbuf_plane;
1196 qbuf.m.planes[0].bytesused = input_record.bytes_used; 1226 qbuf.m.planes[0].bytesused = input_record.bytes_used;
1197 qbuf.length = 1; 1227 qbuf.length = 1;
1198 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf); 1228 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QBUF, &qbuf);
1199 mfc_input_ready_queue_.pop(); 1229 mfc_input_ready_queue_.pop();
1200 input_record.at_device = true; 1230 input_record.at_device = true;
1201 mfc_input_buffer_queued_count_++; 1231 mfc_input_buffer_queued_count_++;
1202 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id=" 1232 DVLOG(3) << "EnqueueMfcInputRecord(): enqueued input_id="
1203 << input_record.input_id; 1233 << input_record.input_id;
1204 return true; 1234 return true;
1205 } 1235 }
1206 1236
1207 bool ExynosVideoDecodeAccelerator::EnqueueMfcOutputRecord() { 1237 bool V4L2VideoDecodeAccelerator::EnqueueMfcOutputRecord() {
1208 DVLOG(3) << "EnqueueMfcOutputRecord()"; 1238 DVLOG(3) << "EnqueueMfcOutputRecord()";
1209 DCHECK(!mfc_free_output_buffers_.empty()); 1239 DCHECK(!mfc_free_output_buffers_.empty());
1210 1240
1211 // Enqueue a MFC output (VIDEO_CAPTURE) buffer. 1241 // Enqueue a MFC output (VIDEO_CAPTURE) buffer.
1212 const int buffer = mfc_free_output_buffers_.front(); 1242 const int buffer = mfc_free_output_buffers_.front();
1213 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer]; 1243 MfcOutputRecord& output_record = mfc_output_buffer_map_[buffer];
1214 DCHECK(!output_record.at_device); 1244 DCHECK(!output_record.at_device);
1215 DCHECK(!output_record.at_client); 1245 DCHECK(!output_record.at_client);
1216 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR); 1246 DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
1217 DCHECK_NE(output_record.picture_id, -1); 1247 DCHECK_NE(output_record.picture_id, -1);
(...skipping 10 matching lines...) Expand all
1228 } 1258 }
1229 struct v4l2_buffer qbuf; 1259 struct v4l2_buffer qbuf;
1230 struct v4l2_plane qbuf_planes[arraysize(output_record.fds)]; 1260 struct v4l2_plane qbuf_planes[arraysize(output_record.fds)];
1231 memset(&qbuf, 0, sizeof(qbuf)); 1261 memset(&qbuf, 0, sizeof(qbuf));
1232 memset(qbuf_planes, 0, sizeof(qbuf_planes)); 1262 memset(qbuf_planes, 0, sizeof(qbuf_planes));
1233 qbuf.index = buffer; 1263 qbuf.index = buffer;
1234 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1264 qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1235 qbuf.memory = V4L2_MEMORY_MMAP; 1265 qbuf.memory = V4L2_MEMORY_MMAP;
1236 qbuf.m.planes = qbuf_planes; 1266 qbuf.m.planes = qbuf_planes;
1237 qbuf.length = arraysize(output_record.fds); 1267 qbuf.length = arraysize(output_record.fds);
1238 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QBUF, &qbuf); 1268 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QBUF, &qbuf);
1239 mfc_free_output_buffers_.pop(); 1269 mfc_free_output_buffers_.pop();
1240 output_record.at_device = true; 1270 output_record.at_device = true;
1241 mfc_output_buffer_queued_count_++; 1271 mfc_output_buffer_queued_count_++;
1242 return true; 1272 return true;
1243 } 1273 }
1244 1274
1245 void ExynosVideoDecodeAccelerator::ReusePictureBufferTask( 1275 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask(
1246 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) { 1276 int32 picture_buffer_id, scoped_ptr<EGLSyncKHRRef> egl_sync_ref) {
1247 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id=" 1277 DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id="
1248 << picture_buffer_id; 1278 << picture_buffer_id;
1249 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1279 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1250 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask"); 1280 TRACE_EVENT0("Video Decoder", "EVDA::ReusePictureBufferTask");
1251 1281
1252 // We run ReusePictureBufferTask even if we're in kResetting. 1282 // We run ReusePictureBufferTask even if we're in kResetting.
1253 if (decoder_state_ == kError) { 1283 if (decoder_state_ == kError) {
1254 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state"; 1284 DVLOG(2) << "ReusePictureBufferTask(): early out: kError state";
1255 return; 1285 return;
(...skipping 26 matching lines...) Expand all
1282 output_record.at_client = false; 1312 output_record.at_client = false;
1283 output_record.egl_sync = egl_sync_ref->egl_sync; 1313 output_record.egl_sync = egl_sync_ref->egl_sync;
1284 mfc_free_output_buffers_.push(index); 1314 mfc_free_output_buffers_.push(index);
1285 decoder_frames_at_client_--; 1315 decoder_frames_at_client_--;
1286 // Take ownership of the EGLSync. 1316 // Take ownership of the EGLSync.
1287 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR; 1317 egl_sync_ref->egl_sync = EGL_NO_SYNC_KHR;
1288 // We got a buffer back, so kick the MFC. 1318 // We got a buffer back, so kick the MFC.
1289 EnqueueMfc(); 1319 EnqueueMfc();
1290 } 1320 }
1291 1321
1292 void ExynosVideoDecodeAccelerator::FlushTask() { 1322 void V4L2VideoDecodeAccelerator::FlushTask() {
1293 DVLOG(3) << "FlushTask()"; 1323 DVLOG(3) << "FlushTask()";
1294 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1324 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1295 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask"); 1325 TRACE_EVENT0("Video Decoder", "EVDA::FlushTask");
1296 1326
1297 // Flush outstanding buffers. 1327 // Flush outstanding buffers.
1298 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) { 1328 if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) {
1299 // There's nothing in the pipe, so return done immediately. 1329 // There's nothing in the pipe, so return done immediately.
1300 DVLOG(3) << "FlushTask(): returning flush"; 1330 DVLOG(3) << "FlushTask(): returning flush";
1301 child_message_loop_proxy_->PostTask( 1331 child_message_loop_proxy_->PostTask(
1302 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); 1332 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1303 return; 1333 return;
1304 } else if (decoder_state_ == kError) { 1334 } else if (decoder_state_ == kError) {
1305 DVLOG(2) << "FlushTask(): early out: kError state"; 1335 DVLOG(2) << "FlushTask(): early out: kError state";
1306 return; 1336 return;
1307 } 1337 }
1308 1338
1309 // We don't support stacked flushing. 1339 // We don't support stacked flushing.
1310 DCHECK(!decoder_flushing_); 1340 DCHECK(!decoder_flushing_);
1311 1341
1312 // Queue up an empty buffer -- this triggers the flush. 1342 // Queue up an empty buffer -- this triggers the flush.
1313 decoder_input_queue_.push( 1343 decoder_input_queue_.push(
1314 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef( 1344 linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
1315 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId))); 1345 io_client_, io_message_loop_proxy_, NULL, 0, kFlushBufferId)));
1316 decoder_flushing_ = true; 1346 decoder_flushing_ = true;
1317 SendPictureReady(); // Send all pending PictureReady. 1347 SendPictureReady(); // Send all pending PictureReady.
1318 1348
1319 ScheduleDecodeBufferTaskIfNeeded(); 1349 ScheduleDecodeBufferTaskIfNeeded();
1320 } 1350 }
1321 1351
1322 void ExynosVideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { 1352 void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
1323 if (!decoder_flushing_) 1353 if (!decoder_flushing_)
1324 return; 1354 return;
1325 1355
1326 // Pipeline is empty when: 1356 // Pipeline is empty when:
1327 // * Decoder input queue is empty of non-delayed buffers. 1357 // * Decoder input queue is empty of non-delayed buffers.
1328 // * There is no currently filling input buffer. 1358 // * There is no currently filling input buffer.
1329 // * MFC input holding queue is empty. 1359 // * MFC input holding queue is empty.
1330 // * All MFC input (VIDEO_OUTPUT) buffers are returned. 1360 // * All MFC input (VIDEO_OUTPUT) buffers are returned.
1331 if (!decoder_input_queue_.empty()) { 1361 if (!decoder_input_queue_.empty()) {
1332 if (decoder_input_queue_.front()->input_id != 1362 if (decoder_input_queue_.front()->input_id !=
(...skipping 23 matching lines...) Expand all
1356 decoder_delay_bitstream_buffer_id_ = -1; 1386 decoder_delay_bitstream_buffer_id_ = -1;
1357 decoder_flushing_ = false; 1387 decoder_flushing_ = false;
1358 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush"; 1388 DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush";
1359 child_message_loop_proxy_->PostTask( 1389 child_message_loop_proxy_->PostTask(
1360 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_)); 1390 FROM_HERE, base::Bind(&Client::NotifyFlushDone, client_));
1361 1391
1362 // While we were flushing, we early-outed DecodeBufferTask()s. 1392 // While we were flushing, we early-outed DecodeBufferTask()s.
1363 ScheduleDecodeBufferTaskIfNeeded(); 1393 ScheduleDecodeBufferTaskIfNeeded();
1364 } 1394 }
1365 1395
1366 void ExynosVideoDecodeAccelerator::ResetTask() { 1396 void V4L2VideoDecodeAccelerator::ResetTask() {
1367 DVLOG(3) << "ResetTask()"; 1397 DVLOG(3) << "ResetTask()";
1368 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1398 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1369 TRACE_EVENT0("Video Decoder", "EVDA::ResetTask"); 1399 TRACE_EVENT0("Video Decoder", "EVDA::ResetTask");
1370 1400
1371 if (decoder_state_ == kError) { 1401 if (decoder_state_ == kError) {
1372 DVLOG(2) << "ResetTask(): early out: kError state"; 1402 DVLOG(2) << "ResetTask(): early out: kError state";
1373 return; 1403 return;
1374 } 1404 }
1375 1405
1376 // If we are in the middle of switching resolutions, postpone reset until 1406 // If we are in the middle of switching resolutions, postpone reset until
(...skipping 20 matching lines...) Expand all
1397 1427
1398 // If we were flushing, we'll never return any more BitstreamBuffers or 1428 // If we were flushing, we'll never return any more BitstreamBuffers or
1399 // PictureBuffers; they have all been dropped and returned by now. 1429 // PictureBuffers; they have all been dropped and returned by now.
1400 NotifyFlushDoneIfNeeded(); 1430 NotifyFlushDoneIfNeeded();
1401 1431
1402 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening 1432 // Mark that we're resetting, then enqueue a ResetDoneTask(). All intervening
1403 // jobs will early-out in the kResetting state. 1433 // jobs will early-out in the kResetting state.
1404 decoder_state_ = kResetting; 1434 decoder_state_ = kResetting;
1405 SendPictureReady(); // Send all pending PictureReady. 1435 SendPictureReady(); // Send all pending PictureReady.
1406 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1436 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1407 &ExynosVideoDecodeAccelerator::ResetDoneTask, base::Unretained(this))); 1437 &V4L2VideoDecodeAccelerator::ResetDoneTask, base::Unretained(this)));
1408 } 1438 }
1409 1439
1410 void ExynosVideoDecodeAccelerator::ResetDoneTask() { 1440 void V4L2VideoDecodeAccelerator::ResetDoneTask() {
1411 DVLOG(3) << "ResetDoneTask()"; 1441 DVLOG(3) << "ResetDoneTask()";
1412 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1442 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1413 TRACE_EVENT0("Video Decoder", "EVDA::ResetDoneTask"); 1443 TRACE_EVENT0("Video Decoder", "EVDA::ResetDoneTask");
1414 1444
1415 if (decoder_state_ == kError) { 1445 if (decoder_state_ == kError) {
1416 DVLOG(2) << "ResetDoneTask(): early out: kError state"; 1446 DVLOG(2) << "ResetDoneTask(): early out: kError state";
1417 return; 1447 return;
1418 } 1448 }
1419 1449
1420 // We might have received a resolution change event while we were waiting 1450 // We might have received a resolution change event while we were waiting
(...skipping 13 matching lines...) Expand all
1434 decoder_state_ = kAfterReset; 1464 decoder_state_ = kAfterReset;
1435 decoder_partial_frame_pending_ = false; 1465 decoder_partial_frame_pending_ = false;
1436 decoder_delay_bitstream_buffer_id_ = -1; 1466 decoder_delay_bitstream_buffer_id_ = -1;
1437 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 1467 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1438 &Client::NotifyResetDone, client_)); 1468 &Client::NotifyResetDone, client_));
1439 1469
1440 // While we were resetting, we early-outed DecodeBufferTask()s. 1470 // While we were resetting, we early-outed DecodeBufferTask()s.
1441 ScheduleDecodeBufferTaskIfNeeded(); 1471 ScheduleDecodeBufferTaskIfNeeded();
1442 } 1472 }
1443 1473
1444 void ExynosVideoDecodeAccelerator::DestroyTask() { 1474 void V4L2VideoDecodeAccelerator::DestroyTask() {
1445 DVLOG(3) << "DestroyTask()"; 1475 DVLOG(3) << "DestroyTask()";
1446 TRACE_EVENT0("Video Decoder", "EVDA::DestroyTask"); 1476 TRACE_EVENT0("Video Decoder", "EVDA::DestroyTask");
1447 1477
1448 // DestroyTask() should run regardless of decoder_state_. 1478 // DestroyTask() should run regardless of decoder_state_.
1449 1479
1450 // Stop streaming and the device_poll_thread_. 1480 // Stop streaming and the device_poll_thread_.
1451 StopDevicePoll(false); 1481 StopDevicePoll(false);
1452 1482
1453 decoder_current_bitstream_buffer_.reset(); 1483 decoder_current_bitstream_buffer_.reset();
1454 decoder_current_input_buffer_ = -1; 1484 decoder_current_input_buffer_ = -1;
1455 decoder_decode_buffer_tasks_scheduled_ = 0; 1485 decoder_decode_buffer_tasks_scheduled_ = 0;
1456 decoder_frames_at_client_ = 0; 1486 decoder_frames_at_client_ = 0;
1457 while (!decoder_input_queue_.empty()) 1487 while (!decoder_input_queue_.empty())
1458 decoder_input_queue_.pop(); 1488 decoder_input_queue_.pop();
1459 decoder_flushing_ = false; 1489 decoder_flushing_ = false;
1460 1490
1461 // Set our state to kError. Just in case. 1491 // Set our state to kError. Just in case.
1462 decoder_state_ = kError; 1492 decoder_state_ = kError;
1463 } 1493 }
1464 1494
1465 bool ExynosVideoDecodeAccelerator::StartDevicePoll() { 1495 bool V4L2VideoDecodeAccelerator::StartDevicePoll() {
1466 DVLOG(3) << "StartDevicePoll()"; 1496 DVLOG(3) << "StartDevicePoll()";
1467 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1497 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1468 DCHECK(!device_poll_thread_.IsRunning()); 1498 DCHECK(!device_poll_thread_.IsRunning());
1469 1499
1470 // Start up the device poll thread and schedule its first DevicePollTask(). 1500 // Start up the device poll thread and schedule its first DevicePollTask().
1471 if (!device_poll_thread_.Start()) { 1501 if (!device_poll_thread_.Start()) {
1472 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; 1502 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
1473 NOTIFY_ERROR(PLATFORM_FAILURE); 1503 NOTIFY_ERROR(PLATFORM_FAILURE);
1474 return false; 1504 return false;
1475 } 1505 }
1476 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1506 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1477 &ExynosVideoDecodeAccelerator::DevicePollTask, 1507 &V4L2VideoDecodeAccelerator::DevicePollTask,
1478 base::Unretained(this), 1508 base::Unretained(this),
1479 0)); 1509 0));
1480 1510
1481 return true; 1511 return true;
1482 } 1512 }
1483 1513
1484 bool ExynosVideoDecodeAccelerator::StopDevicePoll(bool keep_mfc_input_state) { 1514 bool V4L2VideoDecodeAccelerator::StopDevicePoll(bool keep_mfc_input_state) {
1485 DVLOG(3) << "StopDevicePoll()"; 1515 DVLOG(3) << "StopDevicePoll()";
1486 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1516 if (decoder_thread_.IsRunning())
1517 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1487 1518
1488 // Signal the DevicePollTask() to stop, and stop the device poll thread. 1519 // Signal the DevicePollTask() to stop, and stop the device poll thread.
1489 if (!SetDevicePollInterrupt()) 1520 if (!device->SetDevicePollInterrupt(device_poll_interrupt_fd_)) {
1521 NOTIFY_ERROR(PLATFORM_FAILURE);
1490 return false; 1522 return false;
1523 }
1491 device_poll_thread_.Stop(); 1524 device_poll_thread_.Stop();
1492 // Clear the interrupt now, to be sure. 1525 // Clear the interrupt now, to be sure.
1493 if (!ClearDevicePollInterrupt()) 1526 if (!device->ClearDevicePollInterrupt(device_poll_interrupt_fd_)) {
1527 NOTIFY_ERROR(PLATFORM_FAILURE);
1494 return false; 1528 return false;
1529 }
1495 1530
1496 // Stop streaming. 1531 // Stop streaming.
1497 if (!keep_mfc_input_state) { 1532 if (!keep_mfc_input_state) {
1498 if (mfc_input_streamon_) { 1533 if (mfc_input_streamon_) {
1499 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1534 __u32 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1500 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1535 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_STREAMOFF, &type);
1501 } 1536 }
1502 mfc_input_streamon_ = false; 1537 mfc_input_streamon_ = false;
1503 } 1538 }
1504 if (mfc_output_streamon_) { 1539 if (mfc_output_streamon_) {
1505 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1540 __u32 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1506 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_STREAMOFF, &type); 1541 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_STREAMOFF, &type);
1507 } 1542 }
1508 mfc_output_streamon_ = false; 1543 mfc_output_streamon_ = false;
1509 1544
1510 // Reset all our accounting info. 1545 // Reset all our accounting info.
1511 if (!keep_mfc_input_state) { 1546 if (!keep_mfc_input_state) {
1512 while (!mfc_input_ready_queue_.empty()) 1547 while (!mfc_input_ready_queue_.empty())
1513 mfc_input_ready_queue_.pop(); 1548 mfc_input_ready_queue_.pop();
1514 mfc_free_input_buffers_.clear(); 1549 mfc_free_input_buffers_.clear();
1515 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 1550 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1516 mfc_free_input_buffers_.push_back(i); 1551 mfc_free_input_buffers_.push_back(i);
(...skipping 13 matching lines...) Expand all
1530 mfc_free_output_buffers_.push(i); 1565 mfc_free_output_buffers_.push(i);
1531 mfc_output_buffer_map_[i].at_device = false; 1566 mfc_output_buffer_map_[i].at_device = false;
1532 } 1567 }
1533 } 1568 }
1534 mfc_output_buffer_queued_count_ = 0; 1569 mfc_output_buffer_queued_count_ = 0;
1535 1570
1536 DVLOG(3) << "StopDevicePoll(): device poll stopped"; 1571 DVLOG(3) << "StopDevicePoll(): device poll stopped";
1537 return true; 1572 return true;
1538 } 1573 }
1539 1574
1540 bool ExynosVideoDecodeAccelerator::SetDevicePollInterrupt() { 1575 bool V4L2VideoDecodeAccelerator:: ExynosV4L2Device :: SetDevicePollInterrupt(int fd) {
Pawel Osciak 2013/12/24 03:45:24 Please keep methods of one class together (althoug
1541 DVLOG(3) << "SetDevicePollInterrupt()"; 1576 DVLOG(3) << "SetDevicePollInterrupt()";
1542 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1543 1577
1544 const uint64 buf = 1; 1578 const uint64 buf = 1;
1545 if (HANDLE_EINTR(write(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) { 1579 if (HANDLE_EINTR(write(fd, &buf, sizeof(buf))) == -1) {
1546 DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed"; 1580 DPLOG(ERROR) << "SetDevicePollInterrupt(): write() failed";
1547 NOTIFY_ERROR(PLATFORM_FAILURE);
1548 return false; 1581 return false;
1549 } 1582 }
1550 return true; 1583 return true;
1551 } 1584 }
1552 1585
1553 bool ExynosVideoDecodeAccelerator::ClearDevicePollInterrupt() { 1586 bool V4L2VideoDecodeAccelerator:: ExynosV4L2Device :: ClearDevicePollInterrupt(i nt fd) {
1554 DVLOG(3) << "ClearDevicePollInterrupt()"; 1587 DVLOG(3) << "ClearDevicePollInterrupt()";
1555 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1556 1588
1557 uint64 buf; 1589 uint64 buf;
1558 if (HANDLE_EINTR(read(device_poll_interrupt_fd_, &buf, sizeof(buf))) == -1) { 1590 if (HANDLE_EINTR(read(fd, &buf, sizeof(buf))) == -1) {
1559 if (errno == EAGAIN) { 1591 if (errno == EAGAIN) {
1560 // No interrupt flag set, and we're reading nonblocking. Not an error. 1592 // No interrupt flag set, and we're reading nonblocking. Not an error.
1561 return true; 1593 return true;
1562 } else { 1594 } else {
1563 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed"; 1595 DPLOG(ERROR) << "ClearDevicePollInterrupt(): read() failed";
1564 NOTIFY_ERROR(PLATFORM_FAILURE);
1565 return false; 1596 return false;
1566 } 1597 }
1567 } 1598 }
1568 return true; 1599 return true;
1569 } 1600 }
1570 1601
1571 void ExynosVideoDecodeAccelerator::StartResolutionChangeIfNeeded() { 1602 void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() {
1572 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1603 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1573 DCHECK_EQ(decoder_state_, kDecoding); 1604 DCHECK_EQ(decoder_state_, kDecoding);
1574 1605
1575 if (!resolution_change_pending_) 1606 if (!resolution_change_pending_)
1576 return; 1607 return;
1577 1608
1578 DVLOG(3) << "No more work, initiate resolution change"; 1609 DVLOG(3) << "No more work, initiate resolution change";
1579 1610
1580 // Keep MFC input queue. 1611 // Keep MFC input queue.
1581 if (!StopDevicePoll(true)) 1612 if (!StopDevicePoll(true))
1582 return; 1613 return;
1583 1614
1584 decoder_state_ = kChangingResolution; 1615 decoder_state_ = kChangingResolution;
1585 DCHECK(resolution_change_pending_); 1616 DCHECK(resolution_change_pending_);
1586 resolution_change_pending_ = false; 1617 resolution_change_pending_ = false;
1587 1618
1588 // Post a task to clean up buffers on child thread. This will also ensure 1619 // Post a task to clean up buffers on child thread. This will also ensure
1589 // that we won't accept ReusePictureBuffer() anymore after that. 1620 // that we won't accept ReusePictureBuffer() anymore after that.
1590 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 1621 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1591 &ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers, 1622 &V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers,
1592 weak_this_)); 1623 weak_this_));
1593 } 1624 }
1594 1625
1595 void ExynosVideoDecodeAccelerator::FinishResolutionChange() { 1626 void V4L2VideoDecodeAccelerator::FinishResolutionChange() {
1596 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1627 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1597 DVLOG(3) << "FinishResolutionChange()"; 1628 DVLOG(3) << "FinishResolutionChange()";
1598 1629
1599 if (decoder_state_ == kError) { 1630 if (decoder_state_ == kError) {
1600 DVLOG(2) << "FinishResolutionChange(): early out: kError state"; 1631 DVLOG(2) << "FinishResolutionChange(): early out: kError state";
1601 return; 1632 return;
1602 } 1633 }
1603 1634
1604 struct v4l2_format format; 1635 struct v4l2_format format;
1605 bool again; 1636 bool again;
1606 bool ret = GetFormatInfo(&format, &again); 1637 bool ret = GetFormatInfo(&format, &again);
1607 if (!ret || again) { 1638 if (!ret || again) {
1608 DVLOG(3) << "Couldn't get format information after resolution change"; 1639 DVLOG(3) << "Couldn't get format information after resolution change";
1609 NOTIFY_ERROR(PLATFORM_FAILURE); 1640 NOTIFY_ERROR(PLATFORM_FAILURE);
1610 return; 1641 return;
1611 } 1642 }
1612 1643
1613 if (!CreateBuffersForFormat(format)) { 1644 if (!CreateBuffersForFormat(format)) {
1614 DVLOG(3) << "Couldn't reallocate buffers after resolution change"; 1645 DVLOG(3) << "Couldn't reallocate buffers after resolution change";
1615 NOTIFY_ERROR(PLATFORM_FAILURE); 1646 NOTIFY_ERROR(PLATFORM_FAILURE);
1616 return; 1647 return;
1617 } 1648 }
1618 1649
1619 // From here we stay in kChangingResolution and wait for 1650 // From here we stay in kChangingResolution and wait for
1620 // AssignPictureBuffers() before we can resume. 1651 // AssignPictureBuffers() before we can resume.
1621 } 1652 }
1622 1653
1623 void ExynosVideoDecodeAccelerator::ResumeAfterResolutionChange() { 1654 void V4L2VideoDecodeAccelerator::ResumeAfterResolutionChange() {
1624 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1655 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1625 DVLOG(3) << "ResumeAfterResolutionChange()"; 1656 DVLOG(3) << "ResumeAfterResolutionChange()";
1626 1657
1627 decoder_state_ = kDecoding; 1658 decoder_state_ = kDecoding;
1628 1659
1629 if (resolution_change_reset_pending_) { 1660 if (resolution_change_reset_pending_) {
1630 resolution_change_reset_pending_ = false; 1661 resolution_change_reset_pending_ = false;
1631 ResetTask(); 1662 ResetTask();
1632 return; 1663 return;
1633 } 1664 }
1634 1665
1635 if (!StartDevicePoll()) 1666 if (!StartDevicePoll())
1636 return; 1667 return;
1637 1668
1638 EnqueueMfc(); 1669 EnqueueMfc();
1639 ScheduleDecodeBufferTaskIfNeeded(); 1670 ScheduleDecodeBufferTaskIfNeeded();
1640 } 1671 }
1641 1672
1642 void ExynosVideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) { 1673 void V4L2VideoDecodeAccelerator::DevicePollTask(unsigned int poll_fds) {
1643 DVLOG(3) << "DevicePollTask()"; 1674 DVLOG(3) << "DevicePollTask()";
1644 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current()); 1675 DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
1645 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask"); 1676 TRACE_EVENT0("Video Decoder", "EVDA::DevicePollTask");
1646 1677
1647 // This routine just polls the set of device fds, and schedules a 1678 // This routine just polls the set of device fds, and schedules a
1648 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur. 1679 // ServiceDeviceTask() on decoder_thread_ when processing needs to occur.
1649 // Other threads may notify this task to return early by writing to 1680 // Other threads may notify this task to return early by writing to
1650 // device_poll_interrupt_fd_. 1681 // device_poll_interrupt_fd_.
1651 struct pollfd pollfds[3]; 1682 struct pollfd pollfds[3];
1652 nfds_t nfds; 1683 nfds_t nfds;
1653 int mfc_pollfd = -1; 1684 int mfc_pollfd = -1;
1654 1685
1655 // Add device_poll_interrupt_fd_; 1686 // Add device_poll_interrupt_fd_;
1656 pollfds[0].fd = device_poll_interrupt_fd_; 1687 pollfds[0].fd = device_poll_interrupt_fd_;
1657 pollfds[0].events = POLLIN | POLLERR; 1688 pollfds[0].events = POLLIN | POLLERR;
1658 nfds = 1; 1689 nfds = 1;
1659 1690
1660 if (poll_fds & kPollMfc) { 1691 if (poll_fds & kPollMfc) {
1661 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set"; 1692 DVLOG(3) << "DevicePollTask(): adding MFC to poll() set";
1662 pollfds[nfds].fd = mfc_fd_; 1693 pollfds[nfds].fd = videodec_fd_;
1663 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI; 1694 pollfds[nfds].events = POLLIN | POLLOUT | POLLERR | POLLPRI;
1664 mfc_pollfd = nfds; 1695 mfc_pollfd = nfds;
1665 nfds++; 1696 nfds++;
1666 } 1697 }
1667 1698
1668 // Poll it! 1699 // Poll it!
1669 if (HANDLE_EINTR(poll(pollfds, nfds, -1)) == -1) { 1700 if (HANDLE_EINTR(device->dev_poll(pollfds, nfds, -1)) == -1) {
1670 DPLOG(ERROR) << "DevicePollTask(): poll() failed"; 1701 DPLOG(ERROR) << "DevicePollTask(): poll() failed";
1671 NOTIFY_ERROR(PLATFORM_FAILURE); 1702 NOTIFY_ERROR(PLATFORM_FAILURE);
1672 return; 1703 return;
1673 } 1704 }
1674 1705
1675 bool mfc_event_pending = (mfc_pollfd != -1 && 1706 bool mfc_event_pending = (mfc_pollfd != -1 &&
1676 pollfds[mfc_pollfd].revents & POLLPRI); 1707 pollfds[mfc_pollfd].revents & POLLPRI);
1677 1708
1678 // All processing should happen on ServiceDeviceTask(), since we shouldn't 1709 // All processing should happen on ServiceDeviceTask(), since we shouldn't
1679 // touch decoder state from this thread. 1710 // touch decoder state from this thread.
1680 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1711 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1681 &ExynosVideoDecodeAccelerator::ServiceDeviceTask, 1712 &V4L2VideoDecodeAccelerator::ServiceDeviceTask,
1682 base::Unretained(this), mfc_event_pending)); 1713 base::Unretained(this), mfc_event_pending));
1683 } 1714 }
1684 1715
1685 void ExynosVideoDecodeAccelerator::NotifyError(Error error) { 1716 void V4L2VideoDecodeAccelerator::NotifyError(Error error) {
1686 DVLOG(2) << "NotifyError()"; 1717 DVLOG(2) << "NotifyError()";
1687 1718
1688 if (!child_message_loop_proxy_->BelongsToCurrentThread()) { 1719 if (!child_message_loop_proxy_->BelongsToCurrentThread()) {
1689 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( 1720 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
1690 &ExynosVideoDecodeAccelerator::NotifyError, weak_this_, error)); 1721 &V4L2VideoDecodeAccelerator::NotifyError, weak_this_, error));
1691 return; 1722 return;
1692 } 1723 }
1693 1724
1694 if (client_) { 1725 if (client_) {
1695 client_->NotifyError(error); 1726 client_->NotifyError(error);
1696 client_ptr_factory_.InvalidateWeakPtrs(); 1727 client_ptr_factory_.InvalidateWeakPtrs();
1697 } 1728 }
1698 } 1729 }
1699 1730
1700 void ExynosVideoDecodeAccelerator::SetDecoderState(State state) { 1731 void V4L2VideoDecodeAccelerator::SetDecoderState(State state) {
1701 DVLOG(3) << "SetDecoderState(): state=" << state; 1732 DVLOG(3) << "SetDecoderState(): state=" << state;
1702 1733
1703 // We can touch decoder_state_ only if this is the decoder thread or the 1734 // We can touch decoder_state_ only if this is the decoder thread or the
1704 // decoder thread isn't running. 1735 // decoder thread isn't running.
1705 if (decoder_thread_.message_loop() != NULL && 1736 if (decoder_thread_.message_loop() != NULL &&
1706 decoder_thread_.message_loop() != base::MessageLoop::current()) { 1737 decoder_thread_.message_loop() != base::MessageLoop::current()) {
1707 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1738 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1708 &ExynosVideoDecodeAccelerator::SetDecoderState, 1739 &V4L2VideoDecodeAccelerator::SetDecoderState,
1709 base::Unretained(this), state)); 1740 base::Unretained(this), state));
1710 } else { 1741 } else {
1711 decoder_state_ = state; 1742 decoder_state_ = state;
1712 } 1743 }
1713 } 1744 }
1714 1745
1715 bool ExynosVideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format, 1746 bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format,
1716 bool* again) { 1747 bool* again) {
1717 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1748 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1718 1749
1719 *again = false; 1750 *again = false;
1720 memset(format, 0, sizeof(*format)); 1751 memset(format, 0, sizeof(*format));
1721 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1752 format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1722 if (HANDLE_EINTR(ioctl(mfc_fd_, VIDIOC_G_FMT, format)) != 0) { 1753 if (HANDLE_EINTR(device->dev_ioctl(videodec_fd_, VIDIOC_G_FMT, format)) != 0) {
1723 if (errno == EINVAL) { 1754 if (errno == EINVAL) {
1724 // EINVAL means we haven't seen sufficient stream to decode the format. 1755 // EINVAL means we haven't seen sufficient stream to decode the format.
1725 *again = true; 1756 *again = true;
1726 return true; 1757 return true;
1727 } else { 1758 } else {
1728 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT"; 1759 DPLOG(ERROR) << "DecodeBufferInitial(): ioctl() failed: VIDIOC_G_FMT";
1729 NOTIFY_ERROR(PLATFORM_FAILURE); 1760 NOTIFY_ERROR(PLATFORM_FAILURE);
1730 return false; 1761 return false;
1731 } 1762 }
1732 } 1763 }
1733 1764
1734 return true; 1765 return true;
1735 } 1766 }
1736 1767
1737 bool ExynosVideoDecodeAccelerator::CreateBuffersForFormat( 1768 bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
1738 const struct v4l2_format& format) { 1769 const struct v4l2_format& format) {
1739 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1770 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1740 CHECK_EQ(format.fmt.pix_mp.num_planes, 2); 1771 CHECK_EQ(format.fmt.pix_mp.num_planes, 2);
1741 frame_buffer_size_.SetSize( 1772 frame_buffer_size_.SetSize(
1742 format.fmt.pix_mp.width, format.fmt.pix_mp.height); 1773 format.fmt.pix_mp.width, format.fmt.pix_mp.height);
1743 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat; 1774 mfc_output_buffer_pixelformat_ = format.fmt.pix_mp.pixelformat;
1744 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12M); 1775 DCHECK_EQ(mfc_output_buffer_pixelformat_, V4L2_PIX_FMT_NV12M);
1745 DVLOG(3) << "CreateBuffersForFormat(): new resolution: " 1776 DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
1746 << frame_buffer_size_.ToString(); 1777 << frame_buffer_size_.ToString();
1747 1778
1748 if (!CreateMfcOutputBuffers()) 1779 if (!CreateMfcOutputBuffers())
1749 return false; 1780 return false;
1750 1781
1751 return true; 1782 return true;
1752 } 1783 }
1753 1784
1754 bool ExynosVideoDecodeAccelerator::CreateMfcInputBuffers() { 1785 bool V4L2VideoDecodeAccelerator::CreateMfcInputBuffers() {
1755 DVLOG(3) << "CreateMfcInputBuffers()"; 1786 DVLOG(3) << "CreateMfcInputBuffers()";
1756 // We always run this as we prepare to initialize. 1787 // We always run this as we prepare to initialize.
1757 DCHECK_EQ(decoder_state_, kUninitialized); 1788 DCHECK_EQ(decoder_state_, kUninitialized);
1758 DCHECK(!mfc_input_streamon_); 1789 DCHECK(!mfc_input_streamon_);
1759 DCHECK(mfc_input_buffer_map_.empty()); 1790 DCHECK(mfc_input_buffer_map_.empty());
1760 1791
1761 __u32 pixelformat = 0; 1792 __u32 pixelformat = 0;
1762 if (video_profile_ >= media::H264PROFILE_MIN && 1793 if (video_profile_ >= media::H264PROFILE_MIN &&
1763 video_profile_ <= media::H264PROFILE_MAX) { 1794 video_profile_ <= media::H264PROFILE_MAX) {
1764 pixelformat = V4L2_PIX_FMT_H264; 1795 pixelformat = V4L2_PIX_FMT_H264;
1765 } else if (video_profile_ >= media::VP8PROFILE_MIN && 1796 } else if (video_profile_ >= media::VP8PROFILE_MIN &&
1766 video_profile_ <= media::VP8PROFILE_MAX) { 1797 video_profile_ <= media::VP8PROFILE_MAX) {
1767 pixelformat = V4L2_PIX_FMT_VP8; 1798 pixelformat = V4L2_PIX_FMT_VP8;
1768 } else { 1799 } else {
1769 NOTREACHED(); 1800 NOTREACHED();
1770 } 1801 }
1771 1802
1772 struct v4l2_format format; 1803 struct v4l2_format format;
1773 memset(&format, 0, sizeof(format)); 1804 memset(&format, 0, sizeof(format));
1774 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1805 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1775 format.fmt.pix_mp.pixelformat = pixelformat; 1806 format.fmt.pix_mp.pixelformat = pixelformat;
1776 format.fmt.pix_mp.plane_fmt[0].sizeimage = kMfcInputBufferMaxSize; 1807 format.fmt.pix_mp.plane_fmt[0].sizeimage = kMfcInputBufferMaxSize;
1777 format.fmt.pix_mp.num_planes = 1; 1808 format.fmt.pix_mp.num_planes = 1;
1778 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_S_FMT, &format); 1809 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_S_FMT, &format);
1779 1810
1780 struct v4l2_requestbuffers reqbufs; 1811 struct v4l2_requestbuffers reqbufs;
1781 memset(&reqbufs, 0, sizeof(reqbufs)); 1812 memset(&reqbufs, 0, sizeof(reqbufs));
1782 reqbufs.count = kMfcInputBufferCount; 1813 reqbufs.count = kMfcInputBufferCount;
1783 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1814 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1784 reqbufs.memory = V4L2_MEMORY_MMAP; 1815 reqbufs.memory = V4L2_MEMORY_MMAP;
1785 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs); 1816 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_REQBUFS, &reqbufs);
1786 mfc_input_buffer_map_.resize(reqbufs.count); 1817 mfc_input_buffer_map_.resize(reqbufs.count);
1787 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 1818 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1788 mfc_free_input_buffers_.push_back(i); 1819 mfc_free_input_buffers_.push_back(i);
1789 1820
1790 // Query for the MEMORY_MMAP pointer. 1821 // Query for the MEMORY_MMAP pointer.
1791 struct v4l2_plane planes[1]; 1822 struct v4l2_plane planes[1];
1792 struct v4l2_buffer buffer; 1823 struct v4l2_buffer buffer;
1793 memset(&buffer, 0, sizeof(buffer)); 1824 memset(&buffer, 0, sizeof(buffer));
1794 memset(planes, 0, sizeof(planes)); 1825 memset(planes, 0, sizeof(planes));
1795 buffer.index = i; 1826 buffer.index = i;
1796 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1827 buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1797 buffer.memory = V4L2_MEMORY_MMAP; 1828 buffer.memory = V4L2_MEMORY_MMAP;
1798 buffer.m.planes = planes; 1829 buffer.m.planes = planes;
1799 buffer.length = 1; 1830 buffer.length = 1;
1800 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_QUERYBUF, &buffer); 1831 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_QUERYBUF, &buffer);
1801 void* address = mmap(NULL, buffer.m.planes[0].length, 1832 void* address = device->dev_mmap(NULL, buffer.m.planes[0].length,
1802 PROT_READ | PROT_WRITE, MAP_SHARED, mfc_fd_, 1833 PROT_READ | PROT_WRITE, MAP_SHARED, videodec_fd_,
1803 buffer.m.planes[0].m.mem_offset); 1834 buffer.m.planes[0].m.mem_offset);
1804 if (address == MAP_FAILED) { 1835 if (address == MAP_FAILED) {
1805 DPLOG(ERROR) << "CreateMfcInputBuffers(): mmap() failed"; 1836 DPLOG(ERROR) << "CreateMfcInputBuffers(): mmap() failed";
1806 return false; 1837 return false;
1807 } 1838 }
1808 mfc_input_buffer_map_[i].address = address; 1839 mfc_input_buffer_map_[i].address = address;
1809 mfc_input_buffer_map_[i].length = buffer.m.planes[0].length; 1840 mfc_input_buffer_map_[i].length = buffer.m.planes[0].length;
1810 } 1841 }
1811 1842
1812 return true; 1843 return true;
1813 } 1844 }
1814 1845
1815 bool ExynosVideoDecodeAccelerator::CreateMfcOutputBuffers() { 1846 bool V4L2VideoDecodeAccelerator::CreateMfcOutputBuffers() {
1816 DVLOG(3) << "CreateMfcOutputBuffers()"; 1847 DVLOG(3) << "CreateMfcOutputBuffers()";
1817 DCHECK(decoder_state_ == kInitialized || 1848 DCHECK(decoder_state_ == kInitialized ||
1818 decoder_state_ == kChangingResolution); 1849 decoder_state_ == kChangingResolution);
1819 DCHECK(!mfc_output_streamon_); 1850 DCHECK(!mfc_output_streamon_);
1820 DCHECK(mfc_output_buffer_map_.empty()); 1851 DCHECK(mfc_output_buffer_map_.empty());
1821 1852
1822 // Number of MFC output buffers we need. 1853 // Number of MFC output buffers we need.
1823 struct v4l2_control ctrl; 1854 struct v4l2_control ctrl;
1824 memset(&ctrl, 0, sizeof(ctrl)); 1855 memset(&ctrl, 0, sizeof(ctrl));
1825 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE; 1856 ctrl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
1826 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_G_CTRL, &ctrl); 1857 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_G_CTRL, &ctrl);
1827 mfc_output_dpb_size_ = ctrl.value; 1858 mfc_output_dpb_size_ = ctrl.value;
1828 1859
1829 // Output format setup in Initialize(). 1860 // Output format setup in Initialize().
1830 1861
1831 // Allocate the output buffers. 1862 // Allocate the output buffers.
1832 struct v4l2_requestbuffers reqbufs; 1863 struct v4l2_requestbuffers reqbufs;
1833 memset(&reqbufs, 0, sizeof(reqbufs)); 1864 memset(&reqbufs, 0, sizeof(reqbufs));
1834 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount; 1865 reqbufs.count = mfc_output_dpb_size_ + kDpbOutputBufferExtraCount;
1835 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1866 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1836 reqbufs.memory = V4L2_MEMORY_MMAP; 1867 reqbufs.memory = V4L2_MEMORY_MMAP;
1837 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_REQBUFS, &reqbufs); 1868 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_REQBUFS, &reqbufs);
1838 1869
1839 // Create DMABUFs from output buffers. 1870 // Create DMABUFs from output buffers.
1840 mfc_output_buffer_map_.resize(reqbufs.count); 1871 mfc_output_buffer_map_.resize(reqbufs.count);
1841 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) { 1872 for (size_t i = 0; i < mfc_output_buffer_map_.size(); ++i) {
1842 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; 1873 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
1843 for (size_t j = 0; j < arraysize(output_record.fds); ++j) { 1874 for (size_t j = 0; j < arraysize(output_record.fds); ++j) {
1844 // Export the DMABUF fd so we can export it as a texture. 1875 // Export the DMABUF fd so we can export it as a texture.
1845 struct v4l2_exportbuffer expbuf; 1876 struct v4l2_exportbuffer expbuf;
1846 memset(&expbuf, 0, sizeof(expbuf)); 1877 memset(&expbuf, 0, sizeof(expbuf));
1847 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1878 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1848 expbuf.index = i; 1879 expbuf.index = i;
1849 expbuf.plane = j; 1880 expbuf.plane = j;
1850 expbuf.flags = O_CLOEXEC; 1881 expbuf.flags = O_CLOEXEC;
1851 IOCTL_OR_ERROR_RETURN_FALSE(mfc_fd_, VIDIOC_EXPBUF, &expbuf); 1882 IOCTL_OR_ERROR_RETURN_FALSE(videodec_fd_, VIDIOC_EXPBUF, &expbuf);
1852 output_record.fds[j] = expbuf.fd; 1883 output_record.fds[j] = expbuf.fd;
1853 } 1884 }
1854 } 1885 }
1855 1886
1856 DVLOG(3) << "CreateMfcOutputBuffers(): ProvidePictureBuffers(): " 1887 DVLOG(3) << "CreateMfcOutputBuffers(): ProvidePictureBuffers(): "
1857 << "buffer_count=" << mfc_output_buffer_map_.size() 1888 << "buffer_count=" << mfc_output_buffer_map_.size()
1858 << ", width=" << frame_buffer_size_.width() 1889 << ", width=" << frame_buffer_size_.width()
1859 << ", height=" << frame_buffer_size_.height(); 1890 << ", height=" << frame_buffer_size_.height();
1860 child_message_loop_proxy_->PostTask(FROM_HERE, 1891 child_message_loop_proxy_->PostTask(FROM_HERE,
1861 base::Bind(&Client::ProvidePictureBuffers, 1892 base::Bind(&Client::ProvidePictureBuffers,
1862 client_, 1893 client_,
1863 mfc_output_buffer_map_.size(), 1894 mfc_output_buffer_map_.size(),
1864 frame_buffer_size_, 1895 frame_buffer_size_,
1865 GL_TEXTURE_EXTERNAL_OES)); 1896 GL_TEXTURE_EXTERNAL_OES));
1866 1897
1867 return true; 1898 return true;
1868 } 1899 }
1869 1900
1870 void ExynosVideoDecodeAccelerator::DestroyMfcInputBuffers() { 1901 void V4L2VideoDecodeAccelerator::DestroyMfcInputBuffers() {
1871 DVLOG(3) << "DestroyMfcInputBuffers()"; 1902 DVLOG(3) << "DestroyMfcInputBuffers()";
1872 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1903 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1873 DCHECK(!mfc_input_streamon_); 1904 DCHECK(!mfc_input_streamon_);
1874 1905
1875 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) { 1906 for (size_t i = 0; i < mfc_input_buffer_map_.size(); ++i) {
1876 if (mfc_input_buffer_map_[i].address != NULL) { 1907 if (mfc_input_buffer_map_[i].address != NULL) {
1877 munmap(mfc_input_buffer_map_[i].address, 1908 device->dev_munmap(mfc_input_buffer_map_[i].address,
1878 mfc_input_buffer_map_[i].length); 1909 mfc_input_buffer_map_[i].length);
1879 } 1910 }
1880 } 1911 }
1881 1912
1882 struct v4l2_requestbuffers reqbufs; 1913 struct v4l2_requestbuffers reqbufs;
1883 memset(&reqbufs, 0, sizeof(reqbufs)); 1914 memset(&reqbufs, 0, sizeof(reqbufs));
1884 reqbufs.count = 0; 1915 reqbufs.count = 0;
1885 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1916 reqbufs.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1886 reqbufs.memory = V4L2_MEMORY_MMAP; 1917 reqbufs.memory = V4L2_MEMORY_MMAP;
1887 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) 1918 if (device->dev_ioctl(videodec_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
1888 DPLOG(ERROR) << "DestroyMfcInputBuffers(): ioctl() failed: VIDIOC_REQBUFS"; 1919 DPLOG(ERROR) << "DestroyMfcInputBuffers(): ioctl() failed: VIDIOC_REQBUFS";
1889 1920
1890 mfc_input_buffer_map_.clear(); 1921 mfc_input_buffer_map_.clear();
1891 mfc_free_input_buffers_.clear(); 1922 mfc_free_input_buffers_.clear();
1892 } 1923 }
1893 1924
1894 void ExynosVideoDecodeAccelerator::DestroyMfcOutputBuffers() { 1925 void V4L2VideoDecodeAccelerator::DestroyMfcOutputBuffers() {
1895 DVLOG(3) << "DestroyMfcOutputBuffers()"; 1926 DVLOG(3) << "DestroyMfcOutputBuffers()";
1896 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1927 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1897 DCHECK(!mfc_output_streamon_); 1928 DCHECK(!mfc_output_streamon_);
1898 1929
1899 if (mfc_output_buffer_map_.size() != 0) { 1930 if (mfc_output_buffer_map_.size() != 0) {
1931 // TODO(sheu, posciak): Making the context current should not be required
1932 // anymore. Remove it and verify (crbug.com/327869).
1900 if (!make_context_current_.Run()) { 1933 if (!make_context_current_.Run()) {
1901 DLOG(ERROR) << "DestroyMfcOutputBuffers(): " 1934 DLOG(ERROR) << "DestroyMfcOutputBuffers(): "
1902 << "could not make context current"; 1935 << "could not make context current";
1903 } else { 1936 } else {
1904 size_t i = 0; 1937 size_t i = 0;
1905 do { 1938 do {
1906 MfcOutputRecord& output_record = mfc_output_buffer_map_[i]; 1939 MfcOutputRecord& output_record = mfc_output_buffer_map_[i];
1907 for (size_t j = 0; j < arraysize(output_record.fds); ++j) { 1940 for (size_t j = 0; j < arraysize(output_record.fds); ++j) {
1908 if (output_record.fds[j] != -1) 1941 if (output_record.fds[j] != -1)
1909 close(output_record.fds[j]); 1942 device->dev_close(output_record.fds[j]);
1910 if (output_record.egl_image != EGL_NO_IMAGE_KHR) 1943 if (output_record.egl_image != EGL_NO_IMAGE_KHR)
1911 eglDestroyImageKHR(egl_display_, output_record.egl_image); 1944 eglDestroyImageKHR(egl_display_, output_record.egl_image);
1912 if (output_record.egl_sync != EGL_NO_SYNC_KHR) 1945 if (output_record.egl_sync != EGL_NO_SYNC_KHR)
1913 eglDestroySyncKHR(egl_display_, output_record.egl_sync); 1946 eglDestroySyncKHR(egl_display_, output_record.egl_sync);
1914 } 1947 }
1915 DVLOG(1) << "DestroyMfcOutputBuffers(): dismissing PictureBuffer id=" 1948 DVLOG(1) << "DestroyMfcOutputBuffers(): dismissing PictureBuffer id="
1916 << output_record.picture_id; 1949 << output_record.picture_id;
1917 child_message_loop_proxy_->PostTask( 1950 child_message_loop_proxy_->PostTask(
1918 FROM_HERE, 1951 FROM_HERE,
1919 base::Bind(&Client::DismissPictureBuffer, 1952 base::Bind(&Client::DismissPictureBuffer,
1920 client_, 1953 client_,
1921 output_record.picture_id)); 1954 output_record.picture_id));
1922 i++; 1955 i++;
1923 } while (i < mfc_output_buffer_map_.size()); 1956 } while (i < mfc_output_buffer_map_.size());
1924 } 1957 }
1925 } 1958 }
1926 1959
1927 struct v4l2_requestbuffers reqbufs; 1960 struct v4l2_requestbuffers reqbufs;
1928 memset(&reqbufs, 0, sizeof(reqbufs)); 1961 memset(&reqbufs, 0, sizeof(reqbufs));
1929 reqbufs.count = 0; 1962 reqbufs.count = 0;
1930 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1963 reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1931 reqbufs.memory = V4L2_MEMORY_MMAP; 1964 reqbufs.memory = V4L2_MEMORY_MMAP;
1932 if (ioctl(mfc_fd_, VIDIOC_REQBUFS, &reqbufs) != 0) 1965 if (device->dev_ioctl(videodec_fd_, VIDIOC_REQBUFS, &reqbufs) != 0)
1933 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS"; 1966 DPLOG(ERROR) << "DestroyMfcOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
1934 1967
1935 mfc_output_buffer_map_.clear(); 1968 mfc_output_buffer_map_.clear();
1936 while (!mfc_free_output_buffers_.empty()) 1969 while (!mfc_free_output_buffers_.empty())
1937 mfc_free_output_buffers_.pop(); 1970 mfc_free_output_buffers_.pop();
1938 } 1971 }
1939 1972
1940 void ExynosVideoDecodeAccelerator::ResolutionChangeDestroyBuffers() { 1973 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
1941 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread()); 1974 DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
1942 DVLOG(3) << "ResolutionChangeDestroyBuffers()"; 1975 DVLOG(3) << "ResolutionChangeDestroyBuffers()";
1943 1976
1944 DestroyMfcOutputBuffers(); 1977 DestroyMfcOutputBuffers();
1945 1978
1946 // Finish resolution change on decoder thread. 1979 // Finish resolution change on decoder thread.
1947 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 1980 decoder_thread_.message_loop()->PostTask(FROM_HERE, base::Bind(
1948 &ExynosVideoDecodeAccelerator::FinishResolutionChange, 1981 &V4L2VideoDecodeAccelerator::FinishResolutionChange,
1949 base::Unretained(this))); 1982 base::Unretained(this)));
1950 } 1983 }
1951 1984
1952 void ExynosVideoDecodeAccelerator::SendPictureReady() { 1985 void V4L2VideoDecodeAccelerator::SendPictureReady() {
1953 DVLOG(3) << "SendPictureReady()"; 1986 DVLOG(3) << "SendPictureReady()";
1954 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 1987 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1955 bool resetting_or_flushing = 1988 bool resetting_or_flushing =
1956 (decoder_state_ == kResetting || decoder_flushing_); 1989 (decoder_state_ == kResetting || decoder_flushing_);
1957 while (pending_picture_ready_.size() > 0) { 1990 while (pending_picture_ready_.size() > 0) {
1958 bool cleared = pending_picture_ready_.front().cleared; 1991 bool cleared = pending_picture_ready_.front().cleared;
1959 const media::Picture& picture = pending_picture_ready_.front().picture; 1992 const media::Picture& picture = pending_picture_ready_.front().picture;
1960 if (cleared && picture_clearing_count_ == 0) { 1993 if (cleared && picture_clearing_count_ == 0) {
1961 // This picture is cleared. Post it to IO thread to reduce latency. This 1994 // This picture is cleared. Post it to IO thread to reduce latency. This
1962 // should be the case after all pictures are cleared at the beginning. 1995 // should be the case after all pictures are cleared at the beginning.
1963 io_message_loop_proxy_->PostTask( 1996 io_message_loop_proxy_->PostTask(
1964 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture)); 1997 FROM_HERE, base::Bind(&Client::PictureReady, io_client_, picture));
1965 pending_picture_ready_.pop(); 1998 pending_picture_ready_.pop();
1966 } else if (!cleared || resetting_or_flushing) { 1999 } else if (!cleared || resetting_or_flushing) {
1967 DVLOG(3) << "SendPictureReady()" 2000 DVLOG(3) << "SendPictureReady()"
1968 << ". cleared=" << pending_picture_ready_.front().cleared 2001 << ". cleared=" << pending_picture_ready_.front().cleared
1969 << ", decoder_state_=" << decoder_state_ 2002 << ", decoder_state_=" << decoder_state_
1970 << ", decoder_flushing_=" << decoder_flushing_ 2003 << ", decoder_flushing_=" << decoder_flushing_
1971 << ", picture_clearing_count_=" << picture_clearing_count_; 2004 << ", picture_clearing_count_=" << picture_clearing_count_;
1972 // If the picture is not cleared, post it to the child thread because it 2005 // If the picture is not cleared, post it to the child thread because it
1973 // has to be cleared in the child thread. A picture only needs to be 2006 // has to be cleared in the child thread. A picture only needs to be
1974 // cleared once. If the decoder is resetting or flushing, send all 2007 // cleared once. If the decoder is resetting or flushing, send all
1975 // pictures to ensure PictureReady arrive before reset or flush done. 2008 // pictures to ensure PictureReady arrive before reset or flush done.
1976 child_message_loop_proxy_->PostTaskAndReply( 2009 child_message_loop_proxy_->PostTaskAndReply(
1977 FROM_HERE, 2010 FROM_HERE,
1978 base::Bind(&Client::PictureReady, client_, picture), 2011 base::Bind(&Client::PictureReady, client_, picture),
1979 // Unretained is safe. If Client::PictureReady gets to run, |this| is 2012 // Unretained is safe. If Client::PictureReady gets to run, |this| is
1980 // alive. Destroy() will wait the decode thread to finish. 2013 // alive. Destroy() will wait the decode thread to finish.
1981 base::Bind(&ExynosVideoDecodeAccelerator::PictureCleared, 2014 base::Bind(&V4L2VideoDecodeAccelerator::PictureCleared,
1982 base::Unretained(this))); 2015 base::Unretained(this)));
1983 picture_clearing_count_++; 2016 picture_clearing_count_++;
1984 pending_picture_ready_.pop(); 2017 pending_picture_ready_.pop();
1985 } else { 2018 } else {
1986 // This picture is cleared. But some pictures are about to be cleared on 2019 // This picture is cleared. But some pictures are about to be cleared on
1987 // the child thread. To preserve the order, do not send this until those 2020 // the child thread. To preserve the order, do not send this until those
1988 // pictures are cleared. 2021 // pictures are cleared.
1989 break; 2022 break;
1990 } 2023 }
1991 } 2024 }
1992 } 2025 }
1993 2026
1994 void ExynosVideoDecodeAccelerator::PictureCleared() { 2027 void V4L2VideoDecodeAccelerator::PictureCleared() {
1995 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; 2028 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_;
1996 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); 2029 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
1997 DCHECK_GT(picture_clearing_count_, 0); 2030 DCHECK_GT(picture_clearing_count_, 0);
1998 picture_clearing_count_--; 2031 picture_clearing_count_--;
1999 SendPictureReady(); 2032 SendPictureReady();
2000 } 2033 }
2001 2034
2002 } // namespace content 2035 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698