mirror of
https://github.com/mpv-player/mpv
synced 2024-12-18 21:06:00 +00:00
faster mpg and much faster gxf demuxing
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@16370 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
dbe33c933e
commit
9a684fa55f
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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){
|
||||
|
@ -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){
|
||||
|
Loading…
Reference in New Issue
Block a user