diff options
author | reimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2005-09-03 08:58:34 +0000 |
---|---|---|
committer | reimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2005-09-03 08:58:34 +0000 |
commit | 9a684fa55fb45fcde9eede7a44998c1fe44785f8 (patch) | |
tree | 81736325f3517390c95074d96770599bea99b56d | |
parent | dbe33c933e60f6c5ef59856f66bb3363eaecdf8b (diff) | |
download | mpv-9a684fa55fb45fcde9eede7a44998c1fe44785f8.tar.bz2 mpv-9a684fa55fb45fcde9eede7a44998c1fe44785f8.tar.xz |
faster mpg and much faster gxf demuxing
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@16370 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r-- | libmpdemux/demux_mpg.c | 79 | ||||
-rw-r--r-- | libmpdemux/demuxer.h | 4 | ||||
-rw-r--r-- | libmpdemux/parse_es.c | 21 |
3 files changed, 71 insertions, 33 deletions
diff --git a/libmpdemux/demux_mpg.c b/libmpdemux/demux_mpg.c index a04ec2c50b..6bfa09a5f9 100644 --- a/libmpdemux/demux_mpg.c +++ b/libmpdemux/demux_mpg.c @@ -506,33 +506,70 @@ static int demux_mpg_es_fill_buffer(demuxer_t *demux, demux_stream_t *ds){ 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; } diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h index 2630939207..498e1d5b59 100644 --- a/libmpdemux/demuxer.h +++ b/libmpdemux/demuxer.h @@ -259,8 +259,8 @@ int demux_read_data_pack(demux_stream_t *ds,unsigned char* mem,int len); #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){ diff --git a/libmpdemux/parse_es.c b/libmpdemux/parse_es.c index 3b90bb7607..a7ddf85054 100644 --- a/libmpdemux/parse_es.c +++ b/libmpdemux/parse_es.c @@ -53,6 +53,8 @@ int sync_video_packet(demux_stream_t *ds){ 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 @@ int packet_start; 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){ |