mpegts: Stop scanning for keyframes as early as possible

This commit is contained in:
Edward Hervey 2011-05-15 14:04:45 +02:00
parent ae2e7624d6
commit 6c0254b84b
3 changed files with 27 additions and 16 deletions

View file

@ -103,7 +103,7 @@ parse_mpeg2_picture_header (Mpeg2PictureHeader * hdr, guint8 * buffer,
gboolean gboolean
gst_tsdemux_has_mpeg2_keyframe (guint32 * state, gst_tsdemux_has_mpeg2_keyframe (guint32 * state,
MpegTSPacketizerPacket * packet) MpegTSPacketizerPacket * packet, gboolean * need_more)
{ {
guint8 *data = packet->payload; guint8 *data = packet->payload;
guint8 *data_end = packet->data_end; guint8 *data_end = packet->data_end;
@ -122,6 +122,7 @@ gst_tsdemux_has_mpeg2_keyframe (guint32 * state,
if (*state == GROUP_START_CODE) { if (*state == GROUP_START_CODE) {
GST_DEBUG ("found group start code"); GST_DEBUG ("found group start code");
*state = 0xffffffff; *state = 0xffffffff;
*need_more = FALSE;
return TRUE; return TRUE;
} else if (*state == PICTURE_START_CODE) { } else if (*state == PICTURE_START_CODE) {
Mpeg2PictureHeader hdr = { 0 }; Mpeg2PictureHeader hdr = { 0 };
@ -132,6 +133,7 @@ gst_tsdemux_has_mpeg2_keyframe (guint32 * state,
success ? "" : "not ", hdr.picture_coding_type); success ? "" : "not ", hdr.picture_coding_type);
*state = 0xffffffff; *state = 0xffffffff;
*need_more = FALSE;
return success && hdr.picture_coding_type == 1; return success && hdr.picture_coding_type == 1;
} }
} }
@ -210,7 +212,8 @@ is_key_slice (guint8 slice_type)
} }
gboolean gboolean
gst_tsdemux_has_h264_keyframe (guint32 * state, MpegTSPacketizerPacket * packet) gst_tsdemux_has_h264_keyframe (guint32 * state, MpegTSPacketizerPacket * packet,
gboolean * need_more)
{ {
guint8 *data = packet->payload; guint8 *data = packet->payload;
guint8 *data_end = packet->data_end; guint8 *data_end = packet->data_end;
@ -243,6 +246,7 @@ gst_tsdemux_has_h264_keyframe (guint32 * state, MpegTSPacketizerPacket * packet)
case SLICE_IDR_NAL_UNIT_TYPE: case SLICE_IDR_NAL_UNIT_TYPE:
GST_DEBUG ("found SLICE_IDR NAL unit type"); GST_DEBUG ("found SLICE_IDR NAL unit type");
*state = 0xffffffff; *state = 0xffffffff;
*need_more = FALSE;
return TRUE; return TRUE;
case SLICE_NAL_UNIT_TYPE: case SLICE_NAL_UNIT_TYPE:
{ {
@ -254,6 +258,7 @@ gst_tsdemux_has_h264_keyframe (guint32 * state, MpegTSPacketizerPacket * packet)
hdr.slice_type); hdr.slice_type);
*state = 0xffffffff; *state = 0xffffffff;
*need_more = FALSE;
return success && is_key_slice (hdr.slice_type); return success && is_key_slice (hdr.slice_type);
} }
case SEI_NAL_UNIT_TYPE: case SEI_NAL_UNIT_TYPE:

View file

@ -23,10 +23,14 @@
#include "mpegtspacketizer.h" #include "mpegtspacketizer.h"
typedef gboolean (*payload_parse_keyframe) (guint32 *state, MpegTSPacketizerPacket * packet); typedef gboolean (*payload_parse_keyframe) (guint32 *state,
MpegTSPacketizerPacket * packet,
gboolean *need_more);
gboolean gboolean gst_tsdemux_has_mpeg2_keyframe (guint32 *state,
gst_tsdemux_has_mpeg2_keyframe (guint32 *state, MpegTSPacketizerPacket * packet); MpegTSPacketizerPacket * packet,
gboolean *need_more);
gboolean gboolean gst_tsdemux_has_h264_keyframe (guint32 *state,
gst_tsdemux_has_h264_keyframe (guint32 *state, MpegTSPacketizerPacket * packet); MpegTSPacketizerPacket * packet,
gboolean *need_more);

View file

@ -530,7 +530,7 @@ gst_ts_demux_perform_auxiliary_seek (MpegTSBase * base, GstClockTime seektime,
GstTSDemux *demux = (GstTSDemux *) base; GstTSDemux *demux = (GstTSDemux *) base;
GstFlowReturn res = GST_FLOW_ERROR; GstFlowReturn res = GST_FLOW_ERROR;
gboolean done = FALSE; gboolean done = FALSE;
gboolean found_keyframe = FALSE, found_accurate = FALSE; gboolean found_keyframe = FALSE, found_accurate = FALSE, need_more = TRUE;
GstBuffer *buf; GstBuffer *buf;
MpegTSPacketizerPacket packet; MpegTSPacketizerPacket packet;
MpegTSPacketizerPacketReturn pret; MpegTSPacketizerPacketReturn pret;
@ -590,17 +590,19 @@ gst_ts_demux_perform_auxiliary_seek (MpegTSBase * base, GstClockTime seektime,
goto next; goto next;
/* reset state for new packet */ /* reset state for new packet */
state = 0xffffffff; state = 0xffffffff;
need_more = TRUE;
} }
if (auxiliary_seek_fn) { if (auxiliary_seek_fn) {
gboolean is_keyframe = auxiliary_seek_fn (&state, &packet); if (need_more) {
if (is_keyframe) { if (auxiliary_seek_fn (&state, &packet, &need_more)) {
found_keyframe = TRUE; found_keyframe = TRUE;
key_pos = *pcroffset; key_pos = *pcroffset;
GST_DEBUG ("found keyframe: time: %" GST_TIME_FORMAT " pcr: %" GST_DEBUG ("found keyframe: time: %" GST_TIME_FORMAT " pcr: %"
GST_TIME_FORMAT " offset %" G_GINT64_FORMAT, GST_TIME_FORMAT " offset %" G_GINT64_FORMAT,
GST_TIME_ARGS (pcroffset->gsttime), GST_TIME_ARGS (pcroffset->gsttime),
GST_TIME_ARGS (pcroffset->pcr), pcroffset->offset); GST_TIME_ARGS (pcroffset->pcr), pcroffset->offset);
}
} }
} else { } else {
/* if we don't have a payload parsing function /* if we don't have a payload parsing function