[MPlayer-cvslog] CVS: main/libmpdemux demux_mpg.c, 1.63, 1.64 demuxer.h, 1.82, 1.83 parse_es.c, 1.7, 1.8

Reimar Döffinger CVS syncmail at mplayerhq.hu
Sat Sep 3 10:58:37 CEST 2005


CVS change done by Reimar Döffinger CVS

Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var2/tmp/cvs-serv24340/libmpdemux

Modified Files:
	demux_mpg.c demuxer.h parse_es.c 
Log Message:
faster mpg and much faster gxf demuxing


Index: demux_mpg.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demux_mpg.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -r1.63 -r1.64
--- demux_mpg.c	2 Sep 2005 08:32:32 -0000	1.63
+++ demux_mpg.c	3 Sep 2005 08:58:34 -0000	1.64
@@ -506,33 +506,70 @@
   return 1;
 }
 
+/**
+ * \brief discard until 0x100 header and return a filled buffer
+ * \param b buffer-end pointer
+ * \param pos current pos in stream, negative since b points to end of buffer
+ * \param s stream to read from
+ * \return new position, differs from original pos when eof hit and thus
+ *             b was modified to point to the new end of buffer
+ */
+static int find_end(unsigned char **b, int pos, stream_t *s) {
+  register int state = 0xffffffff;
+  unsigned char *buf = *b;
+  int start = pos;
+  int read, unused;
+  // search already read part
+  while (state != 0x100 && pos) {
+    state = state << 8 | buf[pos++];
+  }
+  // continue search in stream
+  while (state != 0x100) {
+    register int c = stream_read_char(s);
+    if (c < 0) break;
+    state = state << 8 | c;
+  }
+  // modify previous header (from 0x1bc or 0x1bf to 0x100)
+  buf[start++] = 0;
+  // copy remaining buffer part to current pos
+  memmove(&buf[start], &buf[pos], -pos);
+  unused = start + -pos; // -unused bytes in buffer
+  read = stream_read(s, &buf[unused], -unused);
+  unused += read;
+  // fix buffer so it ends at pos == 0 (eof case)
+  *b = &buf[unused];
+  start -= unused;
+  return start;
+}
+
+/**
+ * This format usually uses an insane bitrate, which makes this function
+ * performance-critical!
+ * Be sure to benchmark any changes with different compiler versions.
+ */
 static int demux_mpg_gxf_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
   demux_packet_t *pack;
-  uint32_t state = (uint32_t)demux->priv;
-  int pos = 0;
-  int discard = 0;
-  unsigned char *buf;
-  if (demux->stream->eof)
-    return 0;
+  int len;
   demux->filepos = stream_tell(demux->stream);
   pack = new_demux_packet(STREAM_BUFFER_SIZE);
-  buf = pack->buffer;
-  while (pos < STREAM_BUFFER_SIZE) {
-    register int c = stream_read_char(demux->stream);
-    if (c < 0) { // EOF
-      resize_demux_packet(pack, pos);
-      break;
-    }
-    state = state << 8 | c;
-    if (state == 0x1bc || state == 0x1bf)
-      discard = 1;
-    else if (state == 0x100)
-      discard = 0;
-    if (!discard)
-      buf[pos++] = c;
+  len = stream_read(demux->stream, pack->buffer, STREAM_BUFFER_SIZE);
+  if (len <= 0)
+    return 0;
+  {
+    register uint32_t state = (uint32_t)demux->priv;
+    register int pos = -len;
+    unsigned char *buf = &pack->buffer[len];
+    do {
+      state = state << 8 | buf[pos];
+      if (unlikely((state | 3) == 0x1bf))
+        pos = find_end(&buf, pos, demux->stream);
+    } while (++pos);
+    demux->priv = (void *)state;
+    len = buf - pack->buffer;
   }
+  if (len < STREAM_BUFFER_SIZE)
+    resize_demux_packet(pack, len);
   ds_add_packet(ds, pack);
-  demux->priv = (void *)state;
   return 1;
 }
 

Index: demuxer.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.h,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -r1.82 -r1.83
--- demuxer.h	2 Sep 2005 08:32:32 -0000	1.82
+++ demuxer.h	3 Sep 2005 08:58:34 -0000	1.83
@@ -259,8 +259,8 @@
 
 #if 1
 #define demux_getc(ds) (\
-     (ds->buffer_pos<ds->buffer_size) ? ds->buffer[ds->buffer_pos++] \
-     :((!ds_fill_buffer(ds))? (-1) : ds->buffer[ds->buffer_pos++] ) )
+     (likely(ds->buffer_pos<ds->buffer_size)) ? ds->buffer[ds->buffer_pos++] \
+     :((unlikely(!ds_fill_buffer(ds)))? (-1) : ds->buffer[ds->buffer_pos++] ) )
 #else
 inline static int demux_getc(demux_stream_t *ds){
   if(ds->buffer_pos>=ds->buffer_size){

Index: parse_es.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/parse_es.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- parse_es.c	30 Oct 2001 17:03:11 -0000	1.7
+++ parse_es.c	3 Sep 2005 08:58:34 -0000	1.8
@@ -53,6 +53,8 @@
 int read_video_packet(demux_stream_t *ds){
 int packet_start;
   
+  if (VIDEOBUFFER_SIZE - videobuf_len < 5)
+    return 0;
   // SYNC STREAM
 //  if(!sync_video_packet(ds)) return 0; // cannot sync (EOF)
 
@@ -65,21 +67,20 @@
   videobuf_len+=4;
   
   // READ PACKET:
-  { unsigned int head=-1;
-    while(videobuf_len<VIDEOBUFFER_SIZE){
+  {
+    register uint32_t head = 0xffffffff;
+    register unsigned char *buf = &videobuffer[VIDEOBUFFER_SIZE];
+    register int pos = videobuf_len - VIDEOBUFFER_SIZE;
+    do {
       int c=demux_getc(ds);
       if(c<0) break; // EOF
-      videobuffer[videobuf_len++]=c;
-#if 1
+      buf[pos]=c;
       head<<=8;
       if(head==0x100) break; // synced
       head|=c;
-#else
-      if(videobuffer[videobuf_len-4]==0 &&
-         videobuffer[videobuf_len-3]==0 &&
-         videobuffer[videobuf_len-2]==1) break; // synced
-#endif
-    }
+    } while (++pos);
+    if (pos) pos++; // increment missed because of break
+    videobuf_len = &buf[pos] - videobuffer;
   }
   
   if(ds->eof){




More information about the MPlayer-cvslog mailing list