videoencoder/decoder: Move conversion utility functions to a common header and use consistently in encoder/decoder

This commit is contained in:
Sebastian Dröge 2016-07-04 10:47:36 +02:00
parent 1032f5c1b3
commit d8111778bd
4 changed files with 149 additions and 168 deletions

View file

@ -602,117 +602,6 @@ gst_video_decoder_init (GstVideoDecoder * decoder, GstVideoDecoderClass * klass)
gst_video_decoder_reset (decoder, TRUE, TRUE);
}
static gboolean
gst_video_rawvideo_convert (GstVideoCodecState * state,
GstFormat src_format, gint64 src_value,
GstFormat * dest_format, gint64 * dest_value)
{
gboolean res = FALSE;
guint vidsize;
guint fps_n, fps_d;
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_value != NULL, FALSE);
if (src_format == *dest_format || src_value == 0 || src_value == -1) {
*dest_value = src_value;
return TRUE;
}
vidsize = GST_VIDEO_INFO_SIZE (&state->info);
fps_n = GST_VIDEO_INFO_FPS_N (&state->info);
fps_d = GST_VIDEO_INFO_FPS_D (&state->info);
if (src_format == GST_FORMAT_BYTES &&
*dest_format == GST_FORMAT_DEFAULT && vidsize) {
/* convert bytes to frames */
*dest_value = gst_util_uint64_scale_int (src_value, 1, vidsize);
res = TRUE;
} else if (src_format == GST_FORMAT_DEFAULT &&
*dest_format == GST_FORMAT_BYTES && vidsize) {
/* convert bytes to frames */
*dest_value = src_value * vidsize;
res = TRUE;
} else if (src_format == GST_FORMAT_DEFAULT &&
*dest_format == GST_FORMAT_TIME && fps_n) {
/* convert frames to time */
*dest_value = gst_util_uint64_scale (src_value, GST_SECOND * fps_d, fps_n);
res = TRUE;
} else if (src_format == GST_FORMAT_TIME &&
*dest_format == GST_FORMAT_DEFAULT && fps_d) {
/* convert time to frames */
*dest_value = gst_util_uint64_scale (src_value, fps_n, GST_SECOND * fps_d);
res = TRUE;
} else if (src_format == GST_FORMAT_TIME &&
*dest_format == GST_FORMAT_BYTES && fps_d && vidsize) {
/* convert time to bytes */
*dest_value = gst_util_uint64_scale (src_value,
fps_n * (guint64) vidsize, GST_SECOND * fps_d);
res = TRUE;
} else if (src_format == GST_FORMAT_BYTES &&
*dest_format == GST_FORMAT_TIME && fps_n && vidsize) {
/* convert bytes to time */
*dest_value = gst_util_uint64_scale (src_value,
GST_SECOND * fps_d, fps_n * (guint64) vidsize);
res = TRUE;
}
return res;
}
static gboolean
gst_video_encoded_video_convert (gint64 bytes, gint64 time,
GstFormat src_format, gint64 src_value, GstFormat * dest_format,
gint64 * dest_value)
{
gboolean res = FALSE;
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_value != NULL, FALSE);
if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
src_value == -1)) {
if (dest_value)
*dest_value = src_value;
return TRUE;
}
if (bytes <= 0 || time <= 0) {
GST_DEBUG ("not enough metadata yet to convert");
goto exit;
}
switch (src_format) {
case GST_FORMAT_BYTES:
switch (*dest_format) {
case GST_FORMAT_TIME:
*dest_value = gst_util_uint64_scale (src_value, time, bytes);
res = TRUE;
break;
default:
res = FALSE;
}
break;
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES:
*dest_value = gst_util_uint64_scale (src_value, bytes, time);
res = TRUE;
break;
default:
res = FALSE;
}
break;
default:
GST_DEBUG ("unhandled conversion from %d to %d", src_format,
*dest_format);
res = FALSE;
}
exit:
return res;
}
static GstVideoCodecState *
_new_input_state (GstCaps * caps)
{
@ -1753,7 +1642,7 @@ gst_video_decoder_src_query_default (GstVideoDecoder * dec, GstQuery * query)
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
GST_OBJECT_LOCK (dec);
if (dec->priv->output_state != NULL)
res = gst_video_rawvideo_convert (dec->priv->output_state,
res = __gst_video_rawvideo_convert (dec->priv->output_state,
src_fmt, src_val, &dest_fmt, &dest_val);
else
res = FALSE;
@ -1879,8 +1768,8 @@ gst_video_decoder_sink_query_default (GstVideoDecoder * decoder,
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
res =
gst_video_encoded_video_convert (priv->bytes_out, priv->time, src_fmt,
src_val, &dest_fmt, &dest_val);
__gst_video_encoded_video_convert (priv->bytes_out, priv->time,
src_fmt, src_val, &dest_fmt, &dest_val);
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
if (!res)
goto error;

View file

@ -483,59 +483,6 @@ gst_video_encoder_init (GstVideoEncoder * encoder, GstVideoEncoderClass * klass)
gst_video_encoder_reset (encoder, TRUE);
}
static gboolean
gst_video_encoded_video_convert (gint64 bytes, gint64 time,
GstFormat src_format, gint64 src_value, GstFormat * dest_format,
gint64 * dest_value)
{
gboolean res = FALSE;
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_value != NULL, FALSE);
if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
src_value == -1)) {
if (dest_value)
*dest_value = src_value;
return TRUE;
}
if (bytes <= 0 || time <= 0) {
GST_DEBUG ("not enough metadata yet to convert");
goto exit;
}
switch (src_format) {
case GST_FORMAT_BYTES:
switch (*dest_format) {
case GST_FORMAT_TIME:
*dest_value = gst_util_uint64_scale (src_value, time, bytes);
res = TRUE;
break;
default:
res = FALSE;
}
break;
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES:
*dest_value = gst_util_uint64_scale (src_value, bytes, time);
res = TRUE;
break;
default:
res = FALSE;
}
break;
default:
GST_DEBUG ("unhandled conversion from %d to %d", src_format,
*dest_format);
res = FALSE;
}
exit:
return res;
}
/**
* gst_video_encoder_set_headers:
* @encoder: a #GstVideoEncoder
@ -836,6 +783,26 @@ gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
res = TRUE;
break;
}
case GST_QUERY_CONVERT:
{
GstFormat src_fmt, dest_fmt;
gint64 src_val, dest_val;
GST_DEBUG_OBJECT (encoder, "convert query");
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
GST_OBJECT_LOCK (encoder);
if (encoder->priv->input_state != NULL)
res = __gst_video_rawvideo_convert (encoder->priv->input_state,
src_fmt, src_val, &dest_fmt, &dest_val);
else
res = FALSE;
GST_OBJECT_UNLOCK (encoder);
if (!res)
goto error;
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
break;
}
case GST_QUERY_ALLOCATION:
{
GstVideoEncoderClass *klass = GST_VIDEO_ENCODER_GET_CLASS (encoder);
@ -849,6 +816,10 @@ gst_video_encoder_sink_query_default (GstVideoEncoder * encoder,
break;
}
return res;
error:
GST_DEBUG_OBJECT (encoder, "query failed");
return res;
}
static gboolean
@ -1267,7 +1238,7 @@ gst_video_encoder_src_query_default (GstVideoEncoder * enc, GstQuery * query)
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
res =
gst_video_encoded_video_convert (priv->bytes, priv->time, src_fmt,
__gst_video_encoded_video_convert (priv->bytes, priv->time, src_fmt,
src_val, &dest_fmt, &dest_val);
if (!res)
goto error;

View file

@ -144,3 +144,114 @@ done:
return fcaps;
}
gboolean
__gst_video_rawvideo_convert (GstVideoCodecState * state,
GstFormat src_format, gint64 src_value,
GstFormat * dest_format, gint64 * dest_value)
{
gboolean res = FALSE;
guint vidsize;
guint fps_n, fps_d;
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_value != NULL, FALSE);
if (src_format == *dest_format || src_value == 0 || src_value == -1) {
*dest_value = src_value;
return TRUE;
}
vidsize = GST_VIDEO_INFO_SIZE (&state->info);
fps_n = GST_VIDEO_INFO_FPS_N (&state->info);
fps_d = GST_VIDEO_INFO_FPS_D (&state->info);
if (src_format == GST_FORMAT_BYTES &&
*dest_format == GST_FORMAT_DEFAULT && vidsize) {
/* convert bytes to frames */
*dest_value = gst_util_uint64_scale_int (src_value, 1, vidsize);
res = TRUE;
} else if (src_format == GST_FORMAT_DEFAULT &&
*dest_format == GST_FORMAT_BYTES && vidsize) {
/* convert bytes to frames */
*dest_value = src_value * vidsize;
res = TRUE;
} else if (src_format == GST_FORMAT_DEFAULT &&
*dest_format == GST_FORMAT_TIME && fps_n) {
/* convert frames to time */
*dest_value = gst_util_uint64_scale (src_value, GST_SECOND * fps_d, fps_n);
res = TRUE;
} else if (src_format == GST_FORMAT_TIME &&
*dest_format == GST_FORMAT_DEFAULT && fps_d) {
/* convert time to frames */
*dest_value = gst_util_uint64_scale (src_value, fps_n, GST_SECOND * fps_d);
res = TRUE;
} else if (src_format == GST_FORMAT_TIME &&
*dest_format == GST_FORMAT_BYTES && fps_d && vidsize) {
/* convert time to bytes */
*dest_value = gst_util_uint64_scale (src_value,
fps_n * (guint64) vidsize, GST_SECOND * fps_d);
res = TRUE;
} else if (src_format == GST_FORMAT_BYTES &&
*dest_format == GST_FORMAT_TIME && fps_n && vidsize) {
/* convert bytes to time */
*dest_value = gst_util_uint64_scale (src_value,
GST_SECOND * fps_d, fps_n * (guint64) vidsize);
res = TRUE;
}
return res;
}
gboolean
__gst_video_encoded_video_convert (gint64 bytes, gint64 time,
GstFormat src_format, gint64 src_value, GstFormat * dest_format,
gint64 * dest_value)
{
gboolean res = FALSE;
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_value != NULL, FALSE);
if (G_UNLIKELY (src_format == *dest_format || src_value == 0 ||
src_value == -1)) {
if (dest_value)
*dest_value = src_value;
return TRUE;
}
if (bytes <= 0 || time <= 0) {
GST_DEBUG ("not enough metadata yet to convert");
goto exit;
}
switch (src_format) {
case GST_FORMAT_BYTES:
switch (*dest_format) {
case GST_FORMAT_TIME:
*dest_value = gst_util_uint64_scale (src_value, time, bytes);
res = TRUE;
break;
default:
res = FALSE;
}
break;
case GST_FORMAT_TIME:
switch (*dest_format) {
case GST_FORMAT_BYTES:
*dest_value = gst_util_uint64_scale (src_value, bytes, time);
res = TRUE;
break;
default:
res = FALSE;
}
break;
default:
GST_DEBUG ("unhandled conversion from %d to %d", src_format,
*dest_format);
res = FALSE;
}
exit:
return res;
}

View file

@ -36,6 +36,16 @@ GstCaps *__gst_video_element_proxy_getcaps (GstElement * element, GstPad * sinkp
GstPad * srcpad, GstCaps * initial_caps,
GstCaps * filter);
G_GNUC_INTERNAL
gboolean __gst_video_encoded_video_convert (gint64 bytes, gint64 time,
GstFormat src_format, gint64 src_value,
GstFormat * dest_format, gint64 * dest_value);
G_GNUC_INTERNAL
gboolean __gst_video_rawvideo_convert (GstVideoCodecState * state, GstFormat src_format,
gint64 src_value, GstFormat * dest_format,
gint64 * dest_value);
G_END_DECLS
#endif