GstClockTime earliest_time;
gboolean discont;
+ gint64 bytes;
+ gint64 time;
+
/* FIXME before moving to base */
void *padding[GST_PADDING_LARGE];
};
gboolean gst_base_video_rawvideo_convert (GstVideoState *state,
GstFormat src_format, gint64 src_value,
GstFormat * dest_format, gint64 *dest_value);
-gboolean gst_base_video_encoded_video_convert (GstVideoState *state,
- GstFormat src_format, gint64 src_value,
- GstFormat * dest_format, gint64 *dest_value);
+gboolean gst_base_video_encoded_video_convert (GstVideoState * state,
+ gint64 bytes, gint64 time, GstFormat src_format,
+ gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
GstClockTime gst_video_state_get_timestamp (const GstVideoState *state,
GstSegment *segment, int frame_number);
pad);
static gboolean gst_base_video_decoder_src_query (GstPad * pad,
GstQuery * query);
-static gboolean gst_base_video_decoder_src_convert (GstPad * pad,
- GstFormat src_format, gint64 src_value, GstFormat * dest_format,
- gint64 * dest_value);
static void gst_base_video_decoder_reset (GstBaseVideoDecoder *
base_video_decoder);
gst_event_unref (event);
tformat = GST_FORMAT_TIME;
- res =
- gst_base_video_decoder_src_convert (pad, format, cur, &tformat,
- &tcur);
+ res = gst_pad_query_convert (GST_BASE_VIDEO_CODEC_SINK_PAD
+ (base_video_decoder), format, cur, &tformat, &tcur);
if (!res)
goto convert_error;
- res =
- gst_base_video_decoder_src_convert (pad, format, stop, &tformat,
- &tstop);
+ res = gst_pad_query_convert (GST_BASE_VIDEO_CODEC_SINK_PAD
+ (base_video_decoder), format, stop, &tformat, &tstop);
if (!res)
goto convert_error;
goto done;
}
-static gboolean
-gst_base_video_decoder_src_convert (GstPad * pad,
- GstFormat src_format, gint64 src_value,
- GstFormat * dest_format, gint64 * dest_value)
-{
- gboolean res = TRUE;
- GstBaseVideoDecoder *dec;
-
- if (src_format == *dest_format) {
- *dest_value = src_value;
- return TRUE;
- }
-
- dec = GST_BASE_VIDEO_DECODER (gst_pad_get_parent (pad));
-
- /* FIXME: check if we are in a encoding state */
-
- GST_DEBUG_OBJECT (dec, "src convert");
- switch (src_format) {
-#if 0
- case GST_FORMAT_DEFAULT:
- switch (*dest_format) {
- case GST_FORMAT_TIME:
- *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value),
- enc->fps_d * GST_SECOND, enc->fps_n);
- break;
- default:
- res = FALSE;
- }
- break;
- case GST_FORMAT_TIME:
- switch (*dest_format) {
- case GST_FORMAT_DEFAULT:
- {
- *dest_value = gst_util_uint64_scale (src_value,
- enc->fps_n, enc->fps_d * GST_SECOND);
- break;
- }
- default:
- res = FALSE;
- break;
- }
- break;
-#endif
- default:
- res = FALSE;
- break;
- }
-
- gst_object_unref (dec);
-
- return res;
-}
-
static const GstQueryType *
gst_base_video_decoder_get_query_types (GstPad * pad)
{
GST_DEBUG_OBJECT (dec, "convert query");
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
- res =
- gst_base_video_decoder_src_convert (pad, src_fmt, src_val, &dest_fmt,
- &dest_val);
+ res = gst_base_video_rawvideo_convert (&GST_BASE_VIDEO_CODEC (dec)->state,
+ src_fmt, src_val, &dest_fmt, &dest_val);
if (!res)
goto error;
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONVERT:
{
+ GstBaseVideoCodec *codec = GST_BASE_VIDEO_CODEC (base_video_decoder);
GstFormat src_fmt, dest_fmt;
gint64 src_val, dest_val;
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
- res =
- gst_base_video_rawvideo_convert (&GST_BASE_VIDEO_CODEC
- (base_video_decoder)->state, src_fmt, src_val, &dest_fmt, &dest_val);
+ res = gst_base_video_encoded_video_convert (&codec->state, codec->bytes,
+ codec->time, src_fmt, src_val, &dest_fmt, &dest_val);
if (!res)
goto error;
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
GST_BUFFER_OFFSET (src_buffer) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (src_buffer) = GST_BUFFER_OFFSET_NONE;
+ /* update rate estimate */
+ GST_BASE_VIDEO_CODEC (base_video_decoder)->bytes +=
+ GST_BUFFER_SIZE (src_buffer);
+ if (GST_CLOCK_TIME_IS_VALID (frame->presentation_duration)) {
+ GST_BASE_VIDEO_CODEC (base_video_decoder)->time +=
+ frame->presentation_duration;
+ } else {
+ /* better none than nothing valid */
+ GST_BASE_VIDEO_CODEC (base_video_decoder)->time = GST_CLOCK_TIME_NONE;
+ }
+
GST_DEBUG_OBJECT (base_video_decoder, "pushing frame %" GST_TIME_FORMAT,
GST_TIME_ARGS (frame->presentation_timestamp));
caps = gst_video_format_new_caps (state->format,
state->width, state->height,
state->fps_n, state->fps_d, state->par_n, state->par_d);
+ /* arrange for derived info */
+ state->bytes_per_picture =
+ gst_video_format_get_size (state->format, state->width, state->height);
gst_caps_set_simple (caps, "interlaced",
G_TYPE_BOOLEAN, state->interlaced, NULL);
state->interlaced = v;
}
+ state->bytes_per_picture =
+ gst_video_format_get_size (state->format, state->width, state->height);
state->clean_width = state->width;
state->clean_height = state->height;
state->clean_offset_left = 0;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONVERT:
{
+ GstBaseVideoCodec *codec = GST_BASE_VIDEO_CODEC (enc);
GstFormat src_fmt, dest_fmt;
gint64 src_val, dest_val;
gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
- res =
- gst_base_video_encoded_video_convert (&GST_BASE_VIDEO_CODEC
- (enc)->state, src_fmt, src_val, &dest_fmt, &dest_val);
+ res = gst_base_video_encoded_video_convert (&codec->state,
+ codec->bytes, codec->time, src_fmt, src_val, &dest_fmt, &dest_val);
if (!res)
goto error;
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
GST_BUFFER_DURATION (frame->src_buffer) = frame->presentation_duration;
GST_BUFFER_OFFSET (frame->src_buffer) = frame->decode_timestamp;
+ /* update rate estimate */
+ GST_BASE_VIDEO_CODEC (base_video_encoder)->bytes +=
+ GST_BUFFER_SIZE (frame->src_buffer);
+ if (GST_CLOCK_TIME_IS_VALID (frame->presentation_duration)) {
+ GST_BASE_VIDEO_CODEC (base_video_encoder)->time +=
+ frame->presentation_duration;
+ } else {
+ /* better none than nothing valid */
+ GST_BASE_VIDEO_CODEC (base_video_encoder)->time = GST_CLOCK_TIME_NONE;
+ }
+
if (G_UNLIKELY (GST_BASE_VIDEO_CODEC (base_video_encoder)->discont)) {
GST_LOG_OBJECT (base_video_encoder, "marking discont");
GST_BUFFER_FLAG_SET (frame->src_buffer, GST_BUFFER_FLAG_DISCONT);
{
gboolean res = FALSE;
- if (src_format == *dest_format) {
+ 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;
}
*dest_value = gst_util_uint64_scale (src_value, state->fps_n,
GST_SECOND * state->fps_d);
res = TRUE;
+ } else if (src_format == GST_FORMAT_TIME &&
+ *dest_format == GST_FORMAT_BYTES && state->fps_d != 0 &&
+ state->bytes_per_picture != 0) {
+ /* convert time to frames */
+ /* FIXME subtract segment time? */
+ *dest_value = gst_util_uint64_scale (src_value,
+ state->fps_n * state->bytes_per_picture, GST_SECOND * state->fps_d);
+ res = TRUE;
+ } else if (src_format == GST_FORMAT_BYTES &&
+ *dest_format == GST_FORMAT_TIME && state->fps_n != 0 &&
+ state->bytes_per_picture != 0) {
+ /* convert frames to time */
+ /* FIXME add segment time? */
+ *dest_value = gst_util_uint64_scale (src_value,
+ GST_SECOND * state->fps_d, state->fps_n * state->bytes_per_picture);
+ res = TRUE;
}
- /* FIXME add bytes <--> time */
-
return res;
}
gboolean
gst_base_video_encoded_video_convert (GstVideoState * state,
- GstFormat src_format, gint64 src_value,
- GstFormat * dest_format, gint64 * dest_value)
+ gint64 bytes, gint64 time, GstFormat src_format,
+ gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
{
gboolean res = FALSE;
- if (src_format == *dest_format) {
- *dest_value = src_value;
+ 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;
}
- GST_DEBUG ("src convert");
+ if (bytes <= 0 || time <= 0) {
+ GST_DEBUG ("not enough metadata yet to convert");
+ goto exit;
+ }
-#if 0
- if (src_format == GST_FORMAT_DEFAULT && *dest_format == GST_FORMAT_TIME) {
- if (dec->fps_d != 0) {
- *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value),
- dec->fps_d * GST_SECOND, dec->fps_n);
- res = TRUE;
- } else {
+ 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;
- }
- } else {
- GST_WARNING ("unhandled conversion from %d to %d", src_format,
- *dest_format);
- res = FALSE;
}
-#endif
+exit:
return res;
}