videometa: Added video time code meta

It attaches a GstVideoTimeCodeMeta (SMPTE timecode) as metadata to a buffer.

https://bugzilla.gnome.org/show_bug.cgi?id=766419
This commit is contained in:
Vivia Nikolaidou 2016-05-14 17:59:20 +03:00 committed by Sebastian Dröge
parent ab35d7394e
commit 8d8384f20a
2 changed files with 179 additions and 0 deletions

View file

@ -846,3 +846,141 @@ gst_buffer_add_video_region_of_interest_meta_id (GstBuffer * buffer,
return meta; return meta;
} }
/* Time Code Meta implementation *******************************************/
GType
gst_video_time_code_meta_api_get_type (void)
{
static volatile GType type;
if (g_once_init_enter (&type)) {
static const gchar *tags[] = { NULL };
GType _type = gst_meta_api_type_register ("GstVideoTimeCodeMetaAPI", tags);
GST_INFO ("registering");
g_once_init_leave (&type, _type);
}
return type;
}
static gboolean
gst_video_time_code_meta_transform (GstBuffer * dest, GstMeta * meta,
GstBuffer * buffer, GQuark type, gpointer data)
{
GstVideoTimeCodeMeta *dmeta, *smeta;
if (GST_META_TRANSFORM_IS_COPY (type)) {
smeta = (GstVideoTimeCodeMeta *) meta;
GST_DEBUG ("copy time code metadata");
dmeta =
gst_buffer_add_video_time_code_meta_full (dest, smeta->tc.config.fps_n,
smeta->tc.config.fps_d, smeta->tc.config.latest_daily_jam,
smeta->tc.config.flags, smeta->tc.hours, smeta->tc.minutes,
smeta->tc.seconds, smeta->tc.frames, smeta->tc.field_count);
if (!dmeta)
return FALSE;
} else {
/* return FALSE, if transform type is not supported */
return FALSE;
}
return TRUE;
}
static gboolean
gst_video_time_code_meta_init (GstMeta * meta, gpointer params,
GstBuffer * buffer)
{
GstVideoTimeCodeMeta *emeta = (GstVideoTimeCodeMeta *) meta;
memset (&emeta->tc, 0, sizeof (emeta->tc));
gst_video_time_code_clear (&emeta->tc);
return TRUE;
}
static void
gst_video_time_code_meta_free (GstMeta * meta, GstBuffer * buffer)
{
GstVideoTimeCodeMeta *emeta = (GstVideoTimeCodeMeta *) meta;
gst_video_time_code_clear (&emeta->tc);
}
const GstMetaInfo *
gst_video_time_code_meta_get_info (void)
{
static const GstMetaInfo *meta_info = NULL;
if (g_once_init_enter (&meta_info)) {
const GstMetaInfo *mi =
gst_meta_register (GST_VIDEO_TIME_CODE_META_API_TYPE,
"GstVideoTimeCodeMeta",
sizeof (GstVideoTimeCodeMeta),
gst_video_time_code_meta_init,
gst_video_time_code_meta_free,
gst_video_time_code_meta_transform);
g_once_init_leave (&meta_info, mi);
}
return meta_info;
}
/**
* gst_buffer_add_video_time_code_meta:
* @buffer: a #GstBuffer
* @tc: a #GstVideoTimeCode
*
* Attaches #GstVideoTimeCodeMeta metadata to @buffer with the given
* parameters.
*
* Returns: (transfer none): the #GstVideoTimeCodeMeta on @buffer.
*
* Since: 1.10
*/
GstVideoTimeCodeMeta *
gst_buffer_add_video_time_code_meta (GstBuffer * buffer, GstVideoTimeCode * tc)
{
g_return_val_if_fail (gst_video_time_code_is_valid (tc), NULL);
return gst_buffer_add_video_time_code_meta_full (buffer, tc->config.fps_n,
tc->config.fps_d, tc->config.latest_daily_jam, tc->config.flags,
tc->hours, tc->minutes, tc->seconds, tc->frames, tc->field_count);
}
/**
* gst_buffer_add_video_time_code_meta_full:
* @buffer: a #GstBuffer
* @fps_n: framerate numerator
* @fps_d: framerate denominator
* @latest_daily_jam: a #GDateTime for the latest daily jam
* @flags: a #GstVideoTimeCodeFlags
* @hours: hours since the daily jam
* @minutes: minutes since the daily jam
* @seconds: seconds since the daily jam
* @frames: frames since the daily jam
* @field_count: fields since the daily jam
*
* Attaches #GstVideoTimeCodeMeta metadata to @buffer with the given
* parameters.
*
* Returns: (transfer none): the #GstVideoTimeCodeMeta on @buffer.
*
* Since: 1.10
*/
GstVideoTimeCodeMeta *
gst_buffer_add_video_time_code_meta_full (GstBuffer * buffer, guint fps_n,
guint fps_d, GDateTime * latest_daily_jam, GstVideoTimeCodeFlags flags,
guint hours, guint minutes, guint seconds, guint frames, guint field_count)
{
GstVideoTimeCodeMeta *meta;
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
meta = (GstVideoTimeCodeMeta *) gst_buffer_add_meta (buffer,
GST_VIDEO_TIME_CODE_META_INFO, NULL);
gst_video_time_code_init (&meta->tc, fps_n, fps_d, latest_daily_jam, flags,
hours, minutes, seconds, frames, field_count);
g_return_val_if_fail (gst_video_time_code_is_valid (&meta->tc), NULL);
return meta;
}

View file

@ -23,6 +23,7 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/video/video.h> #include <gst/video/video.h>
#include <gst/video/gstvideotimecode.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -295,6 +296,46 @@ GstVideoRegionOfInterestMeta *gst_buffer_add_video_region_of_interest_meta_id (G
guint w, guint w,
guint h); guint h);
/**
* GstVideoTimeCodeMeta:
* @meta: parent #GstMeta
* @tc: the GstVideoTimeCode to attach
*
* Extra buffer metadata describing the GstVideoTimeCode of the frame.
*
* Each frame is assumed to have its own timecode, i.e. they are not
* automatically incremented/interpolated.
*
* Since: 1.10
*/
typedef struct {
GstMeta meta;
GstVideoTimeCode tc;
} GstVideoTimeCodeMeta;
GType gst_video_time_code_meta_api_get_type (void);
#define GST_VIDEO_TIME_CODE_META_API_TYPE (gst_video_time_code_meta_api_get_type())
const GstMetaInfo *gst_video_time_code_meta_get_info (void);
#define GST_VIDEO_TIME_CODE_META_INFO (gst_video_time_code_meta_get_info())
#define gst_buffer_get_video_time_code_meta(b) \
((GstVideoTimeCodeMeta*)gst_buffer_get_meta((b),GST_VIDEO_TIME_CODE_META_API_TYPE))
GstVideoTimeCodeMeta *gst_buffer_add_video_time_code_meta (GstBuffer * buffer,
GstVideoTimeCode * tc);
GstVideoTimeCodeMeta *
gst_buffer_add_video_time_code_meta_full (GstBuffer * buffer,
guint fps_n,
guint fps_d,
GDateTime * latest_daily_jam,
GstVideoTimeCodeFlags flags,
guint hours,
guint minutes,
guint seconds,
guint frames,
guint field_count);
G_END_DECLS G_END_DECLS
#endif /* __GST_VIDEO_META_H__ */ #endif /* __GST_VIDEO_META_H__ */