OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "content/common/gpu/media/vaapi_wrapper.h" | 9 #include "content/common/gpu/media/vaapi_wrapper.h" |
10 | 10 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 unsigned short desth, | 95 unsigned short desth, |
96 VARectangle *cliprects, | 96 VARectangle *cliprects, |
97 unsigned int number_cliprects, | 97 unsigned int number_cliprects, |
98 unsigned int flags); | 98 unsigned int flags); |
99 typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy, | 99 typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy, |
100 VAContextID context, | 100 VAContextID context, |
101 VABufferID *buffers, | 101 VABufferID *buffers, |
102 int num_buffers); | 102 int num_buffers); |
103 typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); | 103 typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); |
104 typedef VAStatus (*VaapiTerminate)(VADisplay dpy); | 104 typedef VAStatus (*VaapiTerminate)(VADisplay dpy); |
105 typedef VAStatus (*VaapiMapBuffer)(VADisplay dpy, | |
106 VABufferID buf_id, | |
107 void **pbuf); | |
108 typedef VAStatus (*VaapiUnmapBuffer)(VADisplay dpy, VABufferID buf_id); | |
109 typedef VAStatus (*VaapiDeriveImage)(VADisplay dpy, | |
110 VASurfaceID surface, | |
111 VAImage *image); | |
112 typedef VAStatus (*VaapiDestroyImage)(VADisplay dpy, VAImageID image); | |
105 | 113 |
106 #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL | 114 #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL |
107 | 115 |
108 VAAPI_SYM(BeginPicture, vaapi_handle); | 116 VAAPI_SYM(BeginPicture, vaapi_handle); |
109 VAAPI_SYM(CreateBuffer, vaapi_handle); | 117 VAAPI_SYM(CreateBuffer, vaapi_handle); |
110 VAAPI_SYM(CreateConfig, vaapi_handle); | 118 VAAPI_SYM(CreateConfig, vaapi_handle); |
111 VAAPI_SYM(CreateContext, vaapi_handle); | 119 VAAPI_SYM(CreateContext, vaapi_handle); |
112 VAAPI_SYM(CreateSurfaces, vaapi_handle); | 120 VAAPI_SYM(CreateSurfaces, vaapi_handle); |
113 VAAPI_SYM(DestroyBuffer, vaapi_handle); | 121 VAAPI_SYM(DestroyBuffer, vaapi_handle); |
114 VAAPI_SYM(DestroyConfig, vaapi_handle); | 122 VAAPI_SYM(DestroyConfig, vaapi_handle); |
115 VAAPI_SYM(DestroyContext, vaapi_handle); | 123 VAAPI_SYM(DestroyContext, vaapi_handle); |
116 VAAPI_SYM(DestroySurfaces, vaapi_handle); | 124 VAAPI_SYM(DestroySurfaces, vaapi_handle); |
117 VAAPI_SYM(DisplayIsValid, vaapi_handle); | 125 VAAPI_SYM(DisplayIsValid, vaapi_handle); |
118 VAAPI_SYM(EndPicture, vaapi_handle); | 126 VAAPI_SYM(EndPicture, vaapi_handle); |
119 VAAPI_SYM(ErrorStr, vaapi_handle); | 127 VAAPI_SYM(ErrorStr, vaapi_handle); |
120 VAAPI_SYM(GetConfigAttributes, vaapi_handle); | 128 VAAPI_SYM(GetConfigAttributes, vaapi_handle); |
121 VAAPI_SYM(GetDisplay, vaapi_x11_handle); | 129 VAAPI_SYM(GetDisplay, vaapi_x11_handle); |
122 VAAPI_SYM(Initialize, vaapi_handle); | 130 VAAPI_SYM(Initialize, vaapi_handle); |
123 VAAPI_SYM(PutSurface, vaapi_x11_handle); | 131 VAAPI_SYM(PutSurface, vaapi_x11_handle); |
124 VAAPI_SYM(RenderPicture, vaapi_handle); | 132 VAAPI_SYM(RenderPicture, vaapi_handle); |
125 VAAPI_SYM(SyncSurface, vaapi_x11_handle); | 133 VAAPI_SYM(SyncSurface, vaapi_x11_handle); |
126 VAAPI_SYM(Terminate, vaapi_handle); | 134 VAAPI_SYM(Terminate, vaapi_handle); |
135 VAAPI_SYM(MapBuffer, vaapi_handle); | |
136 VAAPI_SYM(UnmapBuffer, vaapi_handle); | |
137 VAAPI_SYM(DeriveImage, vaapi_handle); | |
138 VAAPI_SYM(DestroyImage, vaapi_handle); | |
127 | 139 |
128 #undef VAAPI_SYM | 140 #undef VAAPI_SYM |
129 | 141 |
130 // Maps Profile enum values to VaProfile values. | 142 // Maps Profile enum values to VaProfile values. |
131 static bool ProfileToVAProfile(media::VideoCodecProfile profile, | 143 static bool ProfileToVAProfile(media::VideoCodecProfile profile, |
132 VAProfile* va_profile) { | 144 VAProfile* va_profile) { |
133 switch (profile) { | 145 switch (profile) { |
134 case media::H264PROFILE_BASELINE: | 146 case media::H264PROFILE_BASELINE: |
135 *va_profile = VAProfileH264Baseline; | 147 *va_profile = VAProfileH264Baseline; |
136 break; | 148 break; |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
397 va_surface_id, | 409 va_surface_id, |
398 x_pixmap, | 410 x_pixmap, |
399 0, 0, dest_size.width(), dest_size.height(), | 411 0, 0, dest_size.width(), dest_size.height(), |
400 0, 0, dest_size.width(), dest_size.height(), | 412 0, 0, dest_size.width(), dest_size.height(), |
401 NULL, 0, 0); | 413 NULL, 0, 0); |
402 VA_SUCCESS_OR_RETURN(va_res, "Failed putting decode surface to pixmap", | 414 VA_SUCCESS_OR_RETURN(va_res, "Failed putting decode surface to pixmap", |
403 false); | 415 false); |
404 return true; | 416 return true; |
405 } | 417 } |
406 | 418 |
419 static scoped_refptr<media::VideoFrame> CopyNV12ToI420(VAImage* image, | |
420 void* mem) { | |
Pawel Osciak
2013/11/21 06:31:41
What do you think of using VideoFrame::WrapExterna
chihchung
2013/11/21 12:17:32
I don't understand this, but you said it's not a b
| |
421 DVLOG(1) << "CopyNV12ToI420 width=" << image->width | |
422 << ", height=" << image->height; | |
423 | |
424 const gfx::Size coded_size(image->width, image->height); | |
425 const gfx::Rect visible_rect(image->width, image->height); | |
426 const gfx::Size natural_size(image->width, image->height); | |
427 | |
428 scoped_refptr<media::VideoFrame> frame = | |
429 media::VideoFrame::CreateFrame(media::VideoFrame::I420, | |
430 coded_size, | |
431 visible_rect, | |
432 natural_size, | |
433 base::TimeDelta()); | |
434 | |
435 uint8_t* mem_byte_ptr = static_cast<uint8_t*>(mem); | |
436 uint8_t* srcY = mem_byte_ptr + image->offsets[0]; | |
437 uint8_t* srcU = mem_byte_ptr + image->offsets[1]; | |
438 uint8_t* srcV = srcU + 1; | |
439 | |
440 uint8_t* dstY = frame->data(media::VideoFrame::kYPlane); | |
441 uint8_t* dstU = frame->data(media::VideoFrame::kUPlane); | |
442 uint8_t* dstV = frame->data(media::VideoFrame::kVPlane); | |
443 | |
444 for (int i = 0; i < image->height; i++) { | |
445 memcpy(dstY, srcY, image->width); | |
446 srcY += image->pitches[0]; | |
447 dstY += frame->stride(media::VideoFrame::kYPlane); | |
448 | |
449 if ((i & 1) == 1) | |
450 continue; | |
451 for (int j = 0, k = 0; j < image->width; j += 2, k++) { | |
452 dstU[k] = srcU[j]; | |
453 dstV[k] = srcV[j]; | |
454 } | |
455 srcU += image->pitches[1]; | |
456 srcV += image->pitches[1]; | |
457 dstU += frame->stride(media::VideoFrame::kUPlane); | |
458 dstV += frame->stride(media::VideoFrame::kVPlane); | |
459 } | |
460 | |
461 return frame; | |
462 } | |
463 | |
464 scoped_refptr<media::VideoFrame> VaapiWrapper::GetI420FromSurface( | |
465 VASurfaceID va_surface_id) { | |
466 base::AutoLock auto_lock(va_lock_); | |
467 | |
468 VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id); | |
469 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", NULL); | |
470 | |
471 VAImage image; | |
472 void* mem = NULL; | |
473 scoped_refptr<media::VideoFrame> result; | |
474 | |
475 // Derive a VAImage from the VASurface | |
476 va_res = VAAPI_DeriveImage(va_display_, va_surface_id, &image); | |
477 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); | |
478 if (va_res == VA_STATUS_SUCCESS) { | |
479 // Check if the format is NV12 | |
480 if (image.format.fourcc == VA_FOURCC_NV12) { | |
481 // Map the buffer | |
482 va_res = VAAPI_MapBuffer(va_display_, image.buf, &mem); | |
483 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); | |
484 if (va_res == VA_STATUS_SUCCESS) { | |
485 result = CopyNV12ToI420(&image, mem); | |
486 // Unmap the buffer | |
487 VAAPI_UnmapBuffer(va_display_, image.buf); | |
488 } | |
489 } else { | |
490 LOG(ERROR) << "unexpected image format: " << image.format.fourcc; | |
491 } | |
492 VAAPI_DestroyImage(va_display_, image.image_id); | |
493 } | |
494 | |
495 return result; | |
496 } | |
497 | |
407 // static | 498 // static |
408 bool VaapiWrapper::pre_sandbox_init_done_ = false; | 499 bool VaapiWrapper::pre_sandbox_init_done_ = false; |
409 | 500 |
410 // static | 501 // static |
411 void VaapiWrapper::PreSandboxInitialization() { | 502 void VaapiWrapper::PreSandboxInitialization() { |
412 DCHECK(!pre_sandbox_init_done_); | 503 DCHECK(!pre_sandbox_init_done_); |
413 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); | 504 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); |
414 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); | 505 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); |
415 pre_sandbox_init_done_ = vaapi_handle && vaapi_x11_handle; | 506 pre_sandbox_init_done_ = vaapi_handle && vaapi_x11_handle; |
416 } | 507 } |
(...skipping 23 matching lines...) Expand all Loading... | |
440 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); | 531 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); |
441 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); | 532 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); |
442 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); | 533 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); |
443 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); | 534 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); |
444 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); | 535 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); |
445 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); | 536 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); |
446 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); | 537 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); |
447 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); | 538 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); |
448 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); | 539 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); |
449 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); | 540 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); |
541 VAAPI_DLSYM_OR_RETURN_ON_ERROR(MapBuffer, vaapi_handle); | |
542 VAAPI_DLSYM_OR_RETURN_ON_ERROR(UnmapBuffer, vaapi_handle); | |
543 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DeriveImage, vaapi_handle); | |
544 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyImage, vaapi_handle); | |
450 #undef VAAPI_DLSYM | 545 #undef VAAPI_DLSYM |
451 | 546 |
452 return true; | 547 return true; |
453 } | 548 } |
454 | 549 |
455 } // namespace content | 550 } // namespace content |
OLD | NEW |