diff options
Diffstat (limited to 'content/common/gpu/media/vaapi_h264_decoder.cc')
-rw-r--r-- | content/common/gpu/media/vaapi_h264_decoder.cc | 82 |
1 files changed, 55 insertions, 27 deletions
diff --git a/content/common/gpu/media/vaapi_h264_decoder.cc b/content/common/gpu/media/vaapi_h264_decoder.cc index d336b42..78859f8 100644 --- a/content/common/gpu/media/vaapi_h264_decoder.cc +++ b/content/common/gpu/media/vaapi_h264_decoder.cc @@ -156,7 +156,7 @@ class VaapiH264Decoder::DecodeSurface { DecodeSurface(const GLXFBConfig& fb_config, Display* x_display, VADisplay va_display, - const base::Closure& make_context_current, + const base::Callback<bool(void)>& make_context_current, VASurfaceID va_surface_id, int32 picture_buffer_id, uint32 texture_id, @@ -205,7 +205,7 @@ class VaapiH264Decoder::DecodeSurface { private: Display* x_display_; VADisplay va_display_; - base::Closure make_context_current_; + base::Callback<bool(void)> make_context_current_; VASurfaceID va_surface_id_; // Client-provided ids. @@ -233,7 +233,7 @@ VaapiH264Decoder::DecodeSurface::DecodeSurface( const GLXFBConfig& fb_config, Display* x_display, VADisplay va_display, - const base::Closure& make_context_current, + const base::Callback<bool(void)>& make_context_current, VASurfaceID va_surface_id, int32 picture_buffer_id, uint32 texture_id, @@ -246,10 +246,14 @@ VaapiH264Decoder::DecodeSurface::DecodeSurface( texture_id_(texture_id), width_(width), height_(height), - available_(false) { + available_(false), + x_pixmap_(0), + glx_pixmap_(0) { // Bind the surface to a texture of the given width and height, // allocating pixmaps as needed. - make_context_current_.Run(); + if (!make_context_current_.Run()) + return; + glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture_id_); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -271,8 +275,12 @@ VaapiH264Decoder::DecodeSurface::DecodeSurface( GL_NONE, }; - glx_pixmap_ = glXCreatePixmap(x_display_, fb_config, x_pixmap_, - pixmap_attr); + glx_pixmap_ = glXCreatePixmap(x_display_, fb_config, x_pixmap_, pixmap_attr); + if (!glx_pixmap_) { + // x_pixmap_ will be freed in the destructor. + DVLOG(1) << "Failed creating a GLX Pixmap for TFP"; + return; + } glBindTexture(GL_TEXTURE_2D, texture_id_); glXBindTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); @@ -281,11 +289,14 @@ VaapiH264Decoder::DecodeSurface::DecodeSurface( } VaapiH264Decoder::DecodeSurface::~DecodeSurface() { - make_context_current_.Run(); // Unbind surface from texture and deallocate resources. - glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); - glXDestroyGLXPixmap(x_display_, glx_pixmap_); - XFreePixmap(x_display_, x_pixmap_); + if (glx_pixmap_ && make_context_current_.Run()) { + glXReleaseTexImageEXT(x_display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); + glXDestroyGLXPixmap(x_display_, glx_pixmap_); + } + + if (x_pixmap_) + XFreePixmap(x_display_, x_pixmap_); } void VaapiH264Decoder::DecodeSurface::Acquire(int32 input_id, int poc) { @@ -300,7 +311,9 @@ void VaapiH264Decoder::DecodeSurface::Release() { } bool VaapiH264Decoder::DecodeSurface::Sync() { - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; + // Put the decoded data into XPixmap bound to the texture. VAStatus va_res = VAAPI_PutSurface(va_display_, va_surface_id_, x_pixmap_, @@ -394,7 +407,8 @@ void VaapiH264Decoder::Destroy() { DestroyVASurfaces(); // fallthrough case kInitialized: - make_context_current_.Run(); + if (!make_context_current_.Run()) + break; va_res = VAAPI_DestroyConfig(va_display_, va_config_id_); VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed"); va_res = VAAPI_Terminate(va_display_); @@ -454,11 +468,12 @@ bool VaapiH264Decoder::InitializeFBConfig() { return true; } -bool VaapiH264Decoder::Initialize(media::VideoCodecProfile profile, - Display* x_display, - GLXContext glx_context, - const base::Closure& make_context_current, - const OutputPicCB& output_pic_cb) { +bool VaapiH264Decoder::Initialize( + media::VideoCodecProfile profile, + Display* x_display, + GLXContext glx_context, + const base::Callback<bool(void)>& make_context_current, + const OutputPicCB& output_pic_cb) { DCHECK_EQ(state_, kUninitialized); output_pic_cb_ = output_pic_cb; @@ -466,7 +481,9 @@ bool VaapiH264Decoder::Initialize(media::VideoCodecProfile profile, x_display_ = x_display; make_context_current_ = make_context_current; - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; + if (!SetProfile(profile)) { DVLOG(1) << "Unsupported profile"; return false; @@ -560,7 +577,8 @@ bool VaapiH264Decoder::CreateVASurfaces() { DCHECK_NE(pic_width_, -1); DCHECK_NE(pic_height_, -1); DCHECK_EQ(state_, kInitialized); - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; // Allocate VASurfaces in driver. VAStatus va_res = VAAPI_CreateSurfaces(va_display_, pic_width_, @@ -583,10 +601,11 @@ bool VaapiH264Decoder::CreateVASurfaces() { void VaapiH264Decoder::DestroyVASurfaces() { DCHECK(state_ == kDecoding || state_ == kError || state_ == kAfterReset); - make_context_current_.Run(); - decode_surfaces_.clear(); + if (!make_context_current_.Run()) + return; + VAStatus va_res = VAAPI_DestroyContext(va_display_, va_context_id_); VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed"); @@ -699,7 +718,9 @@ VaapiH264Decoder::DecodeSurface* VaapiH264Decoder::UnassignSurfaceFromPoC( // Fill a VAPictureParameterBufferH264 to be later sent to the HW decoder. bool VaapiH264Decoder::SendPPS() { - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; + const H264PPS* pps = parser_.GetPPS(curr_pps_id_); DCHECK(pps); @@ -797,7 +818,9 @@ bool VaapiH264Decoder::SendPPS() { // Fill a VAIQMatrixBufferH264 to be later sent to the HW decoder. bool VaapiH264Decoder::SendIQMatrix() { - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; + const H264PPS* pps = parser_.GetPPS(curr_pps_id_); DCHECK(pps); @@ -844,7 +867,9 @@ bool VaapiH264Decoder::SendIQMatrix() { } bool VaapiH264Decoder::SendVASliceParam(H264SliceHeader* slice_hdr) { - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; + const H264PPS* pps = parser_.GetPPS(slice_hdr->pic_parameter_set_id); DCHECK(pps); @@ -948,7 +973,9 @@ bool VaapiH264Decoder::SendVASliceParam(H264SliceHeader* slice_hdr) { bool VaapiH264Decoder::SendSliceData(const uint8* ptr, size_t size) { - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; + // Can't help it, blame libva... void* non_const_ptr = const_cast<uint8*>(ptr); @@ -981,7 +1008,8 @@ bool VaapiH264Decoder::QueueSlice(H264SliceHeader* slice_hdr) { bool VaapiH264Decoder::DecodePicture() { DCHECK(!frame_ready_at_hw_); DCHECK(curr_pic_.get()); - make_context_current_.Run(); + if (!make_context_current_.Run()) + return false; static const size_t kMaxVABuffers = 32; DCHECK_LE(pending_va_bufs_.size(), kMaxVABuffers); |