/** * gst_vaapi_coded_buffer_proxy_get_buffer: * @proxy: a #GstVaapiCodedBufferProxy * * Returns the #GstVaapiCodedBuffer stored in the @proxy. * * Return value: the #GstVaapiCodedBuffer, or %NULL if an error occurred */ GstVaapiCodedBuffer * gst_vaapi_coded_buffer_proxy_get_buffer (GstVaapiCodedBufferProxy * proxy) { g_return_val_if_fail (proxy != NULL, NULL); return GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (proxy); }
static gboolean ensure_picture (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) { GstVaapiCodedBuffer *const codedbuf = GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); if (!fill_picture (encoder, picture, codedbuf, surface)) return FALSE; return TRUE; }
static gboolean ensure_picture (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface) { GstVaapiCodedBuffer *const codedbuf = GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy); if (!fill_picture (encoder, picture, codedbuf, surface)) return FALSE; if (!set_picture_packed_header (encoder, picture)) { GST_ERROR ("set picture packed header failed"); return FALSE; } return TRUE; }
static GstVaapiEncoderStatus get_encoder_buffer (GstVaapiEncoder * encoder, GstBuffer ** buffer) { GstVaapiCodedBufferProxy *proxy = NULL; GstVaapiEncoderStatus status; status = gst_vaapi_encoder_get_buffer_with_timeout (encoder, &proxy, 50000); if (status < GST_VAAPI_ENCODER_STATUS_SUCCESS) { g_warning ("Failed to get a buffer from encoder: %d", status); return status; } else if (status > GST_VAAPI_ENCODER_STATUS_SUCCESS) { return status; } *buffer = allocate_buffer (GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (proxy)); gst_vaapi_coded_buffer_proxy_unref (proxy); return status; }
static GstFlowReturn gst_vaapiencode_push_frame (GstVaapiEncode * encode, gint64 timeout) { GstVideoEncoder *const venc = GST_VIDEO_ENCODER_CAST (encode); GstVaapiEncodeClass *const klass = GST_VAAPIENCODE_GET_CLASS (encode); GstVideoCodecFrame *out_frame; GstVaapiCodedBufferProxy *codedbuf_proxy = NULL; GstVaapiEncoderStatus status; GstBuffer *out_buffer; GstFlowReturn ret; status = gst_vaapi_encoder_get_buffer_with_timeout (encode->encoder, &codedbuf_proxy, timeout); if (status == GST_VAAPI_ENCODER_STATUS_NO_BUFFER) return GST_VAAPI_ENCODE_FLOW_TIMEOUT; if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS) goto error_get_buffer; out_frame = gst_vaapi_coded_buffer_proxy_get_user_data (codedbuf_proxy); if (!out_frame) goto error_get_buffer; gst_video_codec_frame_ref (out_frame); gst_video_codec_frame_set_user_data (out_frame, NULL, NULL); /* Update output state */ GST_VIDEO_ENCODER_STREAM_LOCK (encode); if (!ensure_output_state (encode)) goto error_output_state; GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); /* Allocate and copy buffer into system memory */ out_buffer = NULL; ret = klass->alloc_buffer (encode, GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy), &out_buffer); gst_vaapi_coded_buffer_proxy_replace (&codedbuf_proxy, NULL); if (ret != GST_FLOW_OK) goto error_allocate_buffer; gst_buffer_replace (&out_frame->output_buffer, out_buffer); gst_buffer_unref (out_buffer); GST_TRACE_OBJECT (encode, "output:%" GST_TIME_FORMAT ", size:%zu", GST_TIME_ARGS (out_frame->pts), gst_buffer_get_size (out_buffer)); return gst_video_encoder_finish_frame (venc, out_frame); /* ERRORS */ error_get_buffer: { GST_ERROR ("failed to get encoded buffer (status %d)", status); if (codedbuf_proxy) gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy); return GST_FLOW_ERROR; } error_allocate_buffer: { GST_ERROR ("failed to allocate encoded buffer in system memory"); if (out_buffer) gst_buffer_unref (out_buffer); gst_video_codec_frame_unref (out_frame); return ret; } error_output_state: { GST_ERROR ("failed to negotiate output state (status %d)", status); GST_VIDEO_ENCODER_STREAM_UNLOCK (encode); gst_video_codec_frame_unref (out_frame); return GST_FLOW_NOT_NEGOTIATED; } }