mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
hdvparse: Emit a GST_MESSAGE_ELEMENT with some goodness in it.
This commit is contained in:
parent
37254a21f4
commit
0e1ee9031a
1 changed files with 67 additions and 18 deletions
|
@ -69,7 +69,7 @@ enum
|
||||||
|
|
||||||
/* If set to 1, then extra validation will be applied to check
|
/* If set to 1, then extra validation will be applied to check
|
||||||
* for complete spec compliance wherever applicable. */
|
* for complete spec compliance wherever applicable. */
|
||||||
#define VALIDATE 1
|
#define VALIDATE 0
|
||||||
|
|
||||||
/* Binary-coded decimal reading macro */
|
/* Binary-coded decimal reading macro */
|
||||||
#define BCD(c) ( ((((c) >> 4) & 0x0f) * 10) + ((c) & 0x0f) )
|
#define BCD(c) ( ((((c) >> 4) & 0x0f) * 10) + ((c) & 0x0f) )
|
||||||
|
@ -186,7 +186,8 @@ sfr_to_framerate (guint8 sfr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
parse_dv_multi_pack (GstHDVParse * filter, guint8 * data, guint64 size)
|
parse_dv_multi_pack (GstHDVParse * filter, guint8 * data, guint64 size,
|
||||||
|
GstStructure * st)
|
||||||
{
|
{
|
||||||
guint64 offs = 1;
|
guint64 offs = 1;
|
||||||
|
|
||||||
|
@ -208,12 +209,15 @@ parse_dv_multi_pack (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
|
|
||||||
GST_LOG (" Iris position %d (0x%x)", irispos, irispos);
|
GST_LOG (" Iris position %d (0x%x)", irispos, irispos);
|
||||||
/* Iris position = 2 ^ (IP/8) (for 0 < IP < 0x3C) */
|
/* Iris position = 2 ^ (IP/8) (for 0 < IP < 0x3C) */
|
||||||
if (irispos < 0x3c)
|
if (irispos < 0x3c) {
|
||||||
GST_LOG (" IRIS F%0.2f", powf (2.0, (((float) irispos) / 8.0)));
|
GST_LOG (" IRIS F%0.2f", powf (2.0, (((float) irispos) / 8.0)));
|
||||||
else if (irispos == 0x3d)
|
gst_structure_set (st, "aperture-fnumber", G_TYPE_FLOAT,
|
||||||
|
powf (2.0, (((float) irispos) / 8.0)), NULL);
|
||||||
|
} else if (irispos == 0x3d) {
|
||||||
GST_LOG (" IRIS < 1.0");
|
GST_LOG (" IRIS < 1.0");
|
||||||
else if (irispos == 0x3e)
|
} else if (irispos == 0x3e) {
|
||||||
GST_LOG (" IRIS closed");
|
GST_LOG (" IRIS closed");
|
||||||
|
}
|
||||||
|
|
||||||
/* AE Mode:
|
/* AE Mode:
|
||||||
* 0 : Full automatic
|
* 0 : Full automatic
|
||||||
|
@ -227,8 +231,9 @@ parse_dv_multi_pack (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
|
|
||||||
GST_LOG (" AGC: %d (0x%x)", agc, agc);
|
GST_LOG (" AGC: %d (0x%x)", agc, agc);
|
||||||
if (agc < 0xd) {
|
if (agc < 0xd) {
|
||||||
GST_LOG (" Gain:%02.2fdB", (agc - 1.0) * 1.5);
|
/* This is what the spec says.. but I'm not seeing the same on my camera :( */
|
||||||
GST_LOG (" Gain:%02.2fdB", (agc * 3.0) - 3);
|
GST_LOG (" Gain:%02.2fdB", (agc * 3.0) - 3.0);
|
||||||
|
gst_structure_set (st, "gain", G_TYPE_FLOAT, (agc * 3.0) - 3.0, NULL);
|
||||||
}
|
}
|
||||||
/* White balance mode
|
/* White balance mode
|
||||||
* 0 : Automatic
|
* 0 : Automatic
|
||||||
|
@ -301,10 +306,12 @@ parse_dv_multi_pack (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
speedint = speedint / 10 * 10;
|
speedint = speedint / 10 * 10;
|
||||||
|
|
||||||
GST_LOG (" Shutter speed : 1/%d", speedint);
|
GST_LOG (" Shutter speed : 1/%d", speedint);
|
||||||
|
gst_structure_set (st, "shutter-speed", GST_TYPE_FRACTION,
|
||||||
|
1, speedint, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gst_util_dump_mem (data + offs, 5);
|
GST_MEMDUMP ("Unknown pack", data + offs, 5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size -= 5;
|
size -= 5;
|
||||||
|
@ -314,7 +321,8 @@ parse_dv_multi_pack (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size,
|
||||||
|
GstStructure * st)
|
||||||
{
|
{
|
||||||
guint32 etn, bitrate;
|
guint32 etn, bitrate;
|
||||||
guint8 nbframes, data_h, hdr_size, sfr, sdm;
|
guint8 nbframes, data_h, hdr_size, sfr, sdm;
|
||||||
|
@ -405,6 +413,9 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
GST_LOG_OBJECT (filter, " Source Frame Rate : %s (0x%x)",
|
GST_LOG_OBJECT (filter, " Source Frame Rate : %s (0x%x)",
|
||||||
sfr_to_framerate (sfr), sfr);
|
sfr_to_framerate (sfr), sfr);
|
||||||
|
|
||||||
|
gst_structure_set (st, "DTS", G_TYPE_UINT64, MPEGTIME_TO_GSTTIME (dts),
|
||||||
|
"interlaced", G_TYPE_BOOLEAN, !pf, NULL);
|
||||||
|
|
||||||
/* Search Data Mode
|
/* Search Data Mode
|
||||||
* ---------------------------------
|
* ---------------------------------
|
||||||
* 15 | Search Data Mode |
|
* 15 | Search Data Mode |
|
||||||
|
@ -482,7 +493,6 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
(chroma == 0x1) ? "4:2:0" : "RESERVED", chroma);
|
(chroma == 0x1) ? "4:2:0" : "RESERVED", chroma);
|
||||||
GST_LOG_OBJECT (filter, " GOP N/M : %d / %d", gop_n, gop_m);
|
GST_LOG_OBJECT (filter, " GOP N/M : %d / %d", gop_n, gop_m);
|
||||||
|
|
||||||
|
|
||||||
/* data availability
|
/* data availability
|
||||||
* ---------------------------------
|
* ---------------------------------
|
||||||
* 29 | 0 | 0 | 0 | 0 | 0 |PE2|PE1|PE0|
|
* 29 | 0 | 0 | 0 | 0 | 0 |PE2|PE1|PE0|
|
||||||
|
@ -494,6 +504,8 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
if (data[29] & 0x1) {
|
if (data[29] & 0x1) {
|
||||||
guint8 fr, sec, min, hr;
|
guint8 fr, sec, min, hr;
|
||||||
gboolean bf, df;
|
gboolean bf, df;
|
||||||
|
gchar *ttcs;
|
||||||
|
|
||||||
/* HD2 TTC
|
/* HD2 TTC
|
||||||
* ---------------------------------
|
* ---------------------------------
|
||||||
* 30 |BF |DF |Tens Fr|Units of Frames|
|
* 30 |BF |DF |Tens Fr|Units of Frames|
|
||||||
|
@ -513,12 +525,19 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
hr = BCD (data[33] & 0x3f);
|
hr = BCD (data[33] & 0x3f);
|
||||||
GST_LOG_OBJECT (filter, " HD2 Title Time Code");
|
GST_LOG_OBJECT (filter, " HD2 Title Time Code");
|
||||||
GST_LOG_OBJECT (filter, " BF:%d, Drop Frame:%d", bf, df);
|
GST_LOG_OBJECT (filter, " BF:%d, Drop Frame:%d", bf, df);
|
||||||
GST_LOG_OBJECT (filter, " Timecode %02d:%02d:%02d.%02d", hr, min, sec, fr);
|
ttcs = g_strdup_printf ("%02d:%02d:%02d.%02d", hr, min, sec, fr);
|
||||||
|
GST_LOG_OBJECT (filter, " Timecode %s", ttcs);
|
||||||
/* FIXME : Use framerate information from above to convert to GstClockTime */
|
/* FIXME : Use framerate information from above to convert to GstClockTime */
|
||||||
|
gst_structure_set (st, "title-time-code", G_TYPE_STRING, ttcs, NULL);
|
||||||
|
g_free (ttcs);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[29] & 0x2) {
|
if (data[29] & 0x2) {
|
||||||
gboolean ds, tm;
|
gboolean ds, tm;
|
||||||
guint8 tz, day, dow, month, year;
|
guint8 tz, day, dow, month, year;
|
||||||
|
GDate *date;
|
||||||
|
|
||||||
/* REC DATE
|
/* REC DATE
|
||||||
* ---------------------------------
|
* ---------------------------------
|
||||||
* 34 |DS |TM |Tens TZ|Units of TimeZn|
|
* 34 |DS |TM |Tens TZ|Units of TimeZn|
|
||||||
|
@ -542,9 +561,17 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
GST_LOG_OBJECT (filter, " ds:%d, tm:%d", ds, tm);
|
GST_LOG_OBJECT (filter, " ds:%d, tm:%d", ds, tm);
|
||||||
GST_LOG_OBJECT (filter, " Timezone: %d", tz);
|
GST_LOG_OBJECT (filter, " Timezone: %d", tz);
|
||||||
GST_LOG_OBJECT (filter, " Date: %d %02d/%02d/%04d", dow, day, month, year);
|
GST_LOG_OBJECT (filter, " Date: %d %02d/%02d/%04d", dow, day, month, year);
|
||||||
|
date = g_date_new_dmy (day, month, year);
|
||||||
|
gst_structure_set (st, "date", GST_TYPE_DATE, date,
|
||||||
|
"timezone", G_TYPE_INT, tz,
|
||||||
|
"daylight-saving", G_TYPE_BOOLEAN, ds, NULL);
|
||||||
|
g_date_free (date);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[29] & 0x4) {
|
if (data[29] & 0x4) {
|
||||||
guint8 fr, sec, min, hr;
|
guint8 fr, sec, min, hr;
|
||||||
|
gchar *times;
|
||||||
|
|
||||||
/* REC TIME
|
/* REC TIME
|
||||||
* ---------------------------------
|
* ---------------------------------
|
||||||
* 38 | 1 | 1 |Tens Fr|Units of Frames|
|
* 38 | 1 | 1 |Tens Fr|Units of Frames|
|
||||||
|
@ -560,7 +587,10 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
sec = BCD (data[39] & 0x7f);
|
sec = BCD (data[39] & 0x7f);
|
||||||
min = BCD (data[40] & 0x7f);
|
min = BCD (data[40] & 0x7f);
|
||||||
hr = BCD (data[41] & 0x3f);
|
hr = BCD (data[41] & 0x3f);
|
||||||
|
times = g_strdup_printf ("%02d:%02d:%02d", hr, min, sec);
|
||||||
GST_LOG_OBJECT (filter, " REC TIME %02d:%02d:%02d.%02d", hr, min, sec, fr);
|
GST_LOG_OBJECT (filter, " REC TIME %02d:%02d:%02d.%02d", hr, min, sec, fr);
|
||||||
|
gst_structure_set (st, "time", G_TYPE_STRING, times, NULL);
|
||||||
|
g_free (times);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MISC
|
/* MISC
|
||||||
|
@ -578,6 +608,8 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
GST_LOG_OBJECT (filter, " ABST : %s",
|
GST_LOG_OBJECT (filter, " ABST : %s",
|
||||||
(abst == 0) ? "DISCONTINUITY" : "NO DISCONTINUITY");
|
(abst == 0) ? "DISCONTINUITY" : "NO DISCONTINUITY");
|
||||||
|
|
||||||
|
gst_structure_set (st, "recording-start-point", G_TYPE_BOOLEAN, !recst, NULL);
|
||||||
|
|
||||||
/* Extended DV Pack #1
|
/* Extended DV Pack #1
|
||||||
* 43 - 47
|
* 43 - 47
|
||||||
*/
|
*/
|
||||||
|
@ -598,7 +630,8 @@ parse_video_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
parse_audio_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
parse_audio_frame (GstHDVParse * filter, guint8 * data, guint64 size,
|
||||||
|
GstStructure * st)
|
||||||
{
|
{
|
||||||
guint32 etn;
|
guint32 etn;
|
||||||
guint8 nbmute, nbaau;
|
guint8 nbmute, nbaau;
|
||||||
|
@ -718,6 +751,10 @@ parse_audio_frame (GstHDVParse * filter, guint8 * data, guint64 size)
|
||||||
GST_LOG_OBJECT (filter, " CGMS : 0x%x", cgms);
|
GST_LOG_OBJECT (filter, " CGMS : 0x%x", cgms);
|
||||||
GST_LOG_OBJECT (filter, " Recording Start Point %s",
|
GST_LOG_OBJECT (filter, " Recording Start Point %s",
|
||||||
(recst) ? "ABSENT" : "PRESENT");
|
(recst) ? "ABSENT" : "PRESENT");
|
||||||
|
|
||||||
|
gst_structure_set (st, "PTS", G_TYPE_UINT64, MPEGTIME_TO_GSTTIME (pts),
|
||||||
|
"recording-start-point", G_TYPE_BOOLEAN, !recst, NULL);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,6 +765,7 @@ gst_hdvparse_parse (GstHDVParse * filter, GstBuffer * buf)
|
||||||
guint8 *data = GST_BUFFER_DATA (buf);
|
guint8 *data = GST_BUFFER_DATA (buf);
|
||||||
guint64 offs = 0;
|
guint64 offs = 0;
|
||||||
guint64 insize = GST_BUFFER_SIZE (buf);
|
guint64 insize = GST_BUFFER_SIZE (buf);
|
||||||
|
GstStructure *st;
|
||||||
|
|
||||||
/* Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
/* Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
||||||
* ---------------------------------
|
* ---------------------------------
|
||||||
|
@ -753,7 +791,7 @@ gst_hdvparse_parse (GstHDVParse * filter, GstBuffer * buf)
|
||||||
* 0x7F : AUX-N NULL PACK
|
* 0x7F : AUX-N NULL PACK
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gst_util_dump_mem (data, insize);
|
st = gst_structure_empty_new ("hdv-aux");
|
||||||
|
|
||||||
while (res == GST_FLOW_OK && (offs < insize)) {
|
while (res == GST_FLOW_OK && (offs < insize)) {
|
||||||
guint8 kw = data[offs] & 0x7f;
|
guint8 kw = data[offs] & 0x7f;
|
||||||
|
@ -767,8 +805,10 @@ gst_hdvparse_parse (GstHDVParse * filter, GstBuffer * buf)
|
||||||
|
|
||||||
/* Size validation */
|
/* Size validation */
|
||||||
GST_DEBUG ("kw:0x%x, insize:%d, offs:%d, size:%d", kw, insize, offs, size);
|
GST_DEBUG ("kw:0x%x, insize:%d, offs:%d, size:%d", kw, insize, offs, size);
|
||||||
if (insize < offs + size)
|
if (insize < offs + size) {
|
||||||
return GST_FLOW_ERROR;
|
res = GST_FLOW_ERROR;
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
|
|
||||||
switch (kw) {
|
switch (kw) {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
|
@ -780,7 +820,7 @@ gst_hdvparse_parse (GstHDVParse * filter, GstBuffer * buf)
|
||||||
break;
|
break;
|
||||||
case 0x40:
|
case 0x40:
|
||||||
GST_LOG ("Audio frame pack");
|
GST_LOG ("Audio frame pack");
|
||||||
res = parse_audio_frame (filter, data + offs + 1, size);
|
res = parse_audio_frame (filter, data + offs + 1, size, st);
|
||||||
offs += size + 2;
|
offs += size + 2;
|
||||||
break;
|
break;
|
||||||
case 0x3f:
|
case 0x3f:
|
||||||
|
@ -789,7 +829,7 @@ gst_hdvparse_parse (GstHDVParse * filter, GstBuffer * buf)
|
||||||
break;
|
break;
|
||||||
case 0x44:
|
case 0x44:
|
||||||
GST_LOG ("Video frame pack");
|
GST_LOG ("Video frame pack");
|
||||||
res = parse_video_frame (filter, data + offs + 1, size);
|
res = parse_video_frame (filter, data + offs + 1, size, st);
|
||||||
offs += size + 2;
|
offs += size + 2;
|
||||||
break;
|
break;
|
||||||
case 0x48:
|
case 0x48:
|
||||||
|
@ -797,7 +837,7 @@ gst_hdvparse_parse (GstHDVParse * filter, GstBuffer * buf)
|
||||||
case 0x4A:
|
case 0x4A:
|
||||||
case 0x4B:
|
case 0x4B:
|
||||||
GST_LOG ("DV multi-pack");
|
GST_LOG ("DV multi-pack");
|
||||||
res = parse_dv_multi_pack (filter, data + offs + 1, size);
|
res = parse_dv_multi_pack (filter, data + offs + 1, size, st);
|
||||||
offs += size + 2;
|
offs += size + 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -806,6 +846,15 @@ gst_hdvparse_parse (GstHDVParse * filter, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beach:
|
||||||
|
if (gst_structure_n_fields (st)) {
|
||||||
|
GstMessage *msg;
|
||||||
|
/* Emit the element message */
|
||||||
|
msg = gst_message_new_element (GST_OBJECT (filter), st);
|
||||||
|
gst_element_post_message (GST_ELEMENT (filter), msg);
|
||||||
|
} else
|
||||||
|
gst_structure_free (st);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue