summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_mpeg.c336
1 files changed, 169 insertions, 167 deletions
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
index f1572219e..97f62c289 100644
--- a/src/demuxers/demux_mpeg.c
+++ b/src/demuxers/demux_mpeg.c
@@ -1,23 +1,23 @@
/*
* Copyright (C) 2000-2002 the xine project
- *
+ *
* This file is part of xine, a free video player.
- *
+ *
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: demux_mpeg.c,v 1.60 2002/05/10 13:10:04 miguelfreitas Exp $
+ * $Id: demux_mpeg.c,v 1.61 2002/05/12 12:06:29 tmattern Exp $
*
* demultiplexer for mpeg 1/2 program streams
* reads streams of variable blocksizes
@@ -47,7 +47,7 @@
#define NUM_PREVIEW_BUFFERS 150
-#define WRAP_THRESHOLD 120000
+#define WRAP_THRESHOLD 120000
#define PTS_AUDIO 0
#define PTS_VIDEO 1
@@ -55,7 +55,7 @@
typedef struct demux_mpeg_s {
demux_plugin_t demux_plugin;
-
+
xine_t *xine;
config_values_t *config;
@@ -77,24 +77,24 @@ typedef struct demux_mpeg_s {
int rate;
int send_end_buffers;
-
+
int64_t last_pts[2];
int send_newpts;
-
+
} demux_mpeg_t;
static uint32_t read_bytes (demux_mpeg_t *this, int n) {
-
+
uint32_t res;
uint32_t i;
unsigned char buf[6];
buf[4]=0;
-
+
i = this->input->read (this->input, buf, n);
if (i != n) {
-
+
this->status = DEMUX_FINISHED;
}
@@ -126,14 +126,14 @@ static uint32_t read_bytes (demux_mpeg_t *this, int n) {
static void check_newpts( demux_mpeg_t *this, int64_t pts, int video )
{
int64_t diff;
-
+
diff = pts - this->last_pts[video];
-
- if( !this->preview_mode && pts &&
+
+ if( !this->preview_mode && pts &&
(this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) {
-
+
buf_element_t *buf;
-
+
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_NEWPTS;
buf->disc_off = pts;
@@ -148,7 +148,7 @@ static void check_newpts( demux_mpeg_t *this, int64_t pts, int video )
this->send_newpts = 0;
this->last_pts[1-video] = 0;
}
-
+
if( !this->preview_mode && pts )
this->last_pts[video] = pts;
}
@@ -183,7 +183,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
w = read_bytes(this, 2);
pts |= (w & 0xFFFE) >> 1;
- header_len -= 5 ;
+ header_len -= 5 ;
}
/* read rest of header */
@@ -208,7 +208,7 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
buf->type = BUF_AUDIO_A52 + track;
buf->pts = pts;
check_newpts( this, pts, PTS_AUDIO );
-
+
if (this->preview_mode)
buf->decoder_flags = BUF_FLAG_PREVIEW;
else
@@ -256,11 +256,11 @@ static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
this->status = DEMUX_FINISHED;
return ;
}
-
+
buf->type = BUF_AUDIO_MPEG + track;
buf->pts = pts;
check_newpts( this, pts, PTS_AUDIO );
-
+
if (this->preview_mode)
buf->decoder_flags = BUF_FLAG_PREVIEW;
else
@@ -342,7 +342,7 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
while ((w & 0x80) == 0x80) {
if (this->status != DEMUX_OK)
- return;
+ return;
/* stuffing bytes */
w = read_bytes(this, 1); len--;
@@ -351,7 +351,7 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
if ((w & 0xC0) == 0x40) {
if (this->status != DEMUX_OK)
- return;
+ return;
/* buffer_scale, buffer size */
w = read_bytes(this, 1); len--;
@@ -361,7 +361,7 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
if ((w & 0xF0) == 0x20) {
if (this->status != DEMUX_OK)
- return;
+ return;
pts = (w & 0xe) << 29 ;
w = read_bytes(this, 2); len -= 2;
@@ -376,7 +376,7 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
} else if ((w & 0xF0) == 0x30) {
if (this->status != DEMUX_OK)
- return;
+ return;
pts = (w & 0x0e) << 29 ;
w = read_bytes(this, 2); len -= 2;
@@ -396,7 +396,7 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
/*
if (w != 0x0f)
- xprintf (VERBOSE|DEMUX, " ERROR w (%02x) != 0x0F ",w);
+ xprintf (VERBOSE|DEMUX, " ERROR w (%02x) != 0x0F ",w);
*/
}
@@ -419,7 +419,7 @@ static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr)
buf->type = BUF_AUDIO_MPEG + track ;
buf->pts = pts;
check_newpts( this, pts, PTS_AUDIO );
-
+
if (this->preview_mode)
buf->decoder_flags = BUF_FLAG_PREVIEW;
else
@@ -477,9 +477,9 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
int stuffing, i;
mpeg_version = 2;
-
+
/* system_clock_reference */
-
+
scr = (buf & 0x08) << 27;
scr = (buf & 0x03) << 28;
buf = read_bytes (this, 1);
@@ -492,14 +492,14 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
buf = read_bytes (this, 1);
scr |= (buf & 0xF8) >> 3;
buf = read_bytes (this, 1); /* extension */
-
+
/* mux_rate */
-
+
buf = read_bytes(this,3);
if (!this->rate) {
this->rate = (buf & 0xFFFFFC) >> 2;
- }
-
+ }
+
/* stuffing bytes */
buf = read_bytes(this,1);
stuffing = buf &0x03;
@@ -519,7 +519,7 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
scr |= (buf & 0xFFFE) >>1;
/* mux_rate */
-
+
if (!this->rate) {
buf = read_bytes (this,1);
this->rate = (buf & 0x7F) << 15;
@@ -527,9 +527,9 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
this->rate |= (buf << 7);
buf = read_bytes (this,1);
this->rate |= (buf >> 1);
-
+
/* printf ("demux_mpeg: mux_rate = %d\n",this->rate); */
-
+
} else
buf = read_bytes (this, 3) ;
}
@@ -538,11 +538,11 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
#if 0
/* scr-wrap detection disabled due bad streams */
if( scr && !this->preview_mode )
- {
+ {
int64_t scr_diff = scr - this->last_scr;
-
+
if (abs(scr_diff) > 60000 && !this->send_newpts) {
-
+
buf_element_t *buf;
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
@@ -551,10 +551,10 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
this->video_fifo->put (this->video_fifo, buf);
if (this->audio_fifo) {
- buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
- buf->type = BUF_CONTROL_DISCONTINUITY;
- buf->disc_off = scr_diff;
- this->audio_fifo->put (this->audio_fifo, buf);
+ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
+ buf->type = BUF_CONTROL_DISCONTINUITY;
+ buf->disc_off = scr_diff;
+ this->audio_fifo->put (this->audio_fifo, buf);
}
}
this->last_scr = scr;
@@ -578,7 +578,7 @@ static uint32_t parse_pack(demux_mpeg_t *this) {
/* printf (" code = %08x\n",buf); */
while ( ((buf & 0xFFFFFF00) == 0x00000100)
- && ((buf & 0xff) != 0xba) ) {
+ && ((buf & 0xff) != 0xba) ) {
if (this->status != DEMUX_OK)
return buf;
@@ -637,10 +637,10 @@ static uint32_t parse_pack_preview (demux_mpeg_t *this, int *num_buffers)
this->input->read (this->input, this->dummy_space, buf);
buf = read_bytes (this, 4) ;
}
-
+
while ( ((buf & 0xFFFFFF00) == 0x00000100)
- && ((buf & 0xff) != 0xba)
- && (*num_buffers > 0)) {
+ && ((buf & 0xff) != 0xba)
+ && (*num_buffers > 0)) {
if (this->status != DEMUX_OK)
return buf;
@@ -653,7 +653,7 @@ static uint32_t parse_pack_preview (demux_mpeg_t *this, int *num_buffers)
buf = read_bytes (this, 4);
*num_buffers = *num_buffers - 1;
}
-
+
return buf;
}
@@ -675,7 +675,7 @@ static void *demux_mpeg_loop (void *this_gen) {
pthread_mutex_lock( &this->mutex );
/* do-while needed to seek after demux finished */
do {
-
+
/* main demuxer loop */
while(this->status == DEMUX_OK) {
w = parse_pack (this);
@@ -694,9 +694,9 @@ static void *demux_mpeg_loop (void *this_gen) {
xine_usec_sleep(100000);
pthread_mutex_lock( &this->mutex );
}
-
+
} while( this->status == DEMUX_OK );
-
+
if (this->send_end_buffers) {
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_END;
@@ -712,11 +712,11 @@ static void *demux_mpeg_loop (void *this_gen) {
}
printf ("demux_mpeg: demux thread finished (status: %d, buf:%x)\n",
- this->status, w);
+ this->status, w);
this->thread_running = 0;
pthread_mutex_unlock( &this->mutex );
-
+
pthread_exit(NULL);
return NULL;
@@ -729,16 +729,16 @@ static void demux_mpeg_stop (demux_plugin_t *this_gen) {
void *p;
pthread_mutex_lock( &this->mutex );
-
+
if (!this->thread_running) {
printf ("demux_mpeg: stop...ignored\n");
pthread_mutex_unlock( &this->mutex );
return;
}
-
+
this->send_end_buffers = 0;
this->status = DEMUX_FINISHED;
-
+
pthread_mutex_unlock( &this->mutex );
pthread_join (this->thread, &p);
@@ -760,29 +760,30 @@ static void demux_mpeg_stop (demux_plugin_t *this_gen) {
static int demux_mpeg_get_status (demux_plugin_t *this_gen) {
demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
- return this->status;
+
+ return (this->thread_running?DEMUX_OK:DEMUX_FINISHED);
}
static void demux_mpeg_start (demux_plugin_t *this_gen,
- fifo_buffer_t *video_fifo,
- fifo_buffer_t *audio_fifo,
- off_t start_pos, int start_time) {
+ fifo_buffer_t *video_fifo,
+ fifo_buffer_t *audio_fifo,
+ off_t start_pos, int start_time) {
- demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
- buf_element_t *buf;
- int err;
+ demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
+ buf_element_t *buf;
+ int err;
pthread_mutex_lock( &this->mutex );
if( !this->thread_running ) {
-
+
this->video_fifo = video_fifo;
this->audio_fifo = audio_fifo;
-
+
this->rate = 0; /* fixme */
this->last_pts[0] = 0;
this->last_pts[1] = 0;
-
+
buf = this->video_fifo->buffer_pool_alloc (this->video_fifo);
buf->type = BUF_CONTROL_START;
this->video_fifo->put (this->video_fifo, buf);
@@ -807,20 +808,20 @@ static void demux_mpeg_start (demux_plugin_t *this_gen,
do {
w = parse_pack_preview (this, &num_buffers);
-
+
if (w != 0x000001ba)
demux_mpeg_resync (this, w);
-
+
num_buffers --;
} while ( (this->status == DEMUX_OK) && (num_buffers>0)) ;
/* printf ("demux_mpeg: rate %d\n", this->rate); */
}
- }
-
+ }
+
if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0 ) {
-
+
if ( (!start_pos) && (start_time))
start_pos = start_time * this->rate * 50;
@@ -828,22 +829,22 @@ static void demux_mpeg_start (demux_plugin_t *this_gen,
if( start_pos )
demux_mpeg_resync (this, read_bytes(this, 4) );
-
+
} else
read_bytes(this, 4);
-
+
this->send_newpts = 1;
this->status = DEMUX_OK ;
-
+
if( !this->thread_running ) {
this->preview_mode = 0;
this->send_end_buffers = 1;
this->thread_running = 1;
if ((err = pthread_create (&this->thread,
- NULL, demux_mpeg_loop, this)) != 0) {
+ NULL, demux_mpeg_loop, this)) != 0) {
printf ("demux_mpeg: can't create new thread (%s)\n",
- strerror(err));
+ strerror(err));
abort();
}
}
@@ -851,67 +852,67 @@ static void demux_mpeg_start (demux_plugin_t *this_gen,
xine_flush_engine(this->xine);
}
pthread_mutex_unlock( &this->mutex );
-
+
}
static void demux_mpeg_seek (demux_plugin_t *this_gen,
- off_t start_pos, int start_time) {
+ off_t start_pos, int start_time) {
demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
- demux_mpeg_start (this_gen, this->video_fifo, this->audio_fifo,
- start_pos, start_time);
+ demux_mpeg_start (this_gen, this->video_fifo, this->audio_fifo,
+ start_pos, start_time);
}
-static int demux_mpeg_open(demux_plugin_t *this_gen,
- input_plugin_t *input, int stage) {
+static int demux_mpeg_open(demux_plugin_t *this_gen,
+ input_plugin_t *input, int stage) {
demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
this->input = input;
switch(stage) {
-
+
case STAGE_BY_CONTENT: {
uint8_t buf[4096];
-
+
if((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) {
input->seek(input, 0, SEEK_SET);
-
+
if(input->get_blocksize(input))
- return DEMUX_CANNOT_HANDLE;
-
+ return DEMUX_CANNOT_HANDLE;
+
if(input->read(input, buf, 6)) {
-
- if(buf[0] || buf[1] || (buf[2] != 0x01))
- return DEMUX_CANNOT_HANDLE;
-
- switch(buf[3]) {
-
- case 0xba:
- if((buf[4] & 0xf0) == 0x20) {
- uint32_t pckbuf ;
-
- pckbuf = read_bytes (this, 1);
- if ((pckbuf>>4) != 4) {
- this->input = input;
- return DEMUX_CAN_HANDLE;
- }
- }
- break;
-#if 0
- case 0xe0:
- if((buf[6] & 0xc0) != 0x80) {
- uint32_t pckbuf ;
-
- pckbuf = read_bytes (this, 1);
- if ((pckbuf>>4) != 4) {
- this->input = input;
- return DEMUX_CAN_HANDLE;
- }
- }
- break;
-#endif
- }
+
+ if(buf[0] || buf[1] || (buf[2] != 0x01))
+ return DEMUX_CANNOT_HANDLE;
+
+ switch(buf[3]) {
+
+ case 0xba:
+ if((buf[4] & 0xf0) == 0x20) {
+ uint32_t pckbuf ;
+
+ pckbuf = read_bytes (this, 1);
+ if ((pckbuf>>4) != 4) {
+ this->input = input;
+ return DEMUX_CAN_HANDLE;
+ }
+ }
+ break;
+#if 0
+ case 0xe0:
+ if((buf[6] & 0xc0) != 0x80) {
+ uint32_t pckbuf ;
+
+ pckbuf = read_bytes (this, 1);
+ if ((pckbuf>>4) != 4) {
+ this->input = input;
+ return DEMUX_CAN_HANDLE;
+ }
+ }
+ break;
+#endif
+ }
}
}
return DEMUX_CANNOT_HANDLE;
@@ -924,54 +925,56 @@ static int demux_mpeg_open(demux_plugin_t *this_gen,
char *MRL = input->get_mrl(input);
char *m, *valid_mrls, *valid_ends;
- xine_strdupa(valid_mrls, (this->config->register_string(this->config,
- "mrl.mrls_mpeg", VALID_MRLS,
- "valid mrls for mpeg demuxer",
- NULL, NULL, NULL)));
-
+ xine_strdupa(valid_mrls,
+ this->config->register_string(this->config,
+ "mrl.mrls_mpeg", VALID_MRLS,
+ "valid mrls for mpeg demuxer",
+ NULL, NULL, NULL));
+
media = strstr(MRL, "://");
if (media) {
- while((m = xine_strsep(&valid_mrls, ",")) != NULL) {
-
- while(*m == ' ' || *m == '\t') m++;
-
- if(!strncmp(MRL, m, strlen(m))) {
-
- if(!strncmp((media + 3), "mpeg1", 5)) {
- this->input = input;
- return DEMUX_CAN_HANDLE;
- }
- else if(!strncasecmp((media + 3), "mpeg2", 5)) {
- return DEMUX_CANNOT_HANDLE;
- }
-
- xine_log (this->xine, XINE_LOG_MSG, _("demux_mpeg: please specify mpeg(mpeg1/mpeg2) stream type.\n"));
- return DEMUX_CANNOT_HANDLE;
- }
+ while((m = xine_strsep(&valid_mrls, ",")) != NULL) {
+
+ while(*m == ' ' || *m == '\t') m++;
+
+ if(!strncmp(MRL, m, strlen(m))) {
+
+ if(!strncmp((media + 3), "mpeg1", 5)) {
+ this->input = input;
+ return DEMUX_CAN_HANDLE;
+ }
+ else if(!strncasecmp((media + 3), "mpeg2", 5)) {
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ xine_log (this->xine, XINE_LOG_MSG, _("demux_mpeg: please specify mpeg(mpeg1/mpeg2) stream type.\n"));
+ return DEMUX_CANNOT_HANDLE;
+ }
}
}
ending = strrchr(MRL, '.');
-
+
if(!ending)
return DEMUX_CANNOT_HANDLE;
-
- xine_strdupa(valid_ends, (this->config->register_string(this->config,
- "mrl.ends_mpeg", VALID_ENDS,
- "valid mrls ending for mpeg demuxer",
- NULL, NULL, NULL)));
- while((m = xine_strsep(&valid_ends, ",")) != NULL) {
-
+
+ xine_strdupa(valid_ends,
+ this->config->register_string(this->config,
+ "mrl.ends_mpeg", VALID_ENDS,
+ "valid mrls ending for mpeg demuxer",
+ NULL, NULL, NULL));
+ while((m = xine_strsep(&valid_ends, ",")) != NULL) {
+
while(*m == ' ' || *m == '\t') m++;
-
+
if(!strcasecmp((ending + 1), m)) {
- this->input = input;
- return DEMUX_CAN_HANDLE;
+ this->input = input;
+ return DEMUX_CAN_HANDLE;
}
}
}
break;
-
+
default:
return DEMUX_CANNOT_HANDLE;
break;
@@ -997,7 +1000,7 @@ static int demux_mpeg_get_stream_length (demux_plugin_t *this_gen) {
demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
- if (this->rate)
+ if (this->rate)
return this->input->get_length (this->input) / (this->rate * 50);
else
return 0;
@@ -1010,25 +1013,25 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
if (iface != 7) {
printf ("demux_mpeg: plugin doesn't support plugin API version %d.\n"
- " this means there's a version mismatch between xine and this "
- " demuxer plugin.\nInstalling current demux plugins should help.\n",
- iface);
+ " this means there's a version mismatch between xine and this "
+ " demuxer plugin.\nInstalling current demux plugins should help.\n",
+ iface);
return NULL;
}
-
+
this = xine_xmalloc (sizeof (demux_mpeg_t));
this->config = xine->config;
this->xine = xine;
/* Calling register_string() configure valid mrls in configfile */
(void*) this->config->register_string(this->config, "mrl.mrls_mpeg", VALID_MRLS,
- "valid mrls for mpeg demuxer",
- NULL, NULL, NULL);
+ "valid mrls for mpeg demuxer",
+ NULL, NULL, NULL);
(void*) this->config->register_string(this->config,
- "mrl.ends_mpeg", VALID_ENDS,
- "valid mrls ending for mpeg demuxer",
- NULL, NULL, NULL);
-
+ "mrl.ends_mpeg", VALID_ENDS,
+ "valid mrls ending for mpeg demuxer",
+ NULL, NULL, NULL);
+
this->demux_plugin.interface_version = DEMUXER_PLUGIN_IFACE_VERSION;
this->demux_plugin.open = demux_mpeg_open;
this->demux_plugin.start = demux_mpeg_start;
@@ -1039,10 +1042,9 @@ demux_plugin_t *init_demuxer_plugin(int iface, xine_t *xine) {
this->demux_plugin.get_identifier = demux_mpeg_get_id;
this->demux_plugin.get_stream_length = demux_mpeg_get_stream_length;
this->demux_plugin.get_mimetypes = demux_mpeg_get_mimetypes;
-
+
this->status = DEMUX_FINISHED;
pthread_mutex_init( &this->mutex, NULL );
-
+
return (demux_plugin_t *) this;
}
-