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

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: change to gtest and add md5 verification Created 7 years, 1 month 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
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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 unsigned short desth, 107 unsigned short desth,
108 VARectangle *cliprects, 108 VARectangle *cliprects,
109 unsigned int number_cliprects, 109 unsigned int number_cliprects,
110 unsigned int flags); 110 unsigned int flags);
111 typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy, 111 typedef VAStatus (*VaapiRenderPicture)(VADisplay dpy,
112 VAContextID context, 112 VAContextID context,
113 VABufferID *buffers, 113 VABufferID *buffers,
114 int num_buffers); 114 int num_buffers);
115 typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target); 115 typedef VAStatus (*VaapiSyncSurface)(VADisplay dpy, VASurfaceID render_target);
116 typedef VAStatus (*VaapiTerminate)(VADisplay dpy); 116 typedef VAStatus (*VaapiTerminate)(VADisplay dpy);
117 typedef VAStatus (*VaapiMapBuffer)(VADisplay dpy,
Pawel Osciak 2013/11/29 04:25:13 Please maintain lexicographical order.
chihchung 2013/11/29 14:06:30 Done.
118 VABufferID buf_id,
119 void** pbuf);
120 typedef VAStatus (*VaapiUnmapBuffer)(VADisplay dpy, VABufferID buf_id);
121 typedef VAStatus (*VaapiDeriveImage)(VADisplay dpy,
122 VASurfaceID surface,
123 VAImage* image);
124 typedef VAStatus (*VaapiDestroyImage)(VADisplay dpy, VAImageID image);
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);
125 VAAPI_SYM(DestroyBuffer, vaapi_handle); 133 VAAPI_SYM(DestroyBuffer, vaapi_handle);
126 VAAPI_SYM(DestroyConfig, vaapi_handle); 134 VAAPI_SYM(DestroyConfig, vaapi_handle);
127 VAAPI_SYM(DestroyContext, vaapi_handle); 135 VAAPI_SYM(DestroyContext, vaapi_handle);
128 VAAPI_SYM(DestroySurfaces, vaapi_handle); 136 VAAPI_SYM(DestroySurfaces, vaapi_handle);
129 VAAPI_SYM(DisplayIsValid, vaapi_handle); 137 VAAPI_SYM(DisplayIsValid, vaapi_handle);
130 VAAPI_SYM(EndPicture, vaapi_handle); 138 VAAPI_SYM(EndPicture, vaapi_handle);
131 VAAPI_SYM(ErrorStr, vaapi_handle); 139 VAAPI_SYM(ErrorStr, vaapi_handle);
132 VAAPI_SYM(GetConfigAttributes, vaapi_handle); 140 VAAPI_SYM(GetConfigAttributes, vaapi_handle);
133 VAAPI_SYM(GetDisplay, vaapi_x11_handle); 141 VAAPI_SYM(GetDisplay, vaapi_x11_handle);
134 VAAPI_SYM(Initialize, vaapi_handle); 142 VAAPI_SYM(Initialize, vaapi_handle);
135 VAAPI_SYM(PutSurface, vaapi_x11_handle); 143 VAAPI_SYM(PutSurface, vaapi_x11_handle);
136 VAAPI_SYM(RenderPicture, vaapi_handle); 144 VAAPI_SYM(RenderPicture, vaapi_handle);
137 VAAPI_SYM(SyncSurface, vaapi_x11_handle); 145 VAAPI_SYM(SyncSurface, vaapi_x11_handle);
138 VAAPI_SYM(Terminate, vaapi_handle); 146 VAAPI_SYM(Terminate, vaapi_handle);
147 VAAPI_SYM(MapBuffer, vaapi_handle);
148 VAAPI_SYM(UnmapBuffer, vaapi_handle);
149 VAAPI_SYM(DeriveImage, vaapi_handle);
150 VAAPI_SYM(DestroyImage, 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,
Pawel Osciak 2013/11/29 04:25:13 To be honest I feel now that all the conversion co
chihchung 2013/11/29 14:06:30 I prefer current code because (1) The linker shoul
Pawel Osciak 2013/12/03 08:52:06 1) We just did an interesting experiment where we
chihchung 2013/12/03 10:57:40 Done.
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,
Pawel Osciak 2013/11/29 04:25:13 Normally I'd suggest adding a VideoFrame::WrapVAIm
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 if ((i & 1) == 1)
Pawel Osciak 2013/11/29 04:25:13 It's obvious for us, but maybe add a comment why t
chihchung 2013/11/29 14:06:30 Done.
479 continue;
480 for (int j = 0, k = 0; j < image->width; j += 2, k++) {
481 dstU[k] = srcU[j];
Pawel Osciak 2013/11/29 04:25:13 Did a quick peek into vagetimage and it looks like
482 dstV[k] = srcV[j];
483 }
484 srcU += image->pitches[1];
485 srcV += image->pitches[1];
486 dstU += frame->stride(media::VideoFrame::kUPlane);
487 dstV += frame->stride(media::VideoFrame::kVPlane);
488 }
489
490 return frame;
491 }
492
493 scoped_refptr<media::VideoFrame> VaapiWrapper::VideoFrameFromVASurface(
494 VASurfaceID va_surface_id) {
495 base::AutoLock auto_lock(va_lock_);
496
497 VAStatus va_res = VAAPI_SyncSurface(va_display_, va_surface_id);
498 VA_SUCCESS_OR_RETURN(va_res, "Failed syncing surface", NULL);
499
500 VAImage image;
501 void* mem = NULL;
502 scoped_refptr<media::VideoFrame> result;
Pawel Osciak 2013/11/29 04:25:13 s/result/frame or something like that :)
chihchung 2013/11/29 14:06:30 Done.
503
504 // Derive a VAImage from the VASurface
505 va_res = VAAPI_DeriveImage(va_display_, va_surface_id, &image);
506 VA_LOG_ON_ERROR(va_res, "vaDeriveImage failed");
507 if (va_res == VA_STATUS_SUCCESS) {
Pawel Osciak 2013/11/29 04:25:13 Early return from here instead maybe to save on in
chihchung 2013/11/29 14:06:30 Done.
508 // Check if the format is NV12
509 if (image.format.fourcc == VA_FOURCC_NV12) {
510 // Map the buffer
511 va_res = VAAPI_MapBuffer(va_display_, image.buf, &mem);
512 VA_LOG_ON_ERROR(va_res, "vaMapBuffer failed");
513 if (va_res == VA_STATUS_SUCCESS) {
514 result = CopyNV12ToI420(&image, mem);
515 // Unmap the buffer
516 VAAPI_UnmapBuffer(va_display_, image.buf);
517 }
518 } else {
519 LOG(ERROR) << "unexpected image format: " << image.format.fourcc;
Pawel Osciak 2013/11/29 04:25:13 Please use DVLOG() instead so as to not pollute th
chihchung 2013/11/29 14:06:30 Done.
520 }
521 VAAPI_DestroyImage(va_display_, image.image_id);
522 }
523
524 return result;
525 }
526
436 // static 527 // static
437 bool VaapiWrapper::PostSandboxInitialization() { 528 bool VaapiWrapper::PostSandboxInitialization() {
438 vaapi_handle = dlopen("libva.so.1", RTLD_NOW); 529 vaapi_handle = dlopen("libva.so.1", RTLD_NOW);
439 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW); 530 vaapi_x11_handle = dlopen("libva-x11.so.1", RTLD_NOW);
440 531
441 if (!vaapi_handle || !vaapi_x11_handle) 532 if (!vaapi_handle || !vaapi_x11_handle)
442 return false; 533 return false;
443 #define VAAPI_DLSYM_OR_RETURN_ON_ERROR(name, handle) \ 534 #define VAAPI_DLSYM_OR_RETURN_ON_ERROR(name, handle) \
444 do { \ 535 do { \
445 VAAPI_##name = reinterpret_cast<Vaapi##name>(dlsym((handle), "va"#name)); \ 536 VAAPI_##name = reinterpret_cast<Vaapi##name>(dlsym((handle), "va"#name)); \
(...skipping 15 matching lines...) Expand all
461 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle); 552 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DisplayIsValid, vaapi_handle);
462 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle); 553 VAAPI_DLSYM_OR_RETURN_ON_ERROR(EndPicture, vaapi_handle);
463 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle); 554 VAAPI_DLSYM_OR_RETURN_ON_ERROR(ErrorStr, vaapi_handle);
464 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle); 555 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetConfigAttributes, vaapi_handle);
465 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle); 556 VAAPI_DLSYM_OR_RETURN_ON_ERROR(GetDisplay, vaapi_x11_handle);
466 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle); 557 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Initialize, vaapi_handle);
467 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle); 558 VAAPI_DLSYM_OR_RETURN_ON_ERROR(PutSurface, vaapi_x11_handle);
468 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle); 559 VAAPI_DLSYM_OR_RETURN_ON_ERROR(RenderPicture, vaapi_handle);
469 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle); 560 VAAPI_DLSYM_OR_RETURN_ON_ERROR(SyncSurface, vaapi_handle);
470 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle); 561 VAAPI_DLSYM_OR_RETURN_ON_ERROR(Terminate, vaapi_handle);
562 VAAPI_DLSYM_OR_RETURN_ON_ERROR(MapBuffer, vaapi_handle);
563 VAAPI_DLSYM_OR_RETURN_ON_ERROR(UnmapBuffer, vaapi_handle);
564 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DeriveImage, vaapi_handle);
565 VAAPI_DLSYM_OR_RETURN_ON_ERROR(DestroyImage, vaapi_handle);
471 #undef VAAPI_DLSYM 566 #undef VAAPI_DLSYM
472 567
473 return true; 568 return true;
474 } 569 }
475 570
476 } // namespace content 571 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698