Chromium Code Reviews| 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 void CopyNV12ToI420(VAImage* image, | |
| 420 void* mem, | |
| 421 void** buffer, | |
| 422 size_t* size) { | |
| 423 DVLOG(1) << "CopyNV12ToI420 width=" << image->width | |
| 424 << ", height=" << image->height; | |
| 425 *size = image->width * image->height * 3 / 2; | |
|
Pawel Osciak
2013/10/20 23:53:11
There are some useful functions in VideoFrame for
chihchung
2013/10/21 09:33:05
Done.
| |
| 426 *buffer = malloc(*size); | |
| 427 uint8_t* mem_byte_ptr = (uint8_t*)mem; | |
| 428 uint8_t* buffer_byte_ptr = (uint8_t*)*buffer; | |
| 429 | |
| 430 uint8_t* srcY = mem_byte_ptr + image->offsets[0]; | |
| 431 uint8_t* srcU = mem_byte_ptr + image->offsets[1]; | |
| 432 uint8_t* srcV = srcU + 1; | |
| 433 uint8_t* dstY = buffer_byte_ptr; | |
| 434 uint8_t* dstU = buffer_byte_ptr + image->width * image->height; | |
| 435 uint8_t* dstV = dstU + image->width * image->height / 4; | |
| 436 | |
| 437 for (int i = 0; i < image->height; i++) { | |
| 438 memcpy(dstY, srcY, image->width); | |
| 439 dstY += image->width; | |
| 440 srcY += image->pitches[0]; | |
| 441 | |
| 442 if ((i & 1) == 1) continue; | |
| 443 for (int j = 0; j < image->width; j += 2) { | |
| 444 *dstU++ = srcU[j]; | |
| 445 *dstV++ = srcV[j]; | |
| 446 } | |
| 447 srcU += image->pitches[1]; | |
| 448 srcV += image->pitches[1]; | |
| 449 } | |
| 450 } | |
| 451 | |
| 452 bool VaapiWrapper::GetI420FromSurface(VASurfaceID va_surface_id, | |
| 453 void** buffer, | |
| 454 size_t* size) { | |
| 455 base::AutoLock auto_lock(va_lock_); | |
| 456 | |
| 457 VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id); | |
| 458 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", false); | |
| 459 | |
| 460 VAImage image; | |
| 461 void* mem = NULL; | |
| 462 | |
| 463 // Derive a VAImage from the VASurface | |
| 464 va_res = VAAPI_DeriveImage(va_display_, va_surface_id, &image); | |
| 465 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); | |
| 466 if (va_res != VA_STATUS_SUCCESS) | |
| 467 goto out; | |
|
Pawel Osciak
2013/10/20 23:53:11
Don't use goto.
chihchung
2013/10/21 09:33:05
Done.
| |
| 468 | |
| 469 // Check if the format is NV12 | |
| 470 if (image.format.fourcc != VA_FOURCC_NV12) { | |
| 471 LOG(ERROR) << "unexpected image format: " << image.format.fourcc; | |
| 472 goto destroy_image; | |
| 473 } | |
| 474 | |
| 475 // Map the buffer | |
| 476 va_res = VAAPI_MapBuffer(va_display_, image.buf, &mem); | |
| 477 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); | |
| 478 if (va_res != VA_STATUS_SUCCESS) | |
| 479 goto destroy_image; | |
| 480 | |
| 481 CopyNV12ToI420(&image, mem, buffer, size); | |
| 482 | |
| 483 // Unmap the buffer | |
| 484 VAAPI_UnmapBuffer(va_display_, image.buf); | |
| 485 | |
| 486 destroy_image: | |
| 487 VAAPI_DestroyImage(va_display_, image.image_id); | |
| 488 | |
| 489 out: | |
| 490 return va_res == VA_STATUS_SUCCESS; | |
| 491 } | |
| 492 | |
| 407 // static | 493 // static |
| 408 bool VaapiWrapper::pre_sandbox_init_done_ = false; | 494 bool VaapiWrapper::pre_sandbox_init_done_ = false; |
| 409 | 495 |
| 410 // static | 496 // static |
| 411 void VaapiWrapper::PreSandboxInitialization() { | 497 void VaapiWrapper::PreSandboxInitialization() { |
| 412 DCHECK(!pre_sandbox_init_done_); | 498 DCHECK(!pre_sandbox_init_done_); |
| 413 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); | 499 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); |
| 414 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); | 500 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); |
| 415 pre_sandbox_init_done_ = vaapi_handle && vaapi_x11_handle; | 501 pre_sandbox_init_done_ = vaapi_handle && vaapi_x11_handle; |
| 416 } | 502 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 440 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); | 526 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); |
| 441 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); | 527 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); |
| 442 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); | 528 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); |
| 443 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); | 529 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); |
| 444 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); | 530 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); |
| 445 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); | 531 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); |
| 446 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); | 532 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); |
| 447 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); | 533 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); |
| 448 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); | 534 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); |
| 449 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); | 535 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); |
| 536 VAAPI_DLSYM_OR_RETURN_ON_ERROR(MapBuffer, vaapi_handle); | |
| 537 VAAPI_DLSYM_OR_RETURN_ON_ERROR(UnmapBuffer, vaapi_handle); | |
| 538 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DeriveImage, vaapi_handle); | |
| 539 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyImage, vaapi_handle); | |
| 450 #undef VAAPI_DLSYM | 540 #undef VAAPI_DLSYM |
| 451 | 541 |
| 452 return true; | 542 return true; |
| 453 } | 543 } |
| 454 | 544 |
| 455 } // namespace content | 545 } // namespace content |
| OLD | NEW |