mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
mpegtsdemux: added autodetect of packet size and removed m2ts mode property
This commit is contained in:
parent
e7f883a272
commit
659e90f8f6
2 changed files with 35 additions and 39 deletions
|
@ -103,7 +103,6 @@ enum
|
||||||
PROP_PROGRAM_NUMBER,
|
PROP_PROGRAM_NUMBER,
|
||||||
PROP_PAT_INFO,
|
PROP_PAT_INFO,
|
||||||
PROP_PMT_INFO,
|
PROP_PMT_INFO,
|
||||||
PROP_M2TS
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GSTTIME_TO_BYTES(time) \
|
#define GSTTIME_TO_BYTES(time) \
|
||||||
|
@ -307,11 +306,6 @@ gst_mpegts_demux_class_init (GstMpegTSDemuxClass * klass)
|
||||||
"about the currently selected program and its streams",
|
"about the currently selected program and its streams",
|
||||||
MPEGTS_TYPE_PMT_INFO, G_PARAM_READABLE));
|
MPEGTS_TYPE_PMT_INFO, G_PARAM_READABLE));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_M2TS,
|
|
||||||
g_param_spec_boolean ("m2ts_mode", "M2TS(192 bytes) Mode",
|
|
||||||
"Defines if the input is normal TS ie .ts(188 bytes)"
|
|
||||||
"or Blue-Ray Format ie .m2ts(192 bytes).", FALSE, G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
gstelement_class->change_state = gst_mpegts_demux_change_state;
|
gstelement_class->change_state = gst_mpegts_demux_change_state;
|
||||||
gstelement_class->provide_clock = gst_mpegts_demux_provide_clock;
|
gstelement_class->provide_clock = gst_mpegts_demux_provide_clock;
|
||||||
}
|
}
|
||||||
|
@ -333,8 +327,6 @@ gst_mpegts_demux_init (GstMpegTSDemux * demux)
|
||||||
demux->nb_elementary_pids = 0;
|
demux->nb_elementary_pids = 0;
|
||||||
demux->check_crc = DEFAULT_PROP_CHECK_CRC;
|
demux->check_crc = DEFAULT_PROP_CHECK_CRC;
|
||||||
demux->program_number = DEFAULT_PROP_PROGRAM_NUMBER;
|
demux->program_number = DEFAULT_PROP_PROGRAM_NUMBER;
|
||||||
demux->packetsize = MPEGTS_NORMAL_TS_PACKETSIZE;
|
|
||||||
demux->m2ts_mode = FALSE;
|
|
||||||
demux->sync_lut = NULL;
|
demux->sync_lut = NULL;
|
||||||
demux->sync_lut_len = 0;
|
demux->sync_lut_len = 0;
|
||||||
demux->bitrate = -1;
|
demux->bitrate = -1;
|
||||||
|
@ -487,34 +479,18 @@ static gboolean
|
||||||
gst_mpegts_demux_sink_setcaps (GstPad * pad, GstCaps * caps)
|
gst_mpegts_demux_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
|
GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
|
||||||
gboolean ret = FALSE;
|
|
||||||
GstStructure *structure = NULL;
|
GstStructure *structure = NULL;
|
||||||
gint expected_packetsize =
|
|
||||||
(demux->m2ts_mode ? MPEGTS_M2TS_TS_PACKETSIZE :
|
|
||||||
MPEGTS_NORMAL_TS_PACKETSIZE);
|
|
||||||
gint packetsize = expected_packetsize;
|
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "setcaps called with %" GST_PTR_FORMAT, caps);
|
GST_DEBUG_OBJECT (demux, "setcaps called with %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
if (!gst_structure_get_int (structure, "packetsize", &packetsize)) {
|
if (!gst_structure_get_int (structure, "packetsize", &demux->packetsize)) {
|
||||||
GST_DEBUG_OBJECT (demux, "packetsize parameter not found in sink caps");
|
GST_DEBUG_OBJECT (demux, "packetsize parameter not found in sink caps");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packetsize < expected_packetsize) {
|
|
||||||
GST_WARNING_OBJECT (demux, "packetsize = %" G_GINT32_FORMAT "is less then"
|
|
||||||
"expected packetsize of %d bytes", packetsize, expected_packetsize);
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* here we my have a correct value for packet size */
|
|
||||||
demux->packetsize = packetsize;
|
|
||||||
ret = TRUE;
|
|
||||||
|
|
||||||
beach:
|
|
||||||
gst_object_unref (demux);
|
gst_object_unref (demux);
|
||||||
return ret;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE guint32
|
static FORCE_INLINE guint32
|
||||||
|
@ -2901,6 +2877,26 @@ is_mpegts_sync (const guint8 * in_data, const guint8 * end_data,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gst_mpegts_demux_detect_packet_size (GstMpegTSDemux * demux, guint len)
|
||||||
|
{
|
||||||
|
guint i, packetsize;
|
||||||
|
|
||||||
|
for (i = 1; i < len; i++) {
|
||||||
|
packetsize = demux->sync_lut[i] - demux->sync_lut[i - 1];
|
||||||
|
if (packetsize == MPEGTS_NORMAL_TS_PACKETSIZE ||
|
||||||
|
packetsize == MPEGTS_M2TS_TS_PACKETSIZE ||
|
||||||
|
packetsize == MPEGTS_DVB_ASI_TS_PACKETSIZE ||
|
||||||
|
packetsize == MPEGTS_ATSC_TS_PACKETSIZE)
|
||||||
|
goto done;
|
||||||
|
else
|
||||||
|
packetsize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
demux->packetsize = (packetsize ? packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
|
||||||
|
GST_DEBUG_OBJECT (demux, "packet_size set to %d bytes", demux->packetsize);
|
||||||
|
}
|
||||||
|
|
||||||
static FORCE_INLINE guint
|
static FORCE_INLINE guint
|
||||||
gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
|
gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
|
||||||
|
@ -2909,10 +2905,12 @@ gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
|
||||||
guint sync_count = 0;
|
guint sync_count = 0;
|
||||||
const guint8 *end_scan = in_data + size - demux->packetsize;
|
const guint8 *end_scan = in_data + size - demux->packetsize;
|
||||||
guint8 *ptr_data = (guint8 *) in_data;
|
guint8 *ptr_data = (guint8 *) in_data;
|
||||||
|
guint packetsize =
|
||||||
|
(demux->packetsize ? demux->packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
|
||||||
|
|
||||||
/* Check if the LUT table is big enough */
|
/* Check if the LUT table is big enough */
|
||||||
if (G_UNLIKELY (demux->sync_lut_len < (size / MPEGTS_NORMAL_TS_PACKETSIZE))) {
|
if (G_UNLIKELY (demux->sync_lut_len < (size / packetsize))) {
|
||||||
demux->sync_lut_len = size / MPEGTS_NORMAL_TS_PACKETSIZE;
|
demux->sync_lut_len = size / packetsize;
|
||||||
if (demux->sync_lut)
|
if (demux->sync_lut)
|
||||||
g_free (demux->sync_lut);
|
g_free (demux->sync_lut);
|
||||||
demux->sync_lut = g_new0 (guint8 *, demux->sync_lut_len);
|
demux->sync_lut = g_new0 (guint8 *, demux->sync_lut_len);
|
||||||
|
@ -2922,22 +2920,24 @@ gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
|
||||||
|
|
||||||
while (ptr_data <= end_scan && sync_count < demux->sync_lut_len) {
|
while (ptr_data <= end_scan && sync_count < demux->sync_lut_len) {
|
||||||
/* if sync code is found try to store it in the LUT */
|
/* if sync code is found try to store it in the LUT */
|
||||||
guint chance = is_mpegts_sync (ptr_data, end_scan, demux->packetsize);
|
guint chance = is_mpegts_sync (ptr_data, end_scan, packetsize);
|
||||||
if (G_LIKELY (chance > 50)) {
|
if (G_LIKELY (chance > 50)) {
|
||||||
/* skip paketsize bytes and try find next */
|
/* skip paketsize bytes and try find next */
|
||||||
guint8 *next_sync = ptr_data + demux->packetsize;
|
guint8 *next_sync = ptr_data + packetsize;
|
||||||
if (next_sync < end_scan) {
|
if (next_sync < end_scan) {
|
||||||
demux->sync_lut[sync_count] = ptr_data;
|
demux->sync_lut[sync_count] = ptr_data;
|
||||||
sync_count++;
|
sync_count++;
|
||||||
ptr_data += demux->packetsize;
|
ptr_data += packetsize;
|
||||||
} else
|
} else
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ptr_data++;
|
ptr_data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
if (G_UNLIKELY (!demux->packetsize))
|
||||||
|
gst_mpegts_demux_detect_packet_size (demux, sync_count);
|
||||||
|
|
||||||
*flush = ptr_data - in_data;
|
*flush = ptr_data - in_data;
|
||||||
|
|
||||||
return sync_count;
|
return sync_count;
|
||||||
|
@ -3147,9 +3147,6 @@ gst_mpegts_demux_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_PROGRAM_NUMBER:
|
case PROP_PROGRAM_NUMBER:
|
||||||
demux->program_number = g_value_get_int (value);
|
demux->program_number = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
case PROP_M2TS:
|
|
||||||
demux->m2ts_mode = g_value_get_boolean (value);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -3200,9 +3197,6 @@ gst_mpegts_demux_get_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROP_M2TS:
|
|
||||||
g_value_set_boolean (value, demux->m2ts_mode);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -59,6 +59,8 @@ G_BEGIN_DECLS
|
||||||
#define MPEGTS_MAX_PID 0x1fff
|
#define MPEGTS_MAX_PID 0x1fff
|
||||||
#define MPEGTS_NORMAL_TS_PACKETSIZE 188
|
#define MPEGTS_NORMAL_TS_PACKETSIZE 188
|
||||||
#define MPEGTS_M2TS_TS_PACKETSIZE 192
|
#define MPEGTS_M2TS_TS_PACKETSIZE 192
|
||||||
|
#define MPEGTS_DVB_ASI_TS_PACKETSIZE 204
|
||||||
|
#define MPEGTS_ATSC_TS_PACKETSIZE 208
|
||||||
|
|
||||||
#define IS_MPEGTS_SYNC(data) (((data)[0] == 0x47) && \
|
#define IS_MPEGTS_SYNC(data) (((data)[0] == 0x47) && \
|
||||||
(((data)[1] & 0x80) == 0x00) && \
|
(((data)[1] & 0x80) == 0x00) && \
|
||||||
|
@ -200,7 +202,7 @@ struct _GstMpegTSDemux {
|
||||||
/* indicates that we need to close our pad group, because we've added
|
/* indicates that we need to close our pad group, because we've added
|
||||||
* at least one pad */
|
* at least one pad */
|
||||||
gboolean need_no_more_pads;
|
gboolean need_no_more_pads;
|
||||||
guint16 packetsize;
|
gint packetsize;
|
||||||
gboolean m2ts_mode;
|
gboolean m2ts_mode;
|
||||||
/* clocking */
|
/* clocking */
|
||||||
GstClock * clock;
|
GstClock * clock;
|
||||||
|
|
Loading…
Reference in a new issue