changeset 10014:01a9af06319a

fully reworked by Nico <nsabbi@libero.it>
author alex
date Mon, 28 Apr 2003 16:43:48 +0000
parents 1dfffdd245dc
children 90c358ba9fac
files libmpdemux/demux_ts.c
diffstat 1 files changed, 220 insertions(+), 249 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_ts.c	Mon Apr 28 16:34:35 2003 +0000
+++ b/libmpdemux/demux_ts.c	Mon Apr 28 16:43:48 2003 +0000
@@ -1,34 +1,11 @@
 /*
- * 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$
- *
  * Demultiplexer for MPEG2 Transport Streams.
  *
  * For the purposes of playing video, we make some assumptions about the
  * kinds of TS we have to process. The most important simplification is to
  * assume that the TS contains a single program (SPTS) because this then
  * allows significant simplifications to be made in processing PATs.
-
-
-
- /* 
+ * 
  * WARNING: Quite a hack was required in order to get files by MultiDec played back correctly.
  * If it breaks anything else, just comment out the "#define DEMUX_PVA_MULTIDEC_HACK" below
  * and it will not be compiled in.
@@ -36,19 +13,15 @@
  * Feedback is appreciated.
  *
  * written by Matteo Giani
- */
- 
- 
-/*
- * MPEG2 transport stream (aka DVB) demux
- * Copyright (c) 2002 Fabrice Bellard.
+ * based on FFmpeg (libavformat) sources
  *
- * This library is free software; you can redistribute it and/or
+ *
+ * This file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
+ * This file 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
  * Lesser General Public License for more details.
@@ -74,26 +47,6 @@
 #include "bswap.h"
 
 
-typedef struct {
-	off_t offset;
-	long size;
-	uint8_t type;
-	uint8_t is_packet_start;
-	float pts;
-	uint8_t packet_size;
-} ts_payload_t;
-
-
-typedef struct {
-	float last_audio_pts;
-	float last_video_pts;
-	uint8_t just_synced;
-	uint8_t synced_stream_id;
-	char *buffer;		
-	int buffer_size;
-	int buffer_offset;
-	int packet_size;
-} ts_priv_t;
 
 #define TS_FEC_PACKET_SIZE 204
 #define TS_PACKET_SIZE 188
@@ -101,18 +54,7 @@
     
 #define MAX_HEADER_SIZE 6			/* enough for PES header + length */
 #define MAX_PROBE_SIZE	1000000
-#define NUM_CONSECUTIVE_TS_PACKETS 5
-
-
-enum MpegTSState {
-    MPEGTS_HEADER = 0,
-    MPEGTS_PESHEADER_FILL,
-    MPEGTS_PESHEADER_FLAGS,
-    MPEGTS_PESHEADER_SIZE,
-    MPEGTS_PESHEADER_READ,
-    MPEGTS_PAYLOAD,
-    MPEGTS_SKIP,
-};
+#define NUM_CONSECUTIVE_TS_PACKETS 32
 
 
 int ts_fastparse = 0;
@@ -123,48 +65,35 @@
 	VIDEO_MPEG2 	= 0x10000002,
 	AUDIO_MP2   	= 0x50,
 	AUDIO_A52   	= 0x2000,
-	AUDIO_LPCM_BE  	= 0x2000000,
+	AUDIO_LPCM_BE  	= 0x10001
+	/*,
 	SPU_DVD		= 0x3000000,
 	SPU_DVB		= 0x3000001,
+	*/
 } es_stream_type_t;    
 
-typedef struct MpegTSStream 		// IT'S AN ES
-{
-    int pid;
-    enum MpegTSState state;
-    int last_cc; /* last cc code (-1 if first packet) */
-    /* used to get the format */
-    int header_size;
-    int payload_size;
-    int pes_header_size;
-    //AVStream *st;
-    es_stream_type_t type;    
-    unsigned char header[MAX_HEADER_SIZE];
-    char *pes_buffer;
-    int offset;
-    float pts;
-    float last_pts;
-} MpegTSStream;
-
-
-typedef struct MpegTSContext {
-    int raw_packet_size; 	/* raw packet size, including FEC if present */
-    MpegTSStream *pids[NB_PID_MAX];
-    demuxer_t *demuxer;
-} MpegTSContext;
-
 
 typedef struct {
     int size;
     unsigned char *start;
+	uint16_t payload_size;
     es_stream_type_t type;    
-    float pts;
+    float pts, last_pts;
     int pid;
-} ES_info_t;
+	int last_cc;				// last cc code (-1 if first packet) 
+} ES_stream_t;
+
 
-MpegTSContext ts;
+typedef struct MpegTSContext {
+    int packet_size; 		// raw packet size, including FEC if present e.g. 188 bytes
+	ES_stream_t *pids[NB_PID_MAX];
+} MpegTSContext;
 
-//FILE *outfile;
+
+typedef struct {
+	MpegTSContext ts;
+} ts_priv_t;
+
 
 
 static uint8_t get_packet_size(const unsigned char *buf, int size)
@@ -195,29 +124,29 @@
 
 
 
-
 int ts_check_file(demuxer_t * demuxer)
 {
 	const int buf_size = (TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS);
-	char buf[buf_size], c, done = 0;
-	uint32_t _read, i=1;
+	unsigned char buf[buf_size], c, done = 0, *ptr;
+	uint32_t _read, i=1, count = 0;
+	int cc[NB_PID_MAX], last_cc[NB_PID_MAX], pid, cc_ok;
 	uint8_t size = 0;
 	off_t pos = 0;
-	
+		
 	mp_msg(MSGT_DEMUX, MSGL_V, "************Checking for TS************\n");
 	
 	while(! done)
 	{	
 	    while(((c=stream_read_char(demuxer->stream)) != 0x47) 
-		&& (i < MAX_PROBE_SIZE)
-		&& ! demuxer->stream->eof
+			&& (i < MAX_PROBE_SIZE)
+			&& ! demuxer->stream->eof
 		) i++; 
 	    
 	    if(c != 0x47)
 	    {
-		mp_msg(MSGT_DEMUX, MSGL_V, "NOT A TS FILE1\n");
-		done = 1;
-		continue;
+			mp_msg(MSGT_DEMUX, MSGL_V, "NOT A TS FILE1\n");
+			done = 1;
+			continue;
 	    }
 	
 	    pos = stream_tell(demuxer->stream) - 1;
@@ -226,101 +155,57 @@
 	
 	    if(_read < buf_size-1)
 	    {
-		mp_msg(MSGT_DEMUX, MSGL_V, "COULDN'T READ ENOUGH DATA, EXITING TS_CHECK\n");
-		stream_reset(demuxer->stream);
-		return 0;
+			mp_msg(MSGT_DEMUX, MSGL_V, "COULDN'T READ ENOUGH DATA, EXITING TS_CHECK\n");
+			stream_reset(demuxer->stream);
+			return 0;
 	    }
 	    
 	    size = get_packet_size(buf, buf_size);
 	    if(size)
-		done = 1;
+		  done = 1;
+	}
+	
+	mp_msg(MSGT_DEMUX, MSGL_V, "TRIED UP TO POSITION %u, FOUND %x, packet_size= %d\n", i, c, size);
+	stream_seek(demuxer->stream, pos);
+	
+	//return size;
+
+	for(count = 0; count < NB_PID_MAX; count++)
+	{
+	  cc[count] = last_cc[count] = -1;
 	}
 	
-	mp_msg(MSGT_DEMUX, MSGL_V, "TRIED UP TO POSITION %u, FUOND %x, packet_size= %d\n", i, c, size);
-	stream_seek(demuxer->stream, pos);
-	return size;
-}
-
-
-
-
-
-demuxer_t *demux_open_ts(demuxer_t * demuxer)
-{
-	uint8_t packet_size;
-	//demuxer_t *vd, *ad;
-	//stream_t *s;
-	sh_video_t *sh_video;
-	sh_audio_t *sh_audio;
-	ts_priv_t * priv;
-	int i;
-	
-	
-	mp_msg(MSGT_DEMUX, MSGL_V, "DEMUX OPEN, AUDIO_ID: %d, VIDEO_ID: %d, SUBTITLE_ID: %d,\n", 
-	    demuxer->audio->id, demuxer->video->id, demuxer->sub->id);
-	
-	for(i=0; i < 8192; i++)
-	    ts.pids[i] = NULL;
-	
-	demuxer->type= DEMUXER_TYPE_MPEG_TS;
-	
-	stream_reset(demuxer->stream);
-	stream_seek(demuxer->stream, 0);
-	
-	packet_size = ts_check_file(demuxer);
-	if(!packet_size)
-	    return NULL;
+	done = 0;
+	for(count = 0; count < NUM_CONSECUTIVE_TS_PACKETS; count++)
+	{
+	  ptr = &(buf[size * count]);  
+	  pid = ((ptr[1] & 0x1f) << 8) | ptr[2];
+	  mp_msg(MSGT_DEMUX, MSGL_V, "BUF: %02x %02x %02x %02x, PID %d, SIZE: %d \n", 
+		ptr[0], ptr[1], ptr[2], ptr[3], pid, size);
 	
-	priv = malloc(sizeof(ts_priv_t));
-	priv->last_video_pts=-1;
-    	priv->last_audio_pts=-1;
-	priv->packet_size = packet_size;
-	demuxer->priv = priv;
-	
-	if(demuxer->stream->type != STREAMTYPE_FILE) demuxer->seekable=0;
-	else demuxer->seekable = 1;
+	  if(pid == 8191)
+		continue;	
 		
-	
-	sh_video = new_sh_video(demuxer, 0);
-	sh_video->ds = demuxer->video;
-	demuxer->video->sh = sh_video;
-	
-        
-	
-	sh_audio = new_sh_audio(demuxer, 0);		
-	sh_audio->ds = demuxer->audio;
-	demuxer->audio->sh = sh_audio;
-	
+	  cc[pid] = (ptr[3] & 0xf);
+	  cc_ok = (last_cc[pid] < 0) || ((((last_cc[pid] + 1) & 0x0f) == cc[pid]));
+	  mp_msg(MSGT_DEMUX, MSGL_V, "PID %d, COMPARE CC %d AND LAST_CC %d\n", pid, cc[pid], last_cc[pid]);
+	  if(! cc_ok)
+		return 0;
 	
-	mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer...");
-
-	if(! ts_fastparse)	
-	    ts_detect_streams(demuxer);
-	
+	  last_cc[pid] = cc[pid];
+	  done++;
+	}
 	
-	/*
-	demuxer->movi_start = 0;
-	demuxer->movi_end = demuxer->stream->end_pos;
-	*/
-	    
-	
-	/*    
-	s= new_ds_stream(demuxer->video);
-	return demux_open_stream(s, DEMUXER_TYPE_MPEG_ES, demuxer->audio->id, demuxer->video->id, demuxer->sub->id, NULL); 
-	*/
-	
-	stream_seek(demuxer->stream, 0);		//IF IT'S FROM A PIPE IT WILL FAIL, BUT WHO CARES?
-	return demuxer;	
+    return size;
 }
 
 
-
 void ts_detect_streams(demuxer_t *demuxer)
 {
 	int video_found = 0, audio_found = 0;
 	off_t pos=0;
-	ES_info_t es;
-	int *apid, *vpid, *spid;
+	ES_stream_t es;
+	int *apid, *vpid, *spid, fapid, fvpid, fspid;
 	unsigned char tmp[TS_FEC_PACKET_SIZE];
 	sh_video_t *sh_video = demuxer->video->sh;
 	sh_audio_t *sh_audio = demuxer->audio->sh;
@@ -340,7 +225,7 @@
 		{
 		    sh_video->format = VIDEO_MPEG2;	//MPEG2 video
 		    if(*vpid == -1)
-			*vpid = es.pid;
+			*vpid = fvpid = es.pid;
 		    video_found = 1;
 		}
 		    
@@ -348,15 +233,23 @@
 		{
 		    sh_audio->format = AUDIO_MP2;	//MPEG1L2 audio
 		    if(*apid == -1)
-			*apid = es.pid;
+			  *apid = fapid = es.pid;
 		    audio_found = 1;
 		}
 		    
 		if(es.type == AUDIO_A52)
 		{
-		    sh_audio->format = AUDIO_A52;	//AC3 audio
+		    sh_audio->format = AUDIO_A52;	//A52 audio
 		    if(*apid == -1)
-			*apid = es.pid;
+			  *apid = fapid = es.pid;
+		    audio_found = 1;
+		  }
+		
+		  if(es.type == AUDIO_LPCM_BE)		//LPCM AUDIO
+		  {
+		    sh_audio->format = AUDIO_LPCM_BE;	
+		    if(*apid == -1)
+			  *apid = fapid = es.pid;
 		    audio_found = 1;
 		}
 		
@@ -367,7 +260,7 @@
 	}
 	
 	if(video_found)
-	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG2...");
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG2(pid=%d)...", fvpid);
 	else
 	{
 	    *vpid = -2;		//WE DIDN'T MATCH ANY VIDEO STREAM, SO WE FORCE THE DEMUXER TO IGNORE VIDEO
@@ -375,9 +268,11 @@
 	}
 	    
 	if(sh_audio->format == AUDIO_MP2)
-	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO MP2\n");
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO MP2(pid=%d)\n", fapid);
 	else if(sh_audio->format == AUDIO_A52)
-	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO A52\n");
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO A52(pid=%d)\n", fapid);
+	else if(sh_audio->format == AUDIO_LPCM_BE)
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO LPCM(pid=%d)\n", fapid);	
 	else    
 	{
 	    *apid = -2;		//WE DIDN'T MATCH ANY AUDIO STREAM, SO WE FORCE THE DEMUXER TO IGNORE AUDIO
@@ -386,6 +281,72 @@
 }
 
 
+
+demuxer_t *demux_open_ts(demuxer_t * demuxer)
+{
+	int i;
+	uint8_t packet_size;
+	sh_video_t *sh_video;
+	sh_audio_t *sh_audio;
+	ts_priv_t * priv = (ts_priv_t*) demuxer->priv;
+	
+	
+	mp_msg(MSGT_DEMUX, MSGL_V, "DEMUX OPEN, AUDIO_ID: %d, VIDEO_ID: %d, SUBTITLE_ID: %d,\n", 
+	    demuxer->audio->id, demuxer->video->id, demuxer->sub->id);
+	
+	
+	demuxer->type= DEMUXER_TYPE_MPEG_TS;
+	
+	stream_reset(demuxer->stream);
+	stream_seek(demuxer->stream, 0);
+	
+	packet_size = ts_check_file(demuxer);
+	if(!packet_size)
+	    return NULL;
+	
+	priv = malloc(sizeof(ts_priv_t));
+	
+	for(i=0; i < 8192; i++)
+	    priv->ts.pids[i] = NULL;
+	priv->ts.packet_size = packet_size;
+	
+	
+	demuxer->priv = priv;
+	
+	if(demuxer->stream->type != STREAMTYPE_FILE) demuxer->seekable=0;
+	else demuxer->seekable = 1;
+		
+	
+	sh_video = new_sh_video(demuxer, 0);
+	sh_video->ds = demuxer->video;
+	demuxer->video->sh = sh_video;
+	
+	sh_audio = new_sh_audio(demuxer, 0);		
+	sh_audio->ds = demuxer->audio;
+	demuxer->audio->sh = sh_audio;
+	
+	
+	mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer...");
+
+	if(! ts_fastparse)	
+	    ts_detect_streams(demuxer);
+	
+	
+	/*
+	demuxer->movi_start = 0;
+	demuxer->movi_end = demuxer->stream->end_pos;
+	*/
+		
+	
+	stream_seek(demuxer->stream, 0);		//IF IT'S FROM A PIPE IT WILL FAIL, BUT WHO CARES?
+	return demuxer;	
+}
+
+
+
+
+
+
 void demux_close_ts(demuxer_t * demuxer)
 {
 	if(demuxer->priv)
@@ -398,8 +359,7 @@
 
 
 
-//MpegTSStream *tss,  const unsigned char *buf, int buf_size, int is_start, ES_info_t *es
-static int pes_parse2(MpegTSStream *tss, unsigned char *buf, uint16_t packet_len, int is_start, ES_info_t *es) 
+static int pes_parse2(unsigned char *buf, uint16_t packet_len, int is_start, ES_stream_t *es) 
 {
     unsigned char *p;
     uint32_t       header_len;
@@ -407,7 +367,7 @@
     uint32_t       stream_id;
     uint32_t       pkt_len;
 
-    mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2(%X, %X, %d, %d, ): \n", tss, buf, packet_len, is_start);
+    mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2(%X, %d, %d, ): \n", buf, packet_len, is_start);
 
     if(packet_len == 0)
     {
@@ -427,7 +387,7 @@
 
     if(! is_start)
     {
-	tss->pts = tss->last_pts;
+	  es->pts = 0.0f;
 	es->start = p;
 	es->size = packet_len;
 	return es->size;
@@ -435,6 +395,7 @@
   
     /* we should have a PES packet here */
 
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: HEADER %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3]);
     if (p[0] || p[1] || (p[2] != 1)) 
     {
         mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: error HEADER %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]);
@@ -443,29 +404,28 @@
 
     packet_len -= 6;
   
-    tss->payload_size = p[4] << 8 | p[5];
-    if (tss->payload_size == 0)
-        tss->payload_size = 65536;
+	es->payload_size = p[4] << 8 | p[5];
+    if (es->payload_size == 0)
+        es->payload_size = 65535;
 		
     stream_id  = p[3];
 
     if(packet_len==0)
 	return 0;
 
-  //mp_msg(MSGT_DEMUX, MSGL_V, "pes_parse2: packet stream id: %.2X (%d) len: %d (%x)\n", stream_id, stream_id, packet_len, packet_len);
 
     if (p[7] & 0x80) 
-    { /* pts avail */
+    { /* pts available */
 	pts  = (int64_t)(p[9] & 0x0E) << 29 ;
 	pts |=  p[10]         << 22 ;
 	pts |= (p[11] & 0xFE) << 14 ;
 	pts |=  p[12]         <<  7 ;
 	pts |= (p[13] & 0xFE) >>  1 ;
     
-	tss->pts = tss->last_pts = pts / 90000.0f;
+	  es->pts = pts / 90000.0f;
     } 
     else
-	tss->pts = tss->last_pts;
+	  es->pts = 0.0f;
 
     header_len = p[8];
 
@@ -481,49 +441,57 @@
 
     if (stream_id == 0xbd) 
     {
+	  /* hack : ac3 track */
 	int track, spu_id;
     
-	mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: audio buf = %02X %02X %02X %02X %02X %02X %02X %02X\n",
-	    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+	  mp_msg(MSGT_DEMUX, MSGL_V, "pes_parse2: audio buf = %02X %02X %02X %02X %02X %02X %02X %02X, 80: %d\n",
+	    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[0] & 0x80);
     
-	track = p[0] & 0x0F; /* hack : ac3 track */
+	  track = p[0] & 0x0F; 
+	  mp_msg(MSGT_DEMUX, MSGL_DBG2, "AC3 TRACK: %d\n", track);
+	  
+    
 	/*
         * we check the descriptor tag first because some stations
         * do not include any of the ac3 header info in their audio tracks
         * these "raw" streams may begin with a byte that looks like a stream type.
         */
-	if(		//(m->descriptor_tag == 0x81) ||    /* ac3 - raw */ 
-    	    (p[0] == 0x0B && p[1] == 0x77))   /* ac3 - syncword */
+	  if(		   /* ac3 - raw or syncword */ 
+    	    (p[0] == 0x0B && p[1] == 0x77))   
 	{ 						
+			mp_msg(MSGT_DEMUX, MSGL_DBG2, "AC3 SYNCWORD\n");
     	    es->start = p;
     	    es->size = packet_len;
-    	    tss->type = AUDIO_A52;
+    	    es->type = AUDIO_A52;
     	    return es->size;
 	} 
+	  /*
 	else if (//m->descriptor_tag == 0x06 && 
 	    p[0] == 0x20 && p[1] == 0x00) 
 	{
-    	    /* DVBSUB */
+    	    // DVBSUB 
     	    long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
     	    es->start = p;
     	    es->size  = packet_len;
-    	    tss->type = SPU_DVB + payload_len;
-      
+    	    es->type = SPU_DVB + payload_len;
     	    return es->size;
 	} 
+	   
 	else if ((p[0] & 0xE0) == 0x20) 
 	{
     	    spu_id      = (p[0] & 0x1f);
             es->start   = p+1;
     	    es->size    = packet_len-1;
-    	    tss->type   = SPU_DVD + spu_id;
+    		es->type   = SPU_DVD + spu_id;
     	    return es->size;
 	} 
+	  */
 	else if ((p[0] & 0xF0) == 0x80) 
 	{
+			mp_msg(MSGT_DEMUX, MSGL_DBG2, "AC3 WITH HEADER\n");
     	    es->start   = p+4;
     	    es->size    = packet_len - 4;
-    	    tss->type   = AUDIO_A52; // + track;
+    	    es->type = AUDIO_A52; 
     	    return es->size;
 	} 
 	else if ((p[0]&0xf0) == 0xa0) 
@@ -541,7 +509,7 @@
 
     	    es->start   = p + pcm_offset;
     	    es->size    = packet_len - pcm_offset;
-    	    tss->type   = AUDIO_LPCM_BE; // + track;
+    	    es->type = AUDIO_LPCM_BE;
     	    return es->size;
 	}
     } 
@@ -549,7 +517,7 @@
     {
 	es->start   = p;
 	es->size    = packet_len;
-	tss->type   = VIDEO_MPEG2;
+	  es->type 		= VIDEO_MPEG2;
 	return es->size;
     } 
     else if ((stream_id & 0xe0) == 0xc0) 
@@ -558,7 +526,7 @@
 	track 	    = stream_id & 0x1f;
 	es->start   = p;
 	es->size    = packet_len;
-	tss->type   = AUDIO_MP2; // + track;
+	  es->type 		= AUDIO_MP2;
 	return es->size;
     } 
     else 
@@ -593,14 +561,15 @@
 
 // 0 = EOF or no stream found
 // 1 = successfully read a packet
-int ts_parse(demuxer_t * demuxer , ES_info_t *es, unsigned char *packet)
+int ts_parse(demuxer_t * demuxer , ES_stream_t *es, unsigned char *packet)
 {
-    MpegTSStream *tss;
+	ES_stream_t *tss;
     uint8_t done = 0;
-    ts_priv_t *priv = demuxer->priv;
     uint16_t buf_size, is_start; 
     int len, pid, cc, cc_ok, afc;
     unsigned char *p;
+	ts_priv_t * priv = (ts_priv_t*) demuxer->priv;
+	
     
     while(! done)
     {
@@ -610,25 +579,22 @@
 	    return 0;
         }
 	
-	len = stream_read(demuxer->stream, &packet[1], priv->packet_size-1);
-        if (len != priv->packet_size-1)
+	  len = stream_read(demuxer->stream, &packet[1], priv->ts.packet_size-1);
+      if (len != priv->ts.packet_size-1)
             return 0;
         
-	
-	
         pid = ((packet[1] & 0x1f) << 8) | packet[2];
-	tss = ts.pids[pid];	//an ES stream
+	  tss = priv->ts.pids[pid];			//an ES stream
         if(tss == NULL) 
 	{
-            /* if no pid found, then add a pid context */
-	    tss = malloc(sizeof(MpegTSStream));
-	    if (!tss)
+		tss = malloc(sizeof(ES_stream_t));
+	    if(! tss)
     		continue;
-	    memset(tss, 0, sizeof(MpegTSStream));
-            ts.pids[pid] = tss;
+	    memset(tss, 0, sizeof(ES_stream_t));
             tss->pid = pid;
             tss->last_cc = -1;
 	    tss->type = UNKNOWN;
+		priv->ts.pids[pid] 	= tss;
             mp_msg(MSGT_DEMUX, MSGL_DBG2, "new TS pid=%u\n", pid);
         }
 	
@@ -636,7 +602,7 @@
         cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
 	if(! cc_ok)
 	{
-	    mp_msg(MSGT_DEMUX, MSGL_V, "ts_parse: CCCheck NOT OK: %d -> %d\n", tss->last_cc, cc);	
+	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "ts_parse: CCCheck NOT OK: %d -> %d\n", tss->last_cc, cc);	
 	}
         tss->last_cc = cc;        
     
@@ -663,14 +629,26 @@
 	buf_size = TS_PACKET_SIZE - (p - packet);
 	
 	is_start = packet[1] & 0x40;
-	if((len = pes_parse2(tss, p, buf_size, is_start, es)))
+	  len = pes_parse2(p, buf_size, is_start, es);
+	  
+	  if(len)
 	{
-	    tss->offset += es->size;
 	    es->pid = tss->pid;
-	    es->pts = tss->pts;
+	    
+		if(! is_start)
 	    es->type = tss->type;
+		else
+		{
+		  tss->type = es->type;
+		  tss->payload_size = es->payload_size;
+		}
+		
+		if(es->pts == 0.0f)
+		  es->pts = tss->pts = tss->last_pts;
+		else
+		  tss->pts = tss->last_pts = es->pts;
             
-	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "ts_parse, type=%X, start=%X, len=%d\n", tss->type, es->start, es->size);
+	    mp_msg(MSGT_DEMUX, MSGL_V, "ts_parse, pid=%d, PSIZE: %u, type=%X, start=%X, len=%d\n", es->pid, es->payload_size, es->type, es->start, es->size);
 	
 	    return len;
 	}    
@@ -680,9 +658,10 @@
 }
 
 
+
 int demux_ts_fill_buffer(demuxer_t * demuxer)
 {
-    ES_info_t es;
+    ES_stream_t es;
     demux_packet_t *dp;
     int len;
     unsigned char packet[TS_FEC_PACKET_SIZE];
@@ -692,7 +671,7 @@
     vpid = &(demuxer->video->id);
     spid = &(demuxer->sub->id);
     
-    while(len = ts_parse(demuxer, &es, packet))
+    while((len = ts_parse(demuxer, &es, packet)) > 0)
     {
 	    mp_msg(MSGT_DEMUX, MSGL_V, "NEW_FILL_BUFFER, NEW_ADD_PACKET(%x, %d) type: %x, PTS: %f\n", es.start, es.size, es.type, es.pts);    
 	
@@ -725,8 +704,10 @@
 		return len;
 	    }
 	
-	    if((es.type == AUDIO_MP2) || (es.type == AUDIO_A52))
+	    if((es.type == AUDIO_MP2) || (es.type == AUDIO_A52) || (es.type == AUDIO_LPCM_BE))
 	    {
+		  mp_msg(MSGT_DEMUX, MSGL_V, "FILL_AUDIO %x	\n", es.type);
+		  
 		if(ts_fastparse)
 		{
 		    if(*apid == -2)
@@ -756,6 +737,7 @@
 	
 	    mp_msg(MSGT_DEMUX, MSGL_V, "SKIP--------\n");    
     }
+    return 0;
 }
 
 
@@ -767,7 +749,7 @@
     uint8_t c = 0, done = 0, i, buf[TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS];
     off_t pos;
     
-    mp_msg(MSGT_DEMUX, MSGL_DBG2, "STRINGENT_TS_SYNC packet_size: %d\n", priv->packet_size);
+    mp_msg(MSGT_DEMUX, MSGL_DBG2, "STRINGENT_TS_SYNC packet_size: %d\n", priv->ts.packet_size);
     
     
     if(! demuxer->seekable)
@@ -791,12 +773,12 @@
 	    
 	done = 1;
 	buf[0] = c;
-	stream_read(demuxer->stream, &buf[1], (priv->packet_size * NUM_CONSECUTIVE_TS_PACKETS) - 1);	
+	stream_read(demuxer->stream, &buf[1], (priv->ts.packet_size * NUM_CONSECUTIVE_TS_PACKETS) - 1);	
 	for(i = 0; i < 5; i++)
 	{	
-	    if (buf[i * priv->packet_size] != 0x47)
+	    if (buf[i * priv->ts.packet_size] != 0x47)
         	done = 0;
-	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "i: %d, char:  %x\n", i, buf[i * priv->packet_size]);	
+	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "i: %d, char:  %x\n", i, buf[i * priv->ts.packet_size]);	
 	}
 	
 	if(done)
@@ -873,17 +855,6 @@
 	  resync_audio_stream(sh_audio);
 	}
 
-	
-	/*
-	 * Reset the PTS info inside the ts_priv_t structure. This way we don't deliver
-	 * data with the wrong PTSs (the ones we had before seeking).
-	 *
-	 */
-	
-	
-	priv->last_video_pts=-1;
-	priv->last_audio_pts=-1;
-	
 	return 1;
 }