Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: content/common/gpu/media/vaapi_wrapper.cc

Issue 27498002: Add vaapi_h264_decoder_test. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address review comments Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/common/gpu/media/vaapi_wrapper.h ('k') | content/content_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « content/common/gpu/media/vaapi_wrapper.h ('k') | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698