From: David Schleef Date: Fri, 4 Jun 2010 19:09:23 +0000 (-0700) Subject: dvdemux: Parse SMPTE time codes X-Git-Tag: RELEASE-0.10.26~228 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=75d0795e53efd56a169ae2e594c353f176f2ab12;p=platform%2Fupstream%2Fgst-plugins-good.git dvdemux: Parse SMPTE time codes --- diff --git a/ext/dv/Makefile.am b/ext/dv/Makefile.am index 928d47592..e63154d05 100644 --- a/ext/dv/Makefile.am +++ b/ext/dv/Makefile.am @@ -1,6 +1,6 @@ plugin_LTLIBRARIES = libgstdv.la -libgstdv_la_SOURCES = gstdv.c gstdvdec.c gstdvdemux.c +libgstdv_la_SOURCES = gstdv.c gstdvdec.c gstdvdemux.c gstsmptetimecode.c libgstdv_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(LIBDV_CFLAGS) libgstdv_la_LIBADD = \ $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) \ diff --git a/ext/dv/gstdvdemux.c b/ext/dv/gstdvdemux.c index 030824955..5261d479f 100644 --- a/ext/dv/gstdvdemux.c +++ b/ext/dv/gstdvdemux.c @@ -26,6 +26,7 @@ #include #include "gstdvdemux.h" +#include "gstsmptetimecode.h" /** * SECTION:element-dvdemux @@ -1357,6 +1358,48 @@ gst_dvdemux_demux_video (GstDVDemux * dvdemux, GstBuffer * buffer, return ret; } +static int +get_ssyb_offset (int dif, int ssyb) +{ + int offset; + + offset = dif * 12000; /* to dif */ + offset += 80 * (1 + (ssyb / 6)); /* to subcode pack */ + offset += 3; /* past header */ + offset += 8 * (ssyb % 6); /* to ssyb */ + + return offset; +} + +static gboolean +gst_dvdemux_get_timecode (GstDVDemux * dvdemux, GstBuffer * buffer, + GstSMPTETimeCode * timecode) +{ + guint8 *data = GST_BUFFER_DATA (buffer); + int offset; + int dif; + int n_difs = dvdemux->decoder->num_dif_seqs; + + for (dif = 0; dif < n_difs; dif++) { + offset = get_ssyb_offset (dif, 3); + if (data[offset + 3] == 0x13) { + timecode->frames = ((data[offset + 4] >> 4) & 0x3) * 10 + + (data[offset + 4] & 0xf); + timecode->seconds = ((data[offset + 5] >> 4) & 0x3) * 10 + + (data[offset + 5] & 0xf); + timecode->minutes = ((data[offset + 6] >> 4) & 0x3) * 10 + + (data[offset + 6] & 0xf); + timecode->hours = ((data[offset + 7] >> 4) & 0x3) * 10 + + (data[offset + 7] & 0xf); + GST_DEBUG ("got timecode %" GST_SMPTE_TIME_CODE_FORMAT, + GST_SMPTE_TIME_CODE_ARGS (timecode)); + return TRUE; + } + } + + return FALSE; +} + static gboolean gst_dvdemux_is_new_media (GstDVDemux * dvdemux, GstBuffer * buffer) { @@ -1390,6 +1433,8 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer) GstFlowReturn aret, vret, ret; guint8 *data; guint64 duration; + GstSMPTETimeCode timecode; + int frame_number; if (G_UNLIKELY (dvdemux->need_segment)) { GstEvent *event; @@ -1428,6 +1473,12 @@ gst_dvdemux_demux_frame (GstDVDemux * dvdemux, GstBuffer * buffer) dvdemux->need_segment = FALSE; } + gst_dvdemux_get_timecode (dvdemux, buffer, &timecode); + gst_smpte_time_code_get_frame_number ( + (dvdemux->decoder->system == e_dv_system_625_50) ? + GST_SMPTE_TIME_CODE_SYSTEM_25 : GST_SMPTE_TIME_CODE_SYSTEM_30, + &frame_number, &timecode); + next_ts = gst_util_uint64_scale_int ( (dvdemux->frame_offset + 1) * GST_SECOND, dvdemux->framerate_denominator, dvdemux->framerate_numerator); diff --git a/ext/dv/gstsmptetimecode.h b/ext/dv/gstsmptetimecode.h index 2f08c9244..cdda03e6f 100644 --- a/ext/dv/gstsmptetimecode.h +++ b/ext/dv/gstsmptetimecode.h @@ -50,6 +50,11 @@ struct _GstSMPTETimeCode { #define GST_SMPTE_TIME_CODE_SYSTEM_IS_VALID(x) \ ((x) >= GST_SMPTE_TIME_CODE_SYSTEM_30 && (x) <= GST_SMPTE_TIME_CODE_SYSTEM_24) +#define GST_SMPTE_TIME_CODE_FORMAT "02d:%02d:%02d:%02d" +#define GST_SMPTE_TIME_CODE_ARGS(timecode) \ + (timecode)->hours, (timecode)->minutes, \ + (timecode)->seconds, (timecode)->frames + gboolean gst_smpte_time_code_is_valid (GstSMPTETimeCodeSystem system, GstSMPTETimeCode *time_code); gboolean gst_smpte_time_code_from_frame_number (GstSMPTETimeCodeSystem system,