mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
videoencoder/decoder: Move conversion utility functions to a common header and use consistently in encoder/decoder
This commit is contained in:
parent
1032f5c1b3
commit
d8111778bd
4 changed files with 149 additions and 168 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue