summaryrefslogtreecommitdiffstats
path: root/content/common/gpu/media/vaapi_h264_decoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/common/gpu/media/vaapi_h264_decoder.cc')
-rw-r--r--content/common/gpu/media/vaapi_h264_decoder.cc82
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);