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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 int num_surfaces, | 69 int num_surfaces, |
70 VASurfaceID *surfaces); | 70 VASurfaceID *surfaces); |
71 typedef VAStatus (*VaapiCreateSurfaces8)(VADisplay dpy, | 71 typedef VAStatus (*VaapiCreateSurfaces8)(VADisplay dpy, |
72 unsigned int format, | 72 unsigned int format, |
73 unsigned int width, | 73 unsigned int width, |
74 unsigned int height, | 74 unsigned int height, |
75 VASurfaceID *surfaces, | 75 VASurfaceID *surfaces, |
76 unsigned int num_surfaces, | 76 unsigned int num_surfaces, |
77 VASurfaceAttrib *attrib_list, | 77 VASurfaceAttrib *attrib_list, |
78 unsigned int num_attribs); | 78 unsigned int num_attribs); |
79 typedef VAStatus (*VaapiDeriveImage)(VADisplay dpy, | |
80 VASurfaceID surface, | |
81 VAImage* image); | |
79 typedef VAStatus (*VaapiDestroyBuffer)(VADisplay dpy, VABufferID buffer_id); | 82 typedef VAStatus (*VaapiDestroyBuffer)(VADisplay dpy, VABufferID buffer_id); |
80 typedef VAStatus (*VaapiDestroyConfig)(VADisplay dpy, VAConfigID config_id); | 83 typedef VAStatus (*VaapiDestroyConfig)(VADisplay dpy, VAConfigID config_id); |
81 typedef VAStatus (*VaapiDestroyContext)(VADisplay dpy, VAContextID context); | 84 typedef VAStatus (*VaapiDestroyContext)(VADisplay dpy, VAContextID context); |
85 typedef VAStatus (*VaapiDestroyImage)(VADisplay dpy, VAImageID image); | |
82 typedef VAStatus (*VaapiDestroySurfaces)(VADisplay dpy, | 86 typedef VAStatus (*VaapiDestroySurfaces)(VADisplay dpy, |
83 VASurfaceID *surfaces, | 87 VASurfaceID *surfaces, |
84 int num_surfaces); | 88 int num_surfaces); |
85 typedef int (*VaapiDisplayIsValid)(VADisplay dpy); | 89 typedef int (*VaapiDisplayIsValid)(VADisplay dpy); |
86 typedef VAStatus (*VaapiEndPicture)(VADisplay dpy, VAContextID context); | 90 typedef VAStatus (*VaapiEndPicture)(VADisplay dpy, VAContextID context); |
87 typedef const char* (*VaapiErrorStr)(VAStatus error_status); | 91 typedef const char* (*VaapiErrorStr)(VAStatus error_status); |
88 typedef VAStatus (*VaapiGetConfigAttributes)(VADisplay dpy, | 92 typedef VAStatus (*VaapiGetConfigAttributes)(VADisplay dpy, |
89 VAProfile profile, | 93 VAProfile profile, |
90 VAEntrypoint entrypoint, | 94 VAEntrypoint entrypoint, |
91 VAConfigAttrib *attrib_list, | 95 VAConfigAttrib *attrib_list, |
92 int num_attribs); | 96 int num_attribs); |
93 typedef VADisplay (*VaapiGetDisplay)(Display *dpy); | 97 typedef VADisplay (*VaapiGetDisplay)(Display *dpy); |
94 typedef VAStatus (*VaapiInitialize)(VADisplay dpy, | 98 typedef VAStatus (*VaapiInitialize)(VADisplay dpy, |
95 int *major_version, | 99 int *major_version, |
96 int *minor_version); | 100 int *minor_version); |
101 typedef VAStatus (*VaapiMapBuffer)(VADisplay dpy, | |
102 VABufferID buf_id, | |
103 void** pbuf); | |
97 typedef VAStatus (*VaapiPutSurface)(VADisplay dpy, | 104 typedef VAStatus (*VaapiPutSurface)(VADisplay dpy, |
98 VASurfaceID surface, | 105 VASurfaceID surface, |
99 Drawable draw, | 106 Drawable draw, |
100 short srcx, | 107 short srcx, |
101 short srcy, | 108 short srcy, |
102 unsigned short srcw, | 109 unsigned short srcw, |
103 unsigned short srch, | 110 unsigned short srch, |
104 short destx, | 111 short destx, |
105 short desty, | 112 short desty, |
106 unsigned short destw, | 113 unsigned short destw, |
107 unsigned short desth, | 114 unsigned short desth, |
108 VARectangle *cliprects, | 115 VARectangle *cliprects, |
109 unsigned int number_cliprects, | 116 unsigned int number_cliprects, |
110 unsigned int flags); | 117 unsigned int flags); |
111 typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy, | 118 typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy, |
112 VAContextID context, | 119 VAContextID context, |
113 VABufferID *buffers, | 120 VABufferID *buffers, |
114 int num_buffers); | 121 int num_buffers); |
115 typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); | 122 typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); |
116 typedef VAStatus (*VaapiTerminate)(VADisplay dpy); | 123 typedef VAStatus (*VaapiTerminate)(VADisplay dpy); |
124 typedef VAStatus (*VaapiUnmapBuffer)(VADisplay dpy, VABufferID buf_id); | |
117 | 125 |
118 #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL | 126 #define VAAPI_SYM(name, handle) Vaapi##name VAAPI_##name = NULL |
119 | 127 |
120 VAAPI_SYM(BeginPicture, vaapi_handle); | 128 VAAPI_SYM(BeginPicture, vaapi_handle); |
121 VAAPI_SYM(CreateBuffer, vaapi_handle); | 129 VAAPI_SYM(CreateBuffer, vaapi_handle); |
122 VAAPI_SYM(CreateConfig, vaapi_handle); | 130 VAAPI_SYM(CreateConfig, vaapi_handle); |
123 VAAPI_SYM(CreateContext, vaapi_handle); | 131 VAAPI_SYM(CreateContext, vaapi_handle); |
124 VAAPI_SYM(CreateSurfaces, vaapi_handle); | 132 VAAPI_SYM(CreateSurfaces, vaapi_handle); |
133 VAAPI_SYM(DeriveImage, vaapi_handle); | |
125 VAAPI_SYM(DestroyBuffer, vaapi_handle); | 134 VAAPI_SYM(DestroyBuffer, vaapi_handle); |
126 VAAPI_SYM(DestroyConfig, vaapi_handle); | 135 VAAPI_SYM(DestroyConfig, vaapi_handle); |
127 VAAPI_SYM(DestroyContext, vaapi_handle); | 136 VAAPI_SYM(DestroyContext, vaapi_handle); |
137 VAAPI_SYM(DestroyImage, vaapi_handle); | |
128 VAAPI_SYM(DestroySurfaces, vaapi_handle); | 138 VAAPI_SYM(DestroySurfaces, vaapi_handle); |
129 VAAPI_SYM(DisplayIsValid, vaapi_handle); | 139 VAAPI_SYM(DisplayIsValid, vaapi_handle); |
130 VAAPI_SYM(EndPicture, vaapi_handle); | 140 VAAPI_SYM(EndPicture, vaapi_handle); |
131 VAAPI_SYM(ErrorStr, vaapi_handle); | 141 VAAPI_SYM(ErrorStr, vaapi_handle); |
132 VAAPI_SYM(GetConfigAttributes, vaapi_handle); | 142 VAAPI_SYM(GetConfigAttributes, vaapi_handle); |
133 VAAPI_SYM(GetDisplay, vaapi_x11_handle); | 143 VAAPI_SYM(GetDisplay, vaapi_x11_handle); |
134 VAAPI_SYM(Initialize, vaapi_handle); | 144 VAAPI_SYM(Initialize, vaapi_handle); |
145 VAAPI_SYM(MapBuffer, vaapi_handle); | |
135 VAAPI_SYM(PutSurface, vaapi_x11_handle); | 146 VAAPI_SYM(PutSurface, vaapi_x11_handle); |
136 VAAPI_SYM(RenderPicture, vaapi_handle); | 147 VAAPI_SYM(RenderPicture, vaapi_handle); |
137 VAAPI_SYM(SyncSurface, vaapi_x11_handle); | 148 VAAPI_SYM(SyncSurface, vaapi_x11_handle); |
138 VAAPI_SYM(Terminate, vaapi_handle); | 149 VAAPI_SYM(Terminate, vaapi_handle); |
150 VAAPI_SYM(UnmapBuffer, vaapi_handle); | |
139 | 151 |
140 #undef VAAPI_SYM | 152 #undef VAAPI_SYM |
141 | 153 |
142 // Maps Profile enum values to VaProfile values. | 154 // Maps Profile enum values to VaProfile values. |
143 static bool ProfileToVAProfile(media::VideoCodecProfile profile, | 155 static bool ProfileToVAProfile(media::VideoCodecProfile profile, |
144 VAProfile* va_profile) { | 156 VAProfile* va_profile) { |
145 switch (profile) { | 157 switch (profile) { |
146 case media::H264PROFILE_BASELINE: | 158 case media::H264PROFILE_BASELINE: |
147 *va_profile = VAProfileH264Baseline; | 159 *va_profile = VAProfileH264Baseline; |
148 break; | 160 break; |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 va_surface_id, | 438 va_surface_id, |
427 x_pixmap, | 439 x_pixmap, |
428 0, 0, dest_size.width(), dest_size.height(), | 440 0, 0, dest_size.width(), dest_size.height(), |
429 0, 0, dest_size.width(), dest_size.height(), | 441 0, 0, dest_size.width(), dest_size.height(), |
430 NULL, 0, 0); | 442 NULL, 0, 0); |
431 VA_SUCCESS_OR_RETURN(va_res, "Failed putting decode surface to pixmap", | 443 VA_SUCCESS_OR_RETURN(va_res, "Failed putting decode surface to pixmap", |
432 false); | 444 false); |
433 return true; | 445 return true; |
434 } | 446 } |
435 | 447 |
448 static scoped_refptr<media::VideoFrame> CopyNV12ToI420(VAImage* image, | |
449 void* mem) { | |
450 DVLOG(1) << "CopyNV12ToI420 width=" << image->width | |
451 << ", height=" << image->height; | |
452 | |
453 const gfx::Size coded_size(image->width, image->height); | |
454 const gfx::Rect visible_rect(image->width, image->height); | |
455 const gfx::Size natural_size(image->width, image->height); | |
456 | |
457 scoped_refptr<media::VideoFrame> frame = | |
458 media::VideoFrame::CreateFrame(media::VideoFrame::I420, | |
459 coded_size, | |
460 visible_rect, | |
461 natural_size, | |
462 base::TimeDelta()); | |
463 | |
464 uint8_t* mem_byte_ptr = static_cast<uint8_t*>(mem); | |
465 uint8_t* srcY = mem_byte_ptr + image->offsets[0]; | |
466 uint8_t* srcU = mem_byte_ptr + image->offsets[1]; | |
467 uint8_t* srcV = srcU + 1; | |
468 | |
469 uint8_t* dstY = frame->data(media::VideoFrame::kYPlane); | |
470 uint8_t* dstU = frame->data(media::VideoFrame::kUPlane); | |
471 uint8_t* dstV = frame->data(media::VideoFrame::kVPlane); | |
472 | |
473 for (int i = 0; i < image->height; i++) { | |
474 memcpy(dstY, srcY, image->width); | |
475 srcY += image->pitches[0]; | |
476 dstY += frame->stride(media::VideoFrame::kYPlane); | |
477 | |
478 // U/V components are subsampled, so there is only one U/V row for every two | |
479 // Y rows. | |
480 if ((i & 1) == 1) | |
481 continue; | |
482 for (int j = 0, k = 0; j < image->width; j += 2, k++) { | |
483 dstU[k] = srcU[j]; | |
484 dstV[k] = srcV[j]; | |
485 } | |
486 srcU += image->pitches[1]; | |
487 srcV += image->pitches[1]; | |
488 dstU += frame->stride(media::VideoFrame::kUPlane); | |
489 dstV += frame->stride(media::VideoFrame::kVPlane); | |
490 } | |
491 | |
492 return frame; | |
493 } | |
494 | |
495 scoped_refptr<media::VideoFrame> VaapiWrapper::VideoFrameFromVASurface( | |
496 VASurfaceID va_surface_id) { | |
497 base::AutoLock auto_lock(va_lock_); | |
498 | |
499 VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id); | |
500 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", NULL); | |
501 | |
502 VAImage image; | |
503 void* mem = NULL; | |
504 scoped_refptr<media::VideoFrame> frame; | |
505 | |
506 // Derive a VAImage from the VASurface | |
507 va_res = VAAPI_DeriveImage(va_display_, va_surface_id, &image); | |
508 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed"); | |
509 if (va_res != VA_STATUS_SUCCESS) | |
510 return frame; | |
511 | |
512 // Check if the format is NV12 | |
513 if (image.format.fourcc == VA_FOURCC_NV12) { | |
514 // Map the buffer | |
515 va_res = VAAPI_MapBuffer(va_display_, image.buf, &mem); | |
516 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed"); | |
517 if (va_res == VA_STATUS_SUCCESS) { | |
518 frame = CopyNV12ToI420(&image, mem); | |
519 // Unmap the buffer | |
520 VAAPI_UnmapBuffer(va_display_, image.buf); | |
521 } | |
522 } else { | |
523 DVLOG(ERROR) << "unexpected image format: " << image.format.fourcc; | |
Pawel Osciak
2013/12/03 08:52:06
The convention is to use numeric constants for *VL
chihchung
2013/12/03 10:57:40
Moved to test and changed to LOG.
| |
524 } | |
525 VAAPI_DestroyImage(va_display_, image.image_id); | |
526 | |
527 return frame; | |
528 } | |
529 | |
436 // static | 530 // static |
437 bool VaapiWrapper::PostSandboxInitialization() { | 531 bool VaapiWrapper::PostSandboxInitialization() { |
438 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); | 532 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); |
439 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); | 533 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); |
440 | 534 |
441 if (!vaapi_handle || !vaapi_x11_handle) | 535 if (!vaapi_handle || !vaapi_x11_handle) |
442 return false; | 536 return false; |
443 #define VAAPI_DLSYM_OR_RETURN_ON_ERROR(name, handle) \ | 537 #define VAAPI_DLSYM_OR_RETURN_ON_ERROR(name, handle) \ |
444 do { \ | 538 do { \ |
445 VAAPI_##name = reinterpret_cast<Vaapi##name>(dlsym((handle), "va"#name)); \ | 539 VAAPI_##name = reinterpret_cast<Vaapi##name>(dlsym((handle), "va"#name)); \ |
446 if (VAAPI_##name == NULL) { \ | 540 if (VAAPI_##name == NULL) { \ |
447 DVLOG(1) << "Failed to dlsym va"#name; \ | 541 DVLOG(1) << "Failed to dlsym va"#name; \ |
448 return false; \ | 542 return false; \ |
449 } \ | 543 } \ |
450 } while (0) | 544 } while (0) |
451 | 545 |
452 VAAPI_DLSYM_OR_RETURN_ON_ERROR(BeginPicture, vaapi_handle); | 546 VAAPI_DLSYM_OR_RETURN_ON_ERROR(BeginPicture, vaapi_handle); |
453 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateBuffer, vaapi_handle); | 547 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateBuffer, vaapi_handle); |
454 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateConfig, vaapi_handle); | 548 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateConfig, vaapi_handle); |
455 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateContext, vaapi_handle); | 549 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateContext, vaapi_handle); |
456 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateSurfaces, vaapi_handle); | 550 VAAPI_DLSYM_OR_RETURN_ON_ERROR(CreateSurfaces, vaapi_handle); |
551 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DeriveImage, vaapi_handle); | |
457 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyBuffer, vaapi_handle); | 552 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyBuffer, vaapi_handle); |
458 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyConfig, vaapi_handle); | 553 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyConfig, vaapi_handle); |
459 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyContext, vaapi_handle); | 554 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyContext, vaapi_handle); |
555 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyImage, vaapi_handle); | |
460 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroySurfaces, vaapi_handle); | 556 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroySurfaces, vaapi_handle); |
461 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); | 557 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); |
462 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); | 558 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); |
463 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); | 559 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); |
464 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); | 560 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); |
465 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); | 561 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); |
466 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); | 562 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); |
563 VAAPI_DLSYM_OR_RETURN_ON_ERROR(MapBuffer, vaapi_handle); | |
467 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); | 564 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); |
468 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); | 565 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); |
469 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); | 566 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); |
470 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); | 567 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); |
568 VAAPI_DLSYM_OR_RETURN_ON_ERROR(UnmapBuffer, vaapi_handle); | |
471 #undef VAAPI_DLSYM | 569 #undef VAAPI_DLSYM |
472 | 570 |
473 return true; | 571 return true; |
474 } | 572 } |
475 | 573 |
476 } // namespace content | 574 } // namespace content |
OLD | NEW |