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 |