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

View file

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