timeoverlay: add "time-line" property

So we can also show running time or stream time, not just the
buffer time stamps.
This commit is contained in:
Tim-Philipp Müller 2014-11-25 14:45:23 +00:00
parent 43f44d41dc
commit 6306cce41e
2 changed files with 110 additions and 6 deletions

View file

@ -1,6 +1,6 @@
/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) <2005> Tim-Philipp Müller <tim@centricular.net>
* Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 2005-2014 Tim-Philipp Müller <tim@centricular.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -50,9 +50,40 @@
#include "gsttimeoverlay.h"
#define DEFAULT_TIME_LINE GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME
enum
{
PROP_0,
PROP_TIME_LINE
};
#define gst_time_overlay_parent_class parent_class
G_DEFINE_TYPE (GstTimeOverlay, gst_time_overlay, GST_TYPE_BASE_TEXT_OVERLAY);
static void gst_time_overlay_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_time_overlay_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
#define GST_TYPE_TIME_OVERLAY_TIME_LINE (gst_time_overlay_time_line_type())
static GType
gst_time_overlay_time_line_type (void)
{
static GType time_line_type = 0;
static const GEnumValue modes[] = {
{GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME, "buffer-time", "buffer-time"},
{GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME, "stream-time", "stream-time"},
{GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME, "running-time", "running-time"},
{0, NULL, NULL},
};
if (!time_line_type) {
time_line_type = g_enum_register_static ("GstTimeOverlayTimeLine", modes);
}
return time_line_type;
}
static gchar *
gst_time_overlay_render_time (GstTimeOverlay * overlay, GstClockTime time)
{
@ -74,21 +105,40 @@ static gchar *
gst_time_overlay_get_text (GstBaseTextOverlay * overlay,
GstBuffer * video_frame)
{
GstClockTime time = GST_BUFFER_TIMESTAMP (video_frame);
GstTimeOverlayTimeLine time_line;
GstClockTime ts, ts_buffer;
GstSegment *segment = &overlay->segment;
gchar *time_str, *txt, *ret;
overlay->need_render = TRUE;
if (!GST_CLOCK_TIME_IS_VALID (time)) {
ts_buffer = GST_BUFFER_TIMESTAMP (video_frame);
if (!GST_CLOCK_TIME_IS_VALID (ts_buffer)) {
GST_DEBUG ("buffer without valid timestamp");
return g_strdup ("");
}
GST_DEBUG ("buffer with timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (time));
GST_DEBUG ("buffer with timestamp %" GST_TIME_FORMAT,
GST_TIME_ARGS (ts_buffer));
time_line = g_atomic_int_get (&GST_TIME_OVERLAY_CAST (overlay)->time_line);
switch (time_line) {
case GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME:
ts = gst_segment_to_stream_time (segment, GST_FORMAT_TIME, ts_buffer);
break;
case GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME:
ts = gst_segment_to_running_time (segment, GST_FORMAT_TIME, ts_buffer);
break;
case GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME:
default:
ts = ts_buffer;
break;
}
txt = g_strdup (overlay->default_text);
time_str = gst_time_overlay_render_time (GST_TIME_OVERLAY (overlay), time);
time_str = gst_time_overlay_render_time (GST_TIME_OVERLAY (overlay), ts);
if (txt != NULL && *txt != '\0') {
ret = g_strdup_printf ("%s %s", txt, time_str);
} else {
@ -107,11 +157,13 @@ gst_time_overlay_class_init (GstTimeOverlayClass * klass)
{
GstElementClass *gstelement_class;
GstBaseTextOverlayClass *gsttextoverlay_class;
GObjectClass *gobject_class;
PangoContext *context;
PangoFontDescription *font_description;
gsttextoverlay_class = (GstBaseTextOverlayClass *) klass;
gstelement_class = (GstElementClass *) klass;
gobject_class = (GObjectClass *) klass;
gst_element_class_set_static_metadata (gstelement_class, "Time overlay",
"Filter/Editor/Video",
@ -120,6 +172,14 @@ gst_time_overlay_class_init (GstTimeOverlayClass * klass)
gsttextoverlay_class->get_text = gst_time_overlay_get_text;
gobject_class->set_property = gst_time_overlay_set_property;
gobject_class->get_property = gst_time_overlay_get_property;
g_object_class_install_property (gobject_class, PROP_TIME_LINE,
g_param_spec_enum ("time-mode", "Time Mode", "What time to show",
GST_TYPE_TIME_OVERLAY_TIME_LINE, DEFAULT_TIME_LINE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_mutex_lock (gsttextoverlay_class->pango_lock);
context = gsttextoverlay_class->pango_context;
@ -147,4 +207,38 @@ gst_time_overlay_init (GstTimeOverlay * overlay)
textoverlay->valign = GST_BASE_TEXT_OVERLAY_VALIGN_TOP;
textoverlay->halign = GST_BASE_TEXT_OVERLAY_HALIGN_LEFT;
overlay->time_line = DEFAULT_TIME_LINE;
}
static void
gst_time_overlay_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstTimeOverlay *overlay = GST_TIME_OVERLAY (object);
switch (prop_id) {
case PROP_TIME_LINE:
g_atomic_int_set (&overlay->time_line, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_time_overlay_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstTimeOverlay *overlay = GST_TIME_OVERLAY (object);
switch (prop_id) {
case PROP_TIME_LINE:
g_value_set_enum (value, g_atomic_int_get (&overlay->time_line));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

View file

@ -36,10 +36,17 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TIME_OVERLAY))
#define GST_IS_TIME_OVERLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TIME_OVERLAY))
#define GST_TIME_OVERLAY_CAST(obj) ((GstTimeOverlay*)(obj))
typedef struct _GstTimeOverlay GstTimeOverlay;
typedef struct _GstTimeOverlayClass GstTimeOverlayClass;
typedef enum {
GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME,
GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME,
GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME
} GstTimeOverlayTimeLine;
/**
* GstTimeOverlay:
*
@ -47,6 +54,9 @@ typedef struct _GstTimeOverlayClass GstTimeOverlayClass;
*/
struct _GstTimeOverlay {
GstBaseTextOverlay textoverlay;
/*< private >*/
GstTimeOverlayTimeLine time_line;
};
struct _GstTimeOverlayClass {