Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "media/base/video_frame.h" | 5 #include "media/base/video_frame.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 #endif // defined(VIDEO_HOLE) | 131 #endif // defined(VIDEO_HOLE) |
| 132 case VideoFrame::ARGB: | 132 case VideoFrame::ARGB: |
| 133 NOTIMPLEMENTED(); | 133 NOTIMPLEMENTED(); |
| 134 return nullptr; | 134 return nullptr; |
| 135 } | 135 } |
| 136 | 136 |
| 137 // Since we're creating a new YUV frame (and allocating memory for it | 137 // Since we're creating a new YUV frame (and allocating memory for it |
| 138 // ourselves), we can pad the requested |coded_size| if necessary if the | 138 // ourselves), we can pad the requested |coded_size| if necessary if the |
| 139 // request does not line up on sample boundaries. | 139 // request does not line up on sample boundaries. |
| 140 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); | 140 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); |
| 141 DCHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size)); | 141 DCHECK(IsValidConfig(format, TEXTURE_NONE, new_coded_size, visible_rect, |
| 142 natural_size)); | |
| 142 | 143 |
| 144 gpu::MailboxHolder mailboxes[kMaxPlanes]; | |
| 143 scoped_refptr<VideoFrame> frame( | 145 scoped_refptr<VideoFrame> frame( |
| 144 new VideoFrame(format, | 146 new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| 145 new_coded_size, | 147 mailboxes, TEXTURE_NONE, timestamp, false)); |
| 146 visible_rect, | |
| 147 natural_size, | |
| 148 scoped_ptr<gpu::MailboxHolder>(), | |
| 149 timestamp, | |
| 150 false)); | |
| 151 frame->AllocateYUV(); | 148 frame->AllocateYUV(); |
| 152 return frame; | 149 return frame; |
| 153 } | 150 } |
| 154 | 151 |
| 155 // static | 152 // static |
| 156 std::string VideoFrame::FormatToString(VideoFrame::Format format) { | 153 std::string VideoFrame::FormatToString(VideoFrame::Format format) { |
| 157 switch (format) { | 154 switch (format) { |
| 158 case VideoFrame::UNKNOWN: | 155 case VideoFrame::UNKNOWN: |
| 159 return "UNKNOWN"; | 156 return "UNKNOWN"; |
| 160 case VideoFrame::YV12: | 157 case VideoFrame::YV12: |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 181 return "ARGB"; | 178 return "ARGB"; |
| 182 case VideoFrame::YV12HD: | 179 case VideoFrame::YV12HD: |
| 183 return "YV12HD"; | 180 return "YV12HD"; |
| 184 } | 181 } |
| 185 NOTREACHED() << "Invalid videoframe format provided: " << format; | 182 NOTREACHED() << "Invalid videoframe format provided: " << format; |
| 186 return ""; | 183 return ""; |
| 187 } | 184 } |
| 188 | 185 |
| 189 // static | 186 // static |
| 190 bool VideoFrame::IsValidConfig(VideoFrame::Format format, | 187 bool VideoFrame::IsValidConfig(VideoFrame::Format format, |
| 188 VideoFrame::TextureFormat texture_format, | |
| 191 const gfx::Size& coded_size, | 189 const gfx::Size& coded_size, |
| 192 const gfx::Rect& visible_rect, | 190 const gfx::Rect& visible_rect, |
| 193 const gfx::Size& natural_size) { | 191 const gfx::Size& natural_size) { |
| 194 // Check maximum limits for all formats. | 192 // Check maximum limits for all formats. |
| 195 if (coded_size.GetArea() > limits::kMaxCanvas || | 193 if (coded_size.GetArea() > limits::kMaxCanvas || |
| 196 coded_size.width() > limits::kMaxDimension || | 194 coded_size.width() > limits::kMaxDimension || |
| 197 coded_size.height() > limits::kMaxDimension || | 195 coded_size.height() > limits::kMaxDimension || |
| 198 visible_rect.x() < 0 || visible_rect.y() < 0 || | 196 visible_rect.x() < 0 || visible_rect.y() < 0 || |
| 199 visible_rect.right() > coded_size.width() || | 197 visible_rect.right() > coded_size.width() || |
| 200 visible_rect.bottom() > coded_size.height() || | 198 visible_rect.bottom() > coded_size.height() || |
| 201 natural_size.GetArea() > limits::kMaxCanvas || | 199 natural_size.GetArea() > limits::kMaxCanvas || |
| 202 natural_size.width() > limits::kMaxDimension || | 200 natural_size.width() > limits::kMaxDimension || |
| 203 natural_size.height() > limits::kMaxDimension) | 201 natural_size.height() > limits::kMaxDimension) |
| 204 return false; | 202 return false; |
| 205 | 203 |
| 206 // Check format-specific width/height requirements. | 204 // Check format-specific width/height requirements. |
| 207 switch (format) { | 205 switch (format) { |
| 208 case VideoFrame::UNKNOWN: | 206 case VideoFrame::UNKNOWN: |
| 209 return (coded_size.IsEmpty() && visible_rect.IsEmpty() && | 207 return (coded_size.IsEmpty() && visible_rect.IsEmpty() && |
| 210 natural_size.IsEmpty()); | 208 natural_size.IsEmpty()); |
| 211 | 209 |
| 212 // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are | 210 // NATIVE_TEXTURE and HOLE have no software-allocated buffers and are |
| 213 // allowed to skip the below check. | 211 // allowed to skip the below check. |
| 214 case VideoFrame::NATIVE_TEXTURE: | 212 case VideoFrame::NATIVE_TEXTURE: |
| 213 return texture_format != VideoFrame::TEXTURE_NONE; | |
| 215 #if defined(VIDEO_HOLE) | 214 #if defined(VIDEO_HOLE) |
| 216 case VideoFrame::HOLE: | 215 case VideoFrame::HOLE: |
| 217 #endif // defined(VIDEO_HOLE) | 216 #endif // defined(VIDEO_HOLE) |
| 218 return true; | 217 return true; |
| 219 | 218 |
| 220 case VideoFrame::YV24: | 219 case VideoFrame::YV24: |
| 221 case VideoFrame::YV12: | 220 case VideoFrame::YV12: |
| 222 case VideoFrame::YV12J: | 221 case VideoFrame::YV12J: |
| 223 case VideoFrame::I420: | 222 case VideoFrame::I420: |
| 224 case VideoFrame::YV12A: | 223 case VideoFrame::YV12A: |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 236 !coded_size.IsEmpty() && !visible_rect.IsEmpty() && | 235 !coded_size.IsEmpty() && !visible_rect.IsEmpty() && |
| 237 !natural_size.IsEmpty(); | 236 !natural_size.IsEmpty(); |
| 238 } | 237 } |
| 239 | 238 |
| 240 NOTREACHED(); | 239 NOTREACHED(); |
| 241 return false; | 240 return false; |
| 242 } | 241 } |
| 243 | 242 |
| 244 // static | 243 // static |
| 245 scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( | 244 scoped_refptr<VideoFrame> VideoFrame::WrapNativeTexture( |
| 246 scoped_ptr<gpu::MailboxHolder> mailbox_holder, | 245 const gpu::MailboxHolder& mailbox_holder, |
| 247 const ReleaseMailboxCB& mailbox_holder_release_cb, | 246 const ReleaseMailboxCB& mailbox_holder_release_cb, |
| 248 const gfx::Size& coded_size, | 247 const gfx::Size& coded_size, |
| 249 const gfx::Rect& visible_rect, | 248 const gfx::Rect& visible_rect, |
| 250 const gfx::Size& natural_size, | 249 const gfx::Size& natural_size, |
| 251 base::TimeDelta timestamp, | 250 base::TimeDelta timestamp, |
| 252 bool allow_overlay) { | 251 bool allow_overlay) { |
| 253 scoped_refptr<VideoFrame> frame(new VideoFrame(NATIVE_TEXTURE, | 252 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| 254 coded_size, | 253 mailbox_holders[0] = mailbox_holder; |
|
reveman
2015/05/03 16:13:27
s/0/kARGBPlan/
Daniele Castagna
2015/05/04 15:00:15
Done.
| |
| 255 visible_rect, | 254 scoped_refptr<VideoFrame> frame( |
| 256 natural_size, | 255 new VideoFrame(NATIVE_TEXTURE, coded_size, visible_rect, natural_size, |
| 257 mailbox_holder.Pass(), | 256 mailbox_holders, TEXTURE_RGBA, timestamp, false)); |
| 258 timestamp, | 257 frame->mailbox_holders_release_cb_ = mailbox_holder_release_cb; |
| 259 false)); | |
| 260 frame->mailbox_holder_release_cb_ = mailbox_holder_release_cb; | |
| 261 frame->allow_overlay_ = allow_overlay; | 258 frame->allow_overlay_ = allow_overlay; |
| 262 | |
| 263 return frame; | 259 return frame; |
| 264 } | 260 } |
| 265 | 261 |
| 262 // static | |
| 263 scoped_refptr<VideoFrame> VideoFrame::WrapYUVNativeTextures( | |
| 264 const gpu::MailboxHolder& y_mailbox_holder, | |
| 265 const gpu::MailboxHolder& u_mailbox_holder, | |
| 266 const gpu::MailboxHolder& v_mailbox_holder, | |
| 267 const ReleaseMailboxCB& mailbox_holder_release_cb, | |
| 268 const gfx::Size& coded_size, | |
| 269 const gfx::Rect& visible_rect, | |
| 270 const gfx::Size& natural_size, | |
| 271 base::TimeDelta timestamp, | |
| 272 bool allow_overlay) { | |
| 273 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; | |
| 274 mailbox_holders[kYPlane] = y_mailbox_holder; | |
| 275 mailbox_holders[kUPlane] = u_mailbox_holder; | |
| 276 mailbox_holders[kVPlane] = v_mailbox_holder; | |
| 277 scoped_refptr<VideoFrame> frame( | |
| 278 new VideoFrame(NATIVE_TEXTURE, coded_size, visible_rect, natural_size, | |
| 279 mailbox_holders, TEXTURE_YUV_R8R8R8, timestamp, false)); | |
| 280 frame->mailbox_holders_release_cb_ = mailbox_holder_release_cb; | |
| 281 frame->allow_overlay_ = allow_overlay; | |
| 282 return frame; | |
| 283 } | |
| 284 | |
| 266 // static | 285 // static |
| 267 scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory( | 286 scoped_refptr<VideoFrame> VideoFrame::WrapExternalPackedMemory( |
| 268 Format format, | 287 Format format, |
| 269 const gfx::Size& coded_size, | 288 const gfx::Size& coded_size, |
| 270 const gfx::Rect& visible_rect, | 289 const gfx::Rect& visible_rect, |
| 271 const gfx::Size& natural_size, | 290 const gfx::Size& natural_size, |
| 272 uint8* data, | 291 uint8* data, |
| 273 size_t data_size, | 292 size_t data_size, |
| 274 base::SharedMemoryHandle handle, | 293 base::SharedMemoryHandle handle, |
| 275 size_t data_offset, | 294 size_t data_offset, |
| 276 base::TimeDelta timestamp, | 295 base::TimeDelta timestamp, |
| 277 const base::Closure& no_longer_needed_cb) { | 296 const base::Closure& no_longer_needed_cb) { |
| 278 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); | 297 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); |
| 279 | 298 |
| 280 if (!IsValidConfig(format, new_coded_size, visible_rect, natural_size)) | 299 if (!IsValidConfig(format, TEXTURE_NONE, new_coded_size, visible_rect, |
| 300 natural_size)) | |
| 281 return NULL; | 301 return NULL; |
| 282 if (data_size < AllocationSize(format, new_coded_size)) | 302 if (data_size < AllocationSize(format, new_coded_size)) |
| 283 return NULL; | 303 return NULL; |
| 284 | 304 |
| 285 switch (format) { | 305 switch (format) { |
| 286 case VideoFrame::I420: { | 306 case VideoFrame::I420: { |
| 307 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; | |
| 287 scoped_refptr<VideoFrame> frame( | 308 scoped_refptr<VideoFrame> frame( |
| 288 new VideoFrame(format, | 309 new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| 289 new_coded_size, | 310 mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| 290 visible_rect, | |
| 291 natural_size, | |
| 292 scoped_ptr<gpu::MailboxHolder>(), | |
| 293 timestamp, | |
| 294 false)); | |
| 295 frame->shared_memory_handle_ = handle; | 311 frame->shared_memory_handle_ = handle; |
| 296 frame->shared_memory_offset_ = data_offset; | 312 frame->shared_memory_offset_ = data_offset; |
| 297 frame->strides_[kYPlane] = new_coded_size.width(); | 313 frame->strides_[kYPlane] = new_coded_size.width(); |
| 298 frame->strides_[kUPlane] = new_coded_size.width() / 2; | 314 frame->strides_[kUPlane] = new_coded_size.width() / 2; |
| 299 frame->strides_[kVPlane] = new_coded_size.width() / 2; | 315 frame->strides_[kVPlane] = new_coded_size.width() / 2; |
| 300 frame->data_[kYPlane] = data; | 316 frame->data_[kYPlane] = data; |
| 301 frame->data_[kUPlane] = data + new_coded_size.GetArea(); | 317 frame->data_[kUPlane] = data + new_coded_size.GetArea(); |
| 302 frame->data_[kVPlane] = data + (new_coded_size.GetArea() * 5 / 4); | 318 frame->data_[kVPlane] = data + (new_coded_size.GetArea() * 5 / 4); |
| 303 frame->no_longer_needed_cb_ = no_longer_needed_cb; | 319 frame->no_longer_needed_cb_ = no_longer_needed_cb; |
| 304 return frame; | 320 return frame; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 317 const gfx::Size& natural_size, | 333 const gfx::Size& natural_size, |
| 318 int32 y_stride, | 334 int32 y_stride, |
| 319 int32 u_stride, | 335 int32 u_stride, |
| 320 int32 v_stride, | 336 int32 v_stride, |
| 321 uint8* y_data, | 337 uint8* y_data, |
| 322 uint8* u_data, | 338 uint8* u_data, |
| 323 uint8* v_data, | 339 uint8* v_data, |
| 324 base::TimeDelta timestamp, | 340 base::TimeDelta timestamp, |
| 325 const base::Closure& no_longer_needed_cb) { | 341 const base::Closure& no_longer_needed_cb) { |
| 326 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); | 342 const gfx::Size new_coded_size = AdjustCodedSize(format, coded_size); |
| 327 CHECK(IsValidConfig(format, new_coded_size, visible_rect, natural_size)); | 343 CHECK(IsValidConfig(format, TEXTURE_NONE, new_coded_size, visible_rect, |
| 344 natural_size)); | |
| 328 | 345 |
| 346 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; | |
| 329 scoped_refptr<VideoFrame> frame( | 347 scoped_refptr<VideoFrame> frame( |
| 330 new VideoFrame(format, | 348 new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| 331 new_coded_size, | 349 mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| 332 visible_rect, | |
| 333 natural_size, | |
| 334 scoped_ptr<gpu::MailboxHolder>(), | |
| 335 timestamp, | |
| 336 false)); | |
| 337 frame->strides_[kYPlane] = y_stride; | 350 frame->strides_[kYPlane] = y_stride; |
| 338 frame->strides_[kUPlane] = u_stride; | 351 frame->strides_[kUPlane] = u_stride; |
| 339 frame->strides_[kVPlane] = v_stride; | 352 frame->strides_[kVPlane] = v_stride; |
| 340 frame->data_[kYPlane] = y_data; | 353 frame->data_[kYPlane] = y_data; |
| 341 frame->data_[kUPlane] = u_data; | 354 frame->data_[kUPlane] = u_data; |
| 342 frame->data_[kVPlane] = v_data; | 355 frame->data_[kVPlane] = v_data; |
| 343 frame->no_longer_needed_cb_ = no_longer_needed_cb; | 356 frame->no_longer_needed_cb_ = no_longer_needed_cb; |
| 344 return frame; | 357 return frame; |
| 345 } | 358 } |
| 346 | 359 |
| 347 #if defined(OS_POSIX) | 360 #if defined(OS_POSIX) |
| 348 // static | 361 // static |
| 349 scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs( | 362 scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs( |
| 350 Format format, | 363 Format format, |
| 351 const gfx::Size& coded_size, | 364 const gfx::Size& coded_size, |
| 352 const gfx::Rect& visible_rect, | 365 const gfx::Rect& visible_rect, |
| 353 const gfx::Size& natural_size, | 366 const gfx::Size& natural_size, |
| 354 const std::vector<int> dmabuf_fds, | 367 const std::vector<int> dmabuf_fds, |
| 355 base::TimeDelta timestamp, | 368 base::TimeDelta timestamp, |
| 356 const base::Closure& no_longer_needed_cb) { | 369 const base::Closure& no_longer_needed_cb) { |
| 357 if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) | 370 if (!IsValidConfig(format, TEXTURE_NONE, coded_size, visible_rect, |
| 371 natural_size)) | |
| 358 return NULL; | 372 return NULL; |
| 359 | 373 |
| 360 // TODO(posciak): This is not exactly correct, it's possible for one | 374 // TODO(posciak): This is not exactly correct, it's possible for one |
| 361 // buffer to contain more than one plane. | 375 // buffer to contain more than one plane. |
| 362 if (dmabuf_fds.size() != NumPlanes(format)) { | 376 if (dmabuf_fds.size() != NumPlanes(format)) { |
| 363 LOG(FATAL) << "Not enough dmabuf fds provided!"; | 377 LOG(FATAL) << "Not enough dmabuf fds provided!"; |
| 364 return NULL; | 378 return NULL; |
| 365 } | 379 } |
| 366 | 380 |
| 381 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; | |
| 367 scoped_refptr<VideoFrame> frame( | 382 scoped_refptr<VideoFrame> frame( |
| 368 new VideoFrame(format, | 383 new VideoFrame(format, coded_size, visible_rect, natural_size, |
| 369 coded_size, | 384 mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| 370 visible_rect, | |
| 371 natural_size, | |
| 372 scoped_ptr<gpu::MailboxHolder>(), | |
| 373 timestamp, | |
| 374 false)); | |
| 375 | 385 |
| 376 for (size_t i = 0; i < dmabuf_fds.size(); ++i) { | 386 for (size_t i = 0; i < dmabuf_fds.size(); ++i) { |
| 377 int duped_fd = HANDLE_EINTR(dup(dmabuf_fds[i])); | 387 int duped_fd = HANDLE_EINTR(dup(dmabuf_fds[i])); |
| 378 if (duped_fd == -1) { | 388 if (duped_fd == -1) { |
| 379 // The already-duped in previous iterations fds will be closed when | 389 // The already-duped in previous iterations fds will be closed when |
| 380 // the partially-created frame drops out of scope here. | 390 // the partially-created frame drops out of scope here. |
| 381 DLOG(ERROR) << "Failed duplicating a dmabuf fd"; | 391 DLOG(ERROR) << "Failed duplicating a dmabuf fd"; |
| 382 return NULL; | 392 return NULL; |
| 383 } | 393 } |
| 384 | 394 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 414 format = Format::NV12; | 424 format = Format::NV12; |
| 415 } else { | 425 } else { |
| 416 DLOG(ERROR) << "CVPixelBuffer format not supported: " << cv_format; | 426 DLOG(ERROR) << "CVPixelBuffer format not supported: " << cv_format; |
| 417 return NULL; | 427 return NULL; |
| 418 } | 428 } |
| 419 | 429 |
| 420 const gfx::Size coded_size(CVImageBufferGetEncodedSize(cv_pixel_buffer)); | 430 const gfx::Size coded_size(CVImageBufferGetEncodedSize(cv_pixel_buffer)); |
| 421 const gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer)); | 431 const gfx::Rect visible_rect(CVImageBufferGetCleanRect(cv_pixel_buffer)); |
| 422 const gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer)); | 432 const gfx::Size natural_size(CVImageBufferGetDisplaySize(cv_pixel_buffer)); |
| 423 | 433 |
| 424 if (!IsValidConfig(format, coded_size, visible_rect, natural_size)) | 434 if (!IsValidConfig(format, TEXTURE_NONE, coded_size, visible_rect, |
| 435 natural_size)) | |
| 425 return NULL; | 436 return NULL; |
| 426 | 437 |
| 438 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; | |
| 427 scoped_refptr<VideoFrame> frame( | 439 scoped_refptr<VideoFrame> frame( |
| 428 new VideoFrame(format, | 440 new VideoFrame(format, new_coded_size, visible_rect, natural_size, |
| 429 coded_size, | 441 mailbox_holders, TEXTURE_NONE, timestamp, false)); |
| 430 visible_rect, | |
| 431 natural_size, | |
| 432 scoped_ptr<gpu::MailboxHolder>(), | |
| 433 timestamp, | |
| 434 false)); | |
| 435 | 442 |
| 436 frame->cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN); | 443 frame->cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN); |
| 437 return frame; | 444 return frame; |
| 438 } | 445 } |
| 439 #endif | 446 #endif |
| 440 | 447 |
| 441 // static | 448 // static |
| 442 scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( | 449 scoped_refptr<VideoFrame> VideoFrame::WrapVideoFrame( |
| 443 const scoped_refptr<VideoFrame>& frame, | 450 const scoped_refptr<VideoFrame>& frame, |
| 444 const gfx::Rect& visible_rect, | 451 const gfx::Rect& visible_rect, |
| 445 const gfx::Size& natural_size, | 452 const gfx::Size& natural_size, |
| 446 const base::Closure& no_longer_needed_cb) { | 453 const base::Closure& no_longer_needed_cb) { |
| 447 // NATIVE_TEXTURE frames need mailbox info propagated, and there's no support | 454 // NATIVE_TEXTURE frames need mailbox info propagated, and there's no support |
| 448 // for that here yet, see http://crbug/362521. | 455 // for that here yet, see http://crbug/362521. |
| 449 CHECK_NE(frame->format(), NATIVE_TEXTURE); | 456 CHECK_NE(frame->format(), NATIVE_TEXTURE); |
| 450 | 457 |
| 451 DCHECK(frame->visible_rect().Contains(visible_rect)); | 458 DCHECK(frame->visible_rect().Contains(visible_rect)); |
| 459 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; | |
| 452 scoped_refptr<VideoFrame> wrapped_frame( | 460 scoped_refptr<VideoFrame> wrapped_frame( |
| 453 new VideoFrame(frame->format(), | 461 new VideoFrame(frame->format(), frame->coded_size(), visible_rect, |
| 454 frame->coded_size(), | 462 natural_size, mailbox_holders, TEXTURE_NONE, |
| 455 visible_rect, | 463 frame->timestamp(), frame->end_of_stream())); |
| 456 natural_size, | |
| 457 scoped_ptr<gpu::MailboxHolder>(), | |
| 458 frame->timestamp(), | |
| 459 frame->end_of_stream())); | |
| 460 | 464 |
| 461 for (size_t i = 0; i < NumPlanes(frame->format()); ++i) { | 465 for (size_t i = 0; i < NumPlanes(frame->format()); ++i) { |
| 462 wrapped_frame->strides_[i] = frame->stride(i); | 466 wrapped_frame->strides_[i] = frame->stride(i); |
| 463 wrapped_frame->data_[i] = frame->data(i); | 467 wrapped_frame->data_[i] = frame->data(i); |
| 464 } | 468 } |
| 465 | 469 |
| 466 wrapped_frame->no_longer_needed_cb_ = no_longer_needed_cb; | 470 wrapped_frame->no_longer_needed_cb_ = no_longer_needed_cb; |
| 467 return wrapped_frame; | 471 return wrapped_frame; |
| 468 } | 472 } |
| 469 | 473 |
| 470 // static | 474 // static |
| 471 scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() { | 475 scoped_refptr<VideoFrame> VideoFrame::CreateEOSFrame() { |
| 472 return new VideoFrame(VideoFrame::UNKNOWN, | 476 gpu::MailboxHolder mailbox_holders[kMaxPlanes]; |
| 473 gfx::Size(), | 477 return new VideoFrame(VideoFrame::UNKNOWN, gfx::Size(), gfx::Rect(), |
| 474 gfx::Rect(), | 478 gfx::Size(), mailbox_holders, TEXTURE_NONE, |
| 475 gfx::Size(), | 479 kNoTimestamp(), true); |
| 476 scoped_ptr<gpu::MailboxHolder>(), | |
| 477 kNoTimestamp(), | |
| 478 true); | |
| 479 } | 480 } |
| 480 | 481 |
| 481 // static | 482 // static |
| 482 scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame( | 483 scoped_refptr<VideoFrame> VideoFrame::CreateColorFrame( |
| 483 const gfx::Size& size, | 484 const gfx::Size& size, |
| 484 uint8 y, uint8 u, uint8 v, | 485 uint8 y, uint8 u, uint8 v, |
| 485 base::TimeDelta timestamp) { | 486 base::TimeDelta timestamp) { |
| 486 scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( | 487 scoped_refptr<VideoFrame> frame = VideoFrame::CreateFrame( |
| 487 VideoFrame::YV12, size, gfx::Rect(size), size, timestamp); | 488 VideoFrame::YV12, size, gfx::Rect(size), size, timestamp); |
| 488 FillYUV(frame.get(), y, u, v); | 489 FillYUV(frame.get(), y, u, v); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 514 // This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not | 515 // This block and other blocks wrapped around #if defined(VIDEO_HOLE) is not |
| 515 // maintained by the general compositor team. Please contact the following | 516 // maintained by the general compositor team. Please contact the following |
| 516 // people instead: | 517 // people instead: |
| 517 // | 518 // |
| 518 // wonsik@chromium.org | 519 // wonsik@chromium.org |
| 519 // ycheo@chromium.org | 520 // ycheo@chromium.org |
| 520 | 521 |
| 521 // static | 522 // static |
| 522 scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( | 523 scoped_refptr<VideoFrame> VideoFrame::CreateHoleFrame( |
| 523 const gfx::Size& size) { | 524 const gfx::Size& size) { |
| 524 DCHECK(IsValidConfig(VideoFrame::HOLE, size, gfx::Rect(size), size)); | 525 DCHECK(IsValidConfig(VideoFrame::HOLE, TEXTURE_NONE, size, gfx::Rect(size), |
| 525 scoped_refptr<VideoFrame> frame( | 526 size)); |
| 526 new VideoFrame(VideoFrame::HOLE, | 527 scoped_refptr<VideoFrame> frame(new VideoFrame(VideoFrame::HOLE, size, |
| 527 size, | 528 gfx::Rect(size), size, |
| 528 gfx::Rect(size), | 529 nullptr, // mailbox holders |
| 529 size, | 530 base::TimeDelta(), false)); |
| 530 scoped_ptr<gpu::MailboxHolder>(), | |
| 531 base::TimeDelta(), | |
| 532 false)); | |
| 533 return frame; | 531 return frame; |
| 534 } | 532 } |
| 535 #endif // defined(VIDEO_HOLE) | 533 #endif // defined(VIDEO_HOLE) |
| 536 | 534 |
| 537 // static | 535 // static |
| 538 size_t VideoFrame::NumPlanes(Format format) { | 536 size_t VideoFrame::NumPlanes(Format format) { |
| 539 switch (format) { | 537 switch (format) { |
| 540 case VideoFrame::NATIVE_TEXTURE: | 538 case VideoFrame::NATIVE_TEXTURE: |
| 541 #if defined(VIDEO_HOLE) | 539 #if defined(VIDEO_HOLE) |
| 542 case VideoFrame::HOLE: | 540 case VideoFrame::HOLE: |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 555 return 3; | 553 return 3; |
| 556 case VideoFrame::YV12A: | 554 case VideoFrame::YV12A: |
| 557 return 4; | 555 return 4; |
| 558 case VideoFrame::UNKNOWN: | 556 case VideoFrame::UNKNOWN: |
| 559 break; | 557 break; |
| 560 } | 558 } |
| 561 NOTREACHED() << "Unsupported video frame format: " << format; | 559 NOTREACHED() << "Unsupported video frame format: " << format; |
| 562 return 0; | 560 return 0; |
| 563 } | 561 } |
| 564 | 562 |
| 563 // static | |
| 564 size_t VideoFrame::NumTextures(TextureFormat texture_format) { | |
| 565 switch (texture_format) { | |
| 566 case TEXTURE_RGBA: | |
| 567 return 1; | |
| 568 case TEXTURE_YUV_R8R8R8: | |
| 569 return 3; | |
| 570 case TEXTURE_NONE: | |
| 571 NOTREACHED(); | |
| 572 return 0; | |
| 573 } | |
| 574 | |
| 575 NOTREACHED(); | |
| 576 return 0; | |
| 577 } | |
| 565 | 578 |
| 566 // static | 579 // static |
| 567 size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { | 580 size_t VideoFrame::AllocationSize(Format format, const gfx::Size& coded_size) { |
| 568 size_t total = 0; | 581 size_t total = 0; |
| 569 for (size_t i = 0; i < NumPlanes(format); ++i) | 582 for (size_t i = 0; i < NumPlanes(format); ++i) |
| 570 total += PlaneAllocationSize(format, i, coded_size); | 583 total += PlaneAllocationSize(format, i, coded_size); |
| 571 return total; | 584 return total; |
| 572 } | 585 } |
| 573 | 586 |
| 574 // static | 587 // static |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 for (size_t plane = 0; plane < VideoFrame::NumPlanes(format_); ++plane) | 670 for (size_t plane = 0; plane < VideoFrame::NumPlanes(format_); ++plane) |
| 658 data_[plane] = data + offset[plane]; | 671 data_[plane] = data + offset[plane]; |
| 659 | 672 |
| 660 no_longer_needed_cb_ = base::Bind(&ReleaseData, data); | 673 no_longer_needed_cb_ = base::Bind(&ReleaseData, data); |
| 661 } | 674 } |
| 662 | 675 |
| 663 VideoFrame::VideoFrame(VideoFrame::Format format, | 676 VideoFrame::VideoFrame(VideoFrame::Format format, |
| 664 const gfx::Size& coded_size, | 677 const gfx::Size& coded_size, |
| 665 const gfx::Rect& visible_rect, | 678 const gfx::Rect& visible_rect, |
| 666 const gfx::Size& natural_size, | 679 const gfx::Size& natural_size, |
| 667 scoped_ptr<gpu::MailboxHolder> mailbox_holder, | 680 const gpu::MailboxHolder mailbox_holders[kMaxPlanes], |
| 681 VideoFrame::TextureFormat texture_format, | |
| 668 base::TimeDelta timestamp, | 682 base::TimeDelta timestamp, |
| 669 bool end_of_stream) | 683 bool end_of_stream) |
| 670 : format_(format), | 684 : format_(format), |
| 685 texture_format_(texture_format), | |
| 671 coded_size_(coded_size), | 686 coded_size_(coded_size), |
| 672 visible_rect_(visible_rect), | 687 visible_rect_(visible_rect), |
| 673 natural_size_(natural_size), | 688 natural_size_(natural_size), |
| 674 mailbox_holder_(mailbox_holder.Pass()), | |
| 675 shared_memory_handle_(base::SharedMemory::NULLHandle()), | 689 shared_memory_handle_(base::SharedMemory::NULLHandle()), |
| 676 shared_memory_offset_(0), | 690 shared_memory_offset_(0), |
| 677 timestamp_(timestamp), | 691 timestamp_(timestamp), |
| 678 release_sync_point_(0), | 692 release_sync_point_(0), |
| 679 end_of_stream_(end_of_stream), | 693 end_of_stream_(end_of_stream), |
| 680 allow_overlay_(false) { | 694 allow_overlay_(false) { |
| 681 DCHECK(IsValidConfig(format_, coded_size_, visible_rect_, natural_size_)); | 695 DCHECK(IsValidConfig(format_, texture_format_, coded_size_, visible_rect_, |
| 682 | 696 natural_size_)); |
| 697 memcpy(&mailbox_holders_, mailbox_holders, sizeof(mailbox_holders_)); | |
| 683 memset(&strides_, 0, sizeof(strides_)); | 698 memset(&strides_, 0, sizeof(strides_)); |
| 684 memset(&data_, 0, sizeof(data_)); | 699 memset(&data_, 0, sizeof(data_)); |
| 685 } | 700 } |
| 686 | 701 |
| 687 VideoFrame::~VideoFrame() { | 702 VideoFrame::~VideoFrame() { |
| 688 if (!mailbox_holder_release_cb_.is_null()) { | 703 if (!mailbox_holders_release_cb_.is_null()) { |
| 689 uint32 release_sync_point; | 704 uint32 release_sync_point; |
| 690 { | 705 { |
| 691 // To ensure that changes to |release_sync_point_| are visible on this | 706 // To ensure that changes to |release_sync_point_| are visible on this |
| 692 // thread (imply a memory barrier). | 707 // thread (imply a memory barrier). |
| 693 base::AutoLock locker(release_sync_point_lock_); | 708 base::AutoLock locker(release_sync_point_lock_); |
| 694 release_sync_point = release_sync_point_; | 709 release_sync_point = release_sync_point_; |
| 695 } | 710 } |
| 696 base::ResetAndReturn(&mailbox_holder_release_cb_).Run(release_sync_point); | 711 base::ResetAndReturn(&mailbox_holders_release_cb_).Run(release_sync_point); |
| 697 } | 712 } |
| 698 if (!no_longer_needed_cb_.is_null()) | 713 if (!no_longer_needed_cb_.is_null()) |
| 699 base::ResetAndReturn(&no_longer_needed_cb_).Run(); | 714 base::ResetAndReturn(&no_longer_needed_cb_).Run(); |
| 700 } | 715 } |
| 701 | 716 |
| 702 // static | 717 // static |
| 703 bool VideoFrame::IsValidPlane(size_t plane, VideoFrame::Format format) { | 718 bool VideoFrame::IsValidPlane(size_t plane, VideoFrame::Format format) { |
| 704 return (plane < NumPlanes(format)); | 719 return (plane < NumPlanes(format)); |
| 705 } | 720 } |
| 706 | 721 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 stride(plane) * (offset.y() / subsample.height()) + // Row offset. | 779 stride(plane) * (offset.y() / subsample.height()) + // Row offset. |
| 765 BytesPerElement(format_, plane) * // Column offset. | 780 BytesPerElement(format_, plane) * // Column offset. |
| 766 (offset.x() / subsample.width()); | 781 (offset.x() / subsample.width()); |
| 767 } | 782 } |
| 768 | 783 |
| 769 uint8* VideoFrame::visible_data(size_t plane) { | 784 uint8* VideoFrame::visible_data(size_t plane) { |
| 770 return const_cast<uint8*>( | 785 return const_cast<uint8*>( |
| 771 static_cast<const VideoFrame*>(this)->visible_data(plane)); | 786 static_cast<const VideoFrame*>(this)->visible_data(plane)); |
| 772 } | 787 } |
| 773 | 788 |
| 774 const gpu::MailboxHolder* VideoFrame::mailbox_holder() const { | 789 const gpu::MailboxHolder& VideoFrame::mailbox_holder(size_t texture) const { |
| 775 DCHECK_EQ(format_, NATIVE_TEXTURE); | 790 DCHECK_EQ(format_, NATIVE_TEXTURE); |
| 776 return mailbox_holder_.get(); | 791 DCHECK_LT(texture, NumTextures(texture_format_)); |
| 792 return mailbox_holders_[texture]; | |
| 777 } | 793 } |
| 778 | 794 |
| 779 base::SharedMemoryHandle VideoFrame::shared_memory_handle() const { | 795 base::SharedMemoryHandle VideoFrame::shared_memory_handle() const { |
| 780 return shared_memory_handle_; | 796 return shared_memory_handle_; |
| 781 } | 797 } |
| 782 | 798 |
| 783 size_t VideoFrame::shared_memory_offset() const { | 799 size_t VideoFrame::shared_memory_offset() const { |
| 784 return shared_memory_offset_; | 800 return shared_memory_offset_; |
| 785 } | 801 } |
| 786 | 802 |
| 787 void VideoFrame::UpdateReleaseSyncPoint(SyncPointClient* client) { | 803 void VideoFrame::UpdateReleaseSyncPoint(SyncPointClient* client) { |
| 788 DCHECK_EQ(format_, NATIVE_TEXTURE); | 804 DCHECK_EQ(format_, NATIVE_TEXTURE); |
| 789 base::AutoLock locker(release_sync_point_lock_); | 805 base::AutoLock locker(release_sync_point_lock_); |
| 790 // Must wait on the previous sync point before inserting a new sync point so | 806 // Must wait on the previous sync point before inserting a new sync point so |
| 791 // that |mailbox_holder_release_cb_| guarantees the previous sync point | 807 // that |mailbox_holders_release_cb_| guarantees the previous sync point |
| 792 // occurred when it waits on |release_sync_point_|. | 808 // occurred when it waits on |release_sync_point_|. |
| 793 if (release_sync_point_) | 809 if (release_sync_point_) |
| 794 client->WaitSyncPoint(release_sync_point_); | 810 client->WaitSyncPoint(release_sync_point_); |
| 795 release_sync_point_ = client->InsertSyncPoint(); | 811 release_sync_point_ = client->InsertSyncPoint(); |
| 796 } | 812 } |
| 797 | 813 |
| 798 #if defined(OS_POSIX) | 814 #if defined(OS_POSIX) |
| 799 int VideoFrame::dmabuf_fd(size_t plane) const { | 815 int VideoFrame::dmabuf_fd(size_t plane) const { |
| 800 return dmabuf_fds_[plane].get(); | 816 return dmabuf_fds_[plane].get(); |
| 801 } | 817 } |
| 802 #endif | 818 #endif |
| 803 | 819 |
| 804 #if defined(OS_MACOSX) | 820 #if defined(OS_MACOSX) |
| 805 CVPixelBufferRef VideoFrame::cv_pixel_buffer() const { | 821 CVPixelBufferRef VideoFrame::cv_pixel_buffer() const { |
| 806 return cv_pixel_buffer_.get(); | 822 return cv_pixel_buffer_.get(); |
| 807 } | 823 } |
| 808 #endif | 824 #endif |
| 809 | 825 |
| 810 void VideoFrame::HashFrameForTesting(base::MD5Context* context) { | 826 void VideoFrame::HashFrameForTesting(base::MD5Context* context) { |
| 811 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) { | 827 for (size_t plane = 0; plane < NumPlanes(format_); ++plane) { |
| 812 for (int row = 0; row < rows(plane); ++row) { | 828 for (int row = 0; row < rows(plane); ++row) { |
| 813 base::MD5Update(context, base::StringPiece( | 829 base::MD5Update(context, base::StringPiece( |
| 814 reinterpret_cast<char*>(data(plane) + stride(plane) * row), | 830 reinterpret_cast<char*>(data(plane) + stride(plane) * row), |
| 815 row_bytes(plane))); | 831 row_bytes(plane))); |
| 816 } | 832 } |
| 817 } | 833 } |
| 818 } | 834 } |
| 819 | 835 |
| 820 } // namespace media | 836 } // namespace media |
| OLD | NEW |