예제 #1
0
static void
gst_vaapiencode_purge (GstVaapiEncode * encode)
{
  GstVaapiCodedBufferProxy *codedbuf_proxy = NULL;
  GstVaapiEncoderStatus status;
  GstVideoCodecFrame *out_frame;

  do {
    status = gst_vaapi_encoder_get_buffer_with_timeout (encode->encoder,
        &codedbuf_proxy, 0);
    if (status == GST_VAAPI_ENCODER_STATUS_SUCCESS) {
      out_frame = gst_vaapi_coded_buffer_proxy_get_user_data (codedbuf_proxy);
      if (out_frame)
        gst_video_codec_frame_set_user_data (out_frame, NULL, NULL);

      gst_vaapi_coded_buffer_proxy_unref (codedbuf_proxy);
    }
  } while (status == GST_VAAPI_ENCODER_STATUS_SUCCESS);
}
예제 #2
0
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;
}
예제 #3
0
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;
  }
}