void VAApiWriter::draw( VASurfaceID _id, int _field ) { if ( _id != VA_INVALID_SURFACE && _field > -1 ) { if ( id != _id || _field == field ) vaSyncSurface( VADisp, _id ); id = _id; field = _field; } if ( id == VA_INVALID_SURFACE ) return; bool associated = false; osd_mutex.lock(); if ( !osd_list.isEmpty() ) { QRect bounds; const qreal scaleW = ( qreal )W / outW, scaleH = ( qreal )H / outH; bool mustRepaint = Functions::mustRepaintOSD( osd_list, osd_checksums, &scaleW, &scaleH, &bounds ); if ( !mustRepaint ) mustRepaint = vaImgSize != bounds.size(); bool canAssociate = !mustRepaint; if ( mustRepaint ) { if ( vaImgSize != bounds.size() ) { clearRGBImage(); vaImgSize = QSize(); if ( vaCreateImage( VADisp, rgbImgFmt, bounds.width(), bounds.height(), &vaImg ) == VA_STATUS_SUCCESS ) { if ( vaCreateSubpicture( VADisp, vaImg.image_id, &vaSubpicID ) == VA_STATUS_SUCCESS ) vaImgSize = bounds.size(); else clearRGBImage(); } } if ( vaSubpicID ) { quint8 *buff; if ( vaMapBuffer( VADisp, vaImg.buf, ( void ** )&buff ) == VA_STATUS_SUCCESS ) { QImage osdImg( buff += vaImg.offsets[ 0 ], vaImg.pitches[ 0 ] >> 2, bounds.height(), QImage::Format_ARGB32 ); osdImg.fill( 0 ); QPainter p( &osdImg ); p.translate( -bounds.topLeft() ); Functions::paintOSD( osd_list, scaleW, scaleH, p, &osd_checksums ); vaUnmapBuffer( VADisp, vaImg.buf ); canAssociate = true; } } }
static gboolean gst_vaapi_subpicture_create (GstVaapiSubpicture * subpicture, GstVaapiImage * image) { GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (subpicture); VASubpictureID subpicture_id; VAStatus status; GST_VAAPI_DISPLAY_LOCK (display); status = vaCreateSubpicture (GST_VAAPI_DISPLAY_VADISPLAY (display), GST_VAAPI_OBJECT_ID (image), &subpicture_id); GST_VAAPI_DISPLAY_UNLOCK (display); if (!vaapi_check_status (status, "vaCreateSubpicture()")) return FALSE; GST_DEBUG ("subpicture %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS (subpicture_id)); GST_VAAPI_OBJECT_ID (subpicture) = subpicture_id; subpicture->image = gst_vaapi_object_ref (image); return TRUE; }