summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@collabora.com>2013-06-15 20:22:09 +0200
committerEdward Hervey <edward@collabora.com>2013-07-30 08:27:05 +0200
commit7c532b2797ac9c580dd5ef097d303da2dded9cae (patch)
tree2bb36974fc9fef2d96c8eeda0f37ca1c573af3aa
parentb17b0047216ec20ace503cafafdbb866149961bf (diff)
codecparsers: Make all parsers use fast start code methodh264parser
This was added in 920053dae6957ded976b18ff8e111a242a077617 but only in the mpeg video parser. We now make mpeg video (1,2,4), h264 and vc1 parser make use of it. Makes scanning for start codes 4.5 times faster, and overall h264 parsing 4 times faster. (When not working in passthrough obviously). https://bugzilla.gnome.org/show_bug.cgi?id=702357
-rw-r--r--gst-libs/gst/codecparsers/gsth264parser.c10
-rw-r--r--gst-libs/gst/codecparsers/gstmpeg4parser.c6
-rw-r--r--gst-libs/gst/codecparsers/gstmpegvideoparser.c38
-rw-r--r--gst-libs/gst/codecparsers/gstvc1parser.c10
-rw-r--r--gst-libs/gst/codecparsers/parserutils.h45
5 files changed, 49 insertions, 60 deletions
diff --git a/gst-libs/gst/codecparsers/gsth264parser.c b/gst-libs/gst/codecparsers/gsth264parser.c
index bd769146e..0c0b11df9 100644
--- a/gst-libs/gst/codecparsers/gsth264parser.c
+++ b/gst-libs/gst/codecparsers/gsth264parser.c
@@ -495,16 +495,6 @@ set_nalu_datas (GstH264NalUnit * nalu)
GST_DEBUG ("Nal type %u, ref_idc %u", nalu->type, nalu->ref_idc);
}
-static inline gint
-scan_for_start_codes (const guint8 * data, guint size)
-{
- GstByteReader br;
- gst_byte_reader_init (&br, data, size);
-
- /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
- return gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
- 0, size);
-}
static gboolean
gst_h264_parser_more_data (NalReader * nr)
diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c
index 5acc4178e..17e3632c2 100644
--- a/gst-libs/gst/codecparsers/gstmpeg4parser.c
+++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c
@@ -461,8 +461,7 @@ gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
first_resync_marker = TRUE;
}
- off1 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
- offset, size - offset);
+ off1 = br_scan_for_start_codes (&br, offset, size - offset);
if (off1 == -1) {
GST_DEBUG ("No start code prefix in this buffer");
@@ -480,8 +479,7 @@ gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
packet->type = (GstMpeg4StartCode) (data[off1 + 3]);
find_end:
- off2 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
- off1 + 4, size - off1 - 4);
+ off2 = br_scan_for_start_codes (&br, off1 + 4, size - off1 - 4);
if (off2 == -1) {
GST_DEBUG ("Packet start %d, No end found", off1 + 4);
diff --git a/gst-libs/gst/codecparsers/gstmpegvideoparser.c b/gst-libs/gst/codecparsers/gstmpegvideoparser.c
index af3191154..0162b20d8 100644
--- a/gst-libs/gst/codecparsers/gstmpegvideoparser.c
+++ b/gst-libs/gst/codecparsers/gstmpegvideoparser.c
@@ -199,40 +199,6 @@ set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
}
}
-/* @size and @offset are wrt current reader position */
-static inline guint
-scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
-{
- const guint8 *data;
- guint i = 0;
-
- g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
- -1);
-
- /* we can't find the pattern with less than 4 bytes */
- if (G_UNLIKELY (size < 4))
- return -1;
-
- data = reader->data + reader->byte + offset;
-
- while (i <= (size - 4)) {
- if (data[i + 2] > 1) {
- i += 3;
- } else if (data[i + 1]) {
- i += 2;
- } else if (data[i] || data[i + 2] != 1) {
- i++;
- } else {
- break;
- }
- }
-
- if (i <= (size - 4))
- return offset + i;
-
- /* nothing found */
- return -1;
-}
/****** API *******/
@@ -268,7 +234,7 @@ gst_mpeg_video_parse (GstMpegVideoPacket * packet,
size -= offset;
gst_byte_reader_init (&br, &data[offset], size);
- off = scan_for_start_codes (&br, 0, size);
+ off = br_scan_for_start_codes (&br, 0, size);
if (off < 0) {
GST_DEBUG ("No start code prefix in this buffer");
@@ -287,7 +253,7 @@ gst_mpeg_video_parse (GstMpegVideoPacket * packet,
/* try to find end of packet */
size -= off + 4;
- off = scan_for_start_codes (&br, 0, size);
+ off = br_scan_for_start_codes (&br, 0, size);
if (off > 0)
packet->size = off;
diff --git a/gst-libs/gst/codecparsers/gstvc1parser.c b/gst-libs/gst/codecparsers/gstvc1parser.c
index 84817bbf8..f1b006364 100644
--- a/gst-libs/gst/codecparsers/gstvc1parser.c
+++ b/gst-libs/gst/codecparsers/gstvc1parser.c
@@ -679,16 +679,6 @@ failed:
return FALSE;
}
-static inline gint
-scan_for_start_codes (const guint8 * data, guint size)
-{
- GstByteReader br;
- gst_byte_reader_init (&br, data, size);
-
- /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
- return gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
- 0, size);
-}
static inline gint
get_unary (GstBitReader * br, gint stop, gint len)
diff --git a/gst-libs/gst/codecparsers/parserutils.h b/gst-libs/gst/codecparsers/parserutils.h
index 6b54ded74..bc8c1b57a 100644
--- a/gst-libs/gst/codecparsers/parserutils.h
+++ b/gst-libs/gst/codecparsers/parserutils.h
@@ -24,6 +24,7 @@
#include <gst/gst.h>
#include <gst/base/gstbitreader.h>
+#include <gst/base/gstbytereader.h>
/* Parsing utils */
#define GET_BITS(b, num, bits) G_STMT_START { \
@@ -92,6 +93,50 @@
} \
} G_STMT_END
+static inline gint
+scan_for_start_codes (const guint8 * data, guint size)
+{
+ guint i = 0;
+
+ /* we can't find the pattern with less than 4 bytes */
+ if (G_UNLIKELY (size < 4))
+ return -1;
+
+ while (i <= (size - 4)) {
+ if (data[i + 2] > 1) {
+ i += 3;
+ } else if (data[i + 1]) {
+ i += 2;
+ } else if (data[i] || data[i + 2] != 1) {
+ i++;
+ } else {
+ break;
+ }
+ }
+
+ if (i <= (size - 4))
+ return i;
+
+ /* nothing found */
+ return -1;
+}
+
+/* @size and @offset are wrt current reader position */
+static inline guint
+br_scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
+{
+ guint ret;
+
+ g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
+ -1);
+
+ ret = scan_for_start_codes (reader->data + reader->byte + offset, size);
+ if (ret < 0)
+ return ret;
+
+ return ret + offset;
+}
+
typedef struct _VLCTable VLCTable;
struct _VLCTable