mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
mpegpsdemux: limit the amount of scanning done on duration queries
Limit the amount of data scanned when looking for PTSes in duration queries as a failsafe for kinda broken, potentially large files with sparse or no PTSes.
This commit is contained in:
parent
0961e2f494
commit
8fb0beaf00
1 changed files with 27 additions and 13 deletions
|
@ -60,6 +60,8 @@
|
||||||
#define SEGMENT_THRESHOLD (300*GST_MSECOND)
|
#define SEGMENT_THRESHOLD (300*GST_MSECOND)
|
||||||
#define VIDEO_SEGMENT_THRESHOLD (500*GST_MSECOND)
|
#define VIDEO_SEGMENT_THRESHOLD (500*GST_MSECOND)
|
||||||
|
|
||||||
|
#define DURATION_SCAN_LIMIT 4 * 1024 * 1024
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SCAN_SCR,
|
SCAN_SCR,
|
||||||
|
@ -154,9 +156,9 @@ static GstStateChangeReturn gst_flups_demux_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
|
||||||
static inline gboolean gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux,
|
static inline gboolean gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux,
|
||||||
guint64 * pos, SCAN_MODE mode, guint64 * rts);
|
guint64 * pos, SCAN_MODE mode, guint64 * rts, gint limit);
|
||||||
static inline gboolean gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux,
|
static inline gboolean gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux,
|
||||||
guint64 * pos, SCAN_MODE mode, guint64 * rts);
|
guint64 * pos, SCAN_MODE mode, guint64 * rts, gint limit);
|
||||||
|
|
||||||
static inline void gst_flups_demux_send_segment_updates (GstFluPSDemux * demux,
|
static inline void gst_flups_demux_send_segment_updates (GstFluPSDemux * demux,
|
||||||
GstClockTime new_time);
|
GstClockTime new_time);
|
||||||
|
@ -1051,19 +1053,22 @@ gst_flups_demux_do_seek (GstFluPSDemux * demux, GstSegment * seeksegment)
|
||||||
MIN (gst_util_uint64_scale (scr - demux->first_scr, scr_rate_n,
|
MIN (gst_util_uint64_scale (scr - demux->first_scr, scr_rate_n,
|
||||||
scr_rate_d), demux->sink_segment.stop);
|
scr_rate_d), demux->sink_segment.stop);
|
||||||
|
|
||||||
found = gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr);
|
found = gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
found = gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr);
|
found =
|
||||||
|
gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (found && fscr < scr) {
|
while (found && fscr < scr) {
|
||||||
offset++;
|
offset++;
|
||||||
found = gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr);
|
found =
|
||||||
|
gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (found && fscr > scr && offset > 0) {
|
while (found && fscr > scr && offset > 0) {
|
||||||
offset--;
|
offset--;
|
||||||
found = gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr);
|
found =
|
||||||
|
gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_INFO_OBJECT (demux, "doing seek at offset %" G_GUINT64_FORMAT
|
GST_INFO_OBJECT (demux, "doing seek at offset %" G_GUINT64_FORMAT
|
||||||
|
@ -2382,7 +2387,7 @@ beach:
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux, guint64 * pos,
|
gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux, guint64 * pos,
|
||||||
SCAN_MODE mode, guint64 * rts)
|
SCAN_MODE mode, guint64 * rts, gint limit)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
|
@ -2398,6 +2403,9 @@ gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux, guint64 * pos,
|
||||||
if (offset + scan_sz > demux->sink_segment.stop)
|
if (offset + scan_sz > demux->sink_segment.stop)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (limit && offset > *pos + limit)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (offset + to_read > demux->sink_segment.stop)
|
if (offset + to_read > demux->sink_segment.stop)
|
||||||
to_read = demux->sink_segment.stop - offset;
|
to_read = demux->sink_segment.stop - offset;
|
||||||
|
|
||||||
|
@ -2435,7 +2443,7 @@ gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux, guint64 * pos,
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux, guint64 * pos,
|
gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux, guint64 * pos,
|
||||||
SCAN_MODE mode, guint64 * rts)
|
SCAN_MODE mode, guint64 * rts, gint limit)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
|
@ -2451,6 +2459,9 @@ gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux, guint64 * pos,
|
||||||
if (offset < scan_sz - 1)
|
if (offset < scan_sz - 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (limit && offset < *pos - limit)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (offset > BLOCK_SZ)
|
if (offset > BLOCK_SZ)
|
||||||
offset -= BLOCK_SZ;
|
offset -= BLOCK_SZ;
|
||||||
else {
|
else {
|
||||||
|
@ -2522,7 +2533,8 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
|
||||||
/* Scan for notorious SCR and PTS to calculate the duration */
|
/* Scan for notorious SCR and PTS to calculate the duration */
|
||||||
/* scan for first SCR in the stream */
|
/* scan for first SCR in the stream */
|
||||||
offset = demux->sink_segment.start;
|
offset = demux->sink_segment.start;
|
||||||
gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &demux->first_scr);
|
gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &demux->first_scr,
|
||||||
|
DURATION_SCAN_LIMIT);
|
||||||
GST_DEBUG_OBJECT (demux, "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
GST_DEBUG_OBJECT (demux, "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
||||||
" in packet starting at %" G_GUINT64_FORMAT,
|
" in packet starting at %" G_GUINT64_FORMAT,
|
||||||
demux->first_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)),
|
demux->first_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)),
|
||||||
|
@ -2530,7 +2542,8 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
|
||||||
demux->first_scr_offset = offset;
|
demux->first_scr_offset = offset;
|
||||||
/* scan for last SCR in the stream */
|
/* scan for last SCR in the stream */
|
||||||
offset = demux->sink_segment.stop;
|
offset = demux->sink_segment.stop;
|
||||||
gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &demux->last_scr);
|
gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR,
|
||||||
|
&demux->last_scr, 0);
|
||||||
GST_DEBUG_OBJECT (demux, "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
GST_DEBUG_OBJECT (demux, "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
||||||
" in packet starting at %" G_GUINT64_FORMAT,
|
" in packet starting at %" G_GUINT64_FORMAT,
|
||||||
demux->last_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)),
|
demux->last_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)),
|
||||||
|
@ -2538,7 +2551,8 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
|
||||||
demux->last_scr_offset = offset;
|
demux->last_scr_offset = offset;
|
||||||
/* scan for first PTS in the stream */
|
/* scan for first PTS in the stream */
|
||||||
offset = demux->sink_segment.start;
|
offset = demux->sink_segment.start;
|
||||||
gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_PTS, &demux->first_pts);
|
gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_PTS, &demux->first_pts,
|
||||||
|
DURATION_SCAN_LIMIT);
|
||||||
GST_DEBUG_OBJECT (demux, "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
GST_DEBUG_OBJECT (demux, "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
||||||
" in packet starting at %" G_GUINT64_FORMAT,
|
" in packet starting at %" G_GUINT64_FORMAT,
|
||||||
demux->first_pts, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)),
|
demux->first_pts, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)),
|
||||||
|
@ -2547,7 +2561,7 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
|
||||||
/* scan for last PTS in the stream */
|
/* scan for last PTS in the stream */
|
||||||
offset = demux->sink_segment.stop;
|
offset = demux->sink_segment.stop;
|
||||||
gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_PTS,
|
gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_PTS,
|
||||||
&demux->last_pts);
|
&demux->last_pts, DURATION_SCAN_LIMIT);
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Last PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
"Last PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
|
||||||
" in packet starting at %" G_GUINT64_FORMAT, demux->last_pts,
|
" in packet starting at %" G_GUINT64_FORMAT, demux->last_pts,
|
||||||
|
@ -2560,7 +2574,7 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
|
||||||
offset = demux->first_scr_offset;
|
offset = demux->first_scr_offset;
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
offset++;
|
offset++;
|
||||||
gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &scr);
|
gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &scr, 0);
|
||||||
if (scr < demux->last_scr) {
|
if (scr < demux->last_scr) {
|
||||||
demux->first_scr = scr;
|
demux->first_scr = scr;
|
||||||
demux->first_scr_offset = offset;
|
demux->first_scr_offset = offset;
|
||||||
|
|
Loading…
Reference in a new issue