summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/demux_mpeg_block.c600
1 files changed, 381 insertions, 219 deletions
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
index 8e62591a3..8b6051902 100644
--- a/src/demuxers/demux_mpeg_block.c
+++ b/src/demuxers/demux_mpeg_block.c
@@ -17,7 +17,7 @@
* 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_block.c,v 1.177 2003/05/07 02:16:59 rockyb Exp $
+ * $Id: demux_mpeg_block.c,v 1.178 2003/05/10 21:14:44 jcdutton Exp $
*
* demultiplexer for mpeg 1/2 program streams
* used with fixed blocksize devices (like dvd/vcd)
@@ -33,6 +33,7 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <assert.h>
#include "xine_internal.h"
#include "xineutils.h"
@@ -78,7 +79,13 @@ typedef struct demux_mpeg_block_s {
int64_t nav_last_start_pts;
int64_t last_pts[2];
int send_newpts;
+ int preview_mode;
int buf_flag_seek;
+ int64_t scr;
+ uint32_t packet_len;
+ int64_t pts;
+ uint32_t stream_id;
+ int32_t mpeg1;
/* stream index for get_audio/video_frame */
int have_index;
@@ -118,6 +125,33 @@ typedef struct {
[Miguel 02-05-2002]
*/
+static int32_t parse_video_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_audio_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_ancillary_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_program_stream_system_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_private_stream_2(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_program_stream_map(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_padding_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_ecm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_emm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_dsmcc_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_emm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_iec_13522_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_h222_typeA_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_h222_typeB_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_h222_typeC_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_h222_typeD_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_h222_typeE_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_program_stream_directory(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+static int32_t parse_program_stream_pack_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf);
+
+
+
+
+
static void check_newpts( demux_mpeg_block_t *this, int64_t pts, int video )
{
int64_t diff;
@@ -152,17 +186,15 @@ static void check_newpts( demux_mpeg_block_t *this, int64_t pts, int video )
this->last_pts[video] = pts;
}
-
static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_mode) {
buf_element_t *buf = NULL;
uint8_t *p;
- int bMpeg1=0;
- uint32_t header_len;
- int64_t pts;
- uint32_t packet_len;
- uint32_t stream_id;
- int64_t scr = 0;
+ int32_t result;
+ int32_t n;
+
+ this->scr = 0;
+ this->preview_mode = preview_mode;
#ifdef LOG
printf ("demux_mpeg_block: read_block\n");
@@ -202,7 +234,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
return;
}
- p = buf->content; /* len = this->mnBlocksize; */
+ p = buf->content; /* len = this->blocksize; */
if (preview_mode)
buf->decoder_flags = BUF_FLAG_PREVIEW;
else
@@ -213,171 +245,284 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
buf->extra_info->input_length = this->input->get_length (this->input);
}
- if (p[3] == 0xBA) { /* program stream pack header */
+ while(p < (buf->content + this->blocksize)) {
+ if (p[0] || p[1] || (p[2] != 1)) {
+ printf ("demux_mpeg_block: error! %02x %02x %02x (should be 0x000001)\n",
+ p[0], p[1], p[2]);
+ buf->free_buffer (buf);
+#if 0
+ this->warned++;
+ if (this->warned > 5) {
+ xine_log (this->stream->xine, XINE_LOG_MSG,
+ _("demux_mpeg_block: too many errors, stopping playback. Maybe this stream is scrambled?\n"));
+ this->status = DEMUX_FINISHED;
+ }
+#endif
+ return;
+ }
- bMpeg1 = (p[4] & 0x40) == 0;
+ this->stream_id = p[3];
+
+ if (this->stream_id == 0xBA) {
+ result = parse_program_stream_pack_header(this, p, buf);
+ } else if (this->stream_id == 0xBB) {
+ result = parse_program_stream_system_header(this, p, buf);
+ } else if (this->stream_id == 0xBC) {
+ result = parse_program_stream_map(this, p, buf);
+ } else if (this->stream_id == 0xBD) {
+ result = parse_private_stream_1(this, p, buf);
+ } else if (this->stream_id == 0xBE) {
+ result = parse_padding_stream(this, p, buf);
+ } else if (this->stream_id == 0xBF) {
+ result = parse_private_stream_2(this, p, buf);
+ } else if ((this->stream_id >= 0xC0)
+ && (this->stream_id < 0xDF)) {
+ result = parse_audio_stream(this, p, buf);
+ } else if ((this->stream_id >= 0xE0)
+ && (this->stream_id < 0xEF)) {
+ result = parse_video_stream(this, p, buf);
+ } else if (this->stream_id == 0xF0) {
+ result = parse_ecm_stream(this, p, buf);
+ } else if (this->stream_id == 0xF1) {
+ result = parse_emm_stream(this, p, buf);
+ } else if (this->stream_id == 0xF2) {
+ result = parse_dsmcc_stream(this, p, buf);
+ } else if (this->stream_id == 0xF3) {
+ result = parse_iec_13522_stream(this, p, buf);
+ } else if (this->stream_id == 0xF4) {
+ result = parse_h222_typeA_stream(this, p, buf);
+ } else if (this->stream_id == 0xF5) {
+ result = parse_h222_typeB_stream(this, p, buf);
+ } else if (this->stream_id == 0xF6) {
+ result = parse_h222_typeC_stream(this, p, buf);
+ } else if (this->stream_id == 0xF7) {
+ result = parse_h222_typeD_stream(this, p, buf);
+ } else if (this->stream_id == 0xF8) {
+ result = parse_h222_typeE_stream(this, p, buf);
+ } else if (this->stream_id == 0xF9) {
+ result = parse_ancillary_stream(this, p, buf);
+ } else if (this->stream_id == 0xFA) {
+ result = parse_IEC14496_SL_packetized_stream(this, p, buf);
+ } else if (this->stream_id == 0xFB) {
+ result = parse_IEC14496_FlexMux_stream(this, p, buf);
+ /* 0xFC, 0xFD, 0xFE reserved */
+ } else if (this->stream_id == 0xFF) {
+ result = parse_program_stream_directory(this, p, buf);
+ } else {
+ printf("xine-lib:demux_mpeg_block: Unrecognised stream_id %02x\n", this->stream_id);
+ assert(0);
+ }
+ if (result < 0) {
+ return;
+ }
+ p+=result;
+ }
+ buf->free_buffer (buf);
+ assert(0);
- if (bMpeg1) {
+ return ;
+}
- /* system_clock_reference */
+static int32_t parse_program_stream_map(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_padding_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_ecm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_emm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_dsmcc_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_iec_13522_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_h222_typeA_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_h222_typeB_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_h222_typeC_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_h222_typeD_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_h222_typeE_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_program_stream_directory(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
+static int32_t parse_ancillary_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ assert(0);
+}
- scr = (p[4] & 0x02) << 30;
- scr |= (p[5] & 0xFF) << 22;
- scr |= (p[6] & 0xFE) << 14;
- scr |= (p[7] & 0xFF) << 7;
- scr |= (p[8] & 0xFE) >> 1;
+static int32_t parse_program_stream_pack_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ /* program stream pack header */
- /* buf->scr = scr; */
+ this->mpeg1 = (p[4] & 0x40) == 0;
- /* mux_rate */
+ if (this->mpeg1) {
- if (!this->rate) {
- this->rate = (p[9] & 0x7F) << 15;
- this->rate |= (p[10] << 7);
- this->rate |= (p[11] >> 1);
- }
+ /* system_clock_reference */
- p += 12;
+ this->scr = (p[4] & 0x02) << 30;
+ this->scr |= (p[5] & 0xFF) << 22;
+ this->scr |= (p[6] & 0xFE) << 14;
+ this->scr |= (p[7] & 0xFF) << 7;
+ this->scr |= (p[8] & 0xFE) >> 1;
- } else { /* mpeg2 */
-
- int num_stuffing_bytes;
-
- /* system_clock_reference */
-
- scr = (p[4] & 0x08) << 27 ;
- scr |= (p[4] & 0x03) << 28 ;
- scr |= p[5] << 20;
- scr |= (p[6] & 0xF8) << 12 ;
- scr |= (p[6] & 0x03) << 13 ;
- scr |= p[7] << 5;
- scr |= (p[8] & 0xF8) >> 3;
- /* optional - decode extension:
- scr *=300;
- scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) );
- */
+ /* buf->scr = scr; */
-#ifdef LOG
- printf ("demux_mpeg_block: SCR=%lld\n", scr);
-#endif
+ /* mux_rate */
- /* mux_rate */
+ if (!this->rate) {
+ this->rate = (p[9] & 0x7F) << 15;
+ this->rate |= (p[10] << 7);
+ this->rate |= (p[11] >> 1);
+ }
- if (!this->rate) {
- this->rate = (p[0xA] << 14);
- this->rate |= (p[0xB] << 6);
- this->rate |= (p[0xB] >> 2);
- }
+ return 12;
- num_stuffing_bytes = p[0xD] & 0x07;
+ } else { /* mpeg2 */
+
+ int num_stuffing_bytes;
+
+ /* system_clock_reference */
+
+ this->scr = (p[4] & 0x08) << 27 ;
+ this->scr |= (p[4] & 0x03) << 28 ;
+ this->scr |= p[5] << 20;
+ this->scr |= (p[6] & 0xF8) << 12 ;
+ this->scr |= (p[6] & 0x03) << 13 ;
+ this->scr |= p[7] << 5;
+ this->scr |= (p[8] & 0xF8) >> 3;
+ /* optional - decode extension:
+ this->scr *=300;
+ this->scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) );
+ */
- p += 14 + num_stuffing_bytes;
- }
- }
+#ifdef LOG
+ printf ("demux_mpeg_block: SCR=%lld\n", scr);
+#endif
- if (p[3] == 0xbb) { /* program stream system header */
+ /* mux_rate */
- int header_len;
+ if (!this->rate) {
+ this->rate = (p[0xA] << 14);
+ this->rate |= (p[0xB] << 6);
+ this->rate |= (p[0xB] >> 2);
+ }
- header_len = (p[4] << 8) | p[5];
+ num_stuffing_bytes = p[0xD] & 0x07;
- p += 6 + header_len;
+ return 14 + num_stuffing_bytes;
}
- /* we should now have a PES packet here */
+}
- if (p[0] || p[1] || (p[2] != 1)) {
- printf ("demux_mpeg_block: error! %02x %02x %02x (should be 0x000001)\n",
- p[0], p[1], p[2]);
- buf->free_buffer (buf);
+static int32_t parse_program_stream_system_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ /* program stream system header */
- this->warned++;
- if (this->warned > 5) {
- xine_log (this->stream->xine, XINE_LOG_MSG,
- _("demux_mpeg_block: too many errors, stopping playback. Maybe this stream is scrambled?\n"));
- this->status = DEMUX_FINISHED;
- }
+ int32_t header_len;
- return;
- }
+ header_len = (p[4] << 8) | p[5];
+ return 6 + header_len;
+}
- packet_len = p[4] << 8 | p[5];
- stream_id = p[3];
+static int32_t parse_private_stream_2(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
- if (stream_id == 0xbf) { /* NAV Packet */
+ /* NAV Packet */
+ this->packet_len = p[4] << 8 | p[5];
- int64_t start_pts, end_pts;
+ int64_t start_pts, end_pts;
- start_pts = (p[7+12] << 24);
- start_pts |= (p[7+13] << 16);
- start_pts |= (p[7+14] << 8);
- start_pts |= p[7+15];
+ start_pts = (p[7+12] << 24);
+ start_pts |= (p[7+13] << 16);
+ start_pts |= (p[7+14] << 8);
+ start_pts |= p[7+15];
- end_pts = (p[7+16] << 24);
- end_pts |= (p[7+17] << 16);
- end_pts |= (p[7+18] << 8);
- end_pts |= p[7+19];
+ end_pts = (p[7+16] << 24);
+ end_pts |= (p[7+17] << 16);
+ end_pts |= (p[7+18] << 8);
+ end_pts |= p[7+19];
- /* some input plugins like DVD can have better timing information and have
- * already set the input_time, so we can use the cell elapsed time from
- * the NAV packet for a much more accurate timing */
- if (buf->extra_info->input_time) {
- int64_t cell_time, frames;
+ /* some input plugins like DVD can have better timing information and have
+ * already set the input_time, so we can use the cell elapsed time from
+ * the NAV packet for a much more accurate timing */
+ if (buf->extra_info->input_time) {
+ int64_t cell_time, frames;
- cell_time = (p[7+0x18] >> 4 ) * 10 * 60 * 60 * 1000;
- cell_time += (p[7+0x18] & 0x0f) * 60 * 60 * 1000;
- cell_time += (p[7+0x19] >> 4 ) * 10 * 60 * 1000;
- cell_time += (p[7+0x19] & 0x0f) * 60 * 1000;
- cell_time += (p[7+0x1a] >> 4 ) * 10 * 1000;
- cell_time += (p[7+0x1a] & 0x0f) * 1000;
- frames = ((p[7+0x1b] & 0x30) >> 4) * 10;
- frames += ((p[7+0x1b] & 0x0f) ) ;
-
- if (p[7+0x1b] & 0x80)
- cell_time += (frames * 1000)/25;
- else
- cell_time += (frames * 1000)/30;
-
- this->last_cell_time = cell_time;
- this->last_cell_pos = buf->extra_info->input_pos;
- this->last_begin_time = buf->extra_info->input_time;
- }
+ cell_time = (p[7+0x18] >> 4 ) * 10 * 60 * 60 * 1000;
+ cell_time += (p[7+0x18] & 0x0f) * 60 * 60 * 1000;
+ cell_time += (p[7+0x19] >> 4 ) * 10 * 60 * 1000;
+ cell_time += (p[7+0x19] & 0x0f) * 60 * 1000;
+ cell_time += (p[7+0x1a] >> 4 ) * 10 * 1000;
+ cell_time += (p[7+0x1a] & 0x0f) * 1000;
+ frames = ((p[7+0x1b] & 0x30) >> 4) * 10;
+ frames += ((p[7+0x1b] & 0x0f) ) ;
+
+ if (p[7+0x1b] & 0x80)
+ cell_time += (frames * 1000)/25;
+ else
+ cell_time += (frames * 1000)/30;
+
+ this->last_cell_time = cell_time;
+ this->last_cell_pos = buf->extra_info->input_pos;
+ this->last_begin_time = buf->extra_info->input_time;
+ }
#ifdef LOG
- printf ("demux_mpeg_block: NAV packet, start pts = %lld, end_pts = %lld\n",
- start_pts, end_pts);
+ printf ("demux_mpeg_block: NAV packet, start pts = %lld, end_pts = %lld\n",
+ start_pts, end_pts);
#endif
- if (this->nav_last_end_pts != start_pts && !preview_mode) {
+ if (this->nav_last_end_pts != start_pts && !this->preview_mode) {
#ifdef LOG
- printf("demux_mpeg_block: discontinuity detected by nav packet\n" );
+ printf("demux_mpeg_block: discontinuity detected by nav packet\n" );
#endif
- if (this->buf_flag_seek) {
- xine_demux_control_newpts(this->stream, start_pts, BUF_FLAG_SEEK);
- this->buf_flag_seek = 0;
- } else {
- xine_demux_control_newpts(this->stream, start_pts, 0);
- }
+ if (this->buf_flag_seek) {
+ xine_demux_control_newpts(this->stream, start_pts, BUF_FLAG_SEEK);
+ this->buf_flag_seek = 0;
+ } else {
+ xine_demux_control_newpts(this->stream, start_pts, 0);
}
- this->nav_last_end_pts = end_pts;
- this->nav_last_start_pts = start_pts;
- this->send_newpts = 0;
- this->last_pts[PTS_AUDIO] = this->last_pts[PTS_VIDEO] = 0;
-
- buf->content = p;
- buf->size = packet_len;
- buf->type = BUF_SPU_DVD;
- buf->decoder_flags |= BUF_FLAG_SPECIAL;
- buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
- buf->decoder_info[2] = SPU_DVD_SUBTYPE_NAV;
- buf->pts = 0; /* NAV packets do not have PES values */
- this->video_fifo->put (this->video_fifo, buf);
-
- return ;
}
+ this->nav_last_end_pts = end_pts;
+ this->nav_last_start_pts = start_pts;
+ this->send_newpts = 0;
+ this->last_pts[PTS_AUDIO] = this->last_pts[PTS_VIDEO] = 0;
+
+ buf->content = p;
+ buf->size = this->packet_len;
+ buf->type = BUF_SPU_DVD;
+ buf->decoder_flags |= BUF_FLAG_SPECIAL;
+ buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
+ buf->decoder_info[2] = SPU_DVD_SUBTYPE_NAV;
+ buf->pts = 0; /* NAV packets do not have PES values */
+ this->video_fifo->put (this->video_fifo, buf);
+
+ return -1;
+}
+static int32_t parse_pes_for_pts(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ int32_t header_len;
+
+ this->packet_len = p[4] << 8 | p[5];
/* some input plugins like DVD can have better timing information and have
* already set the total_time, so we can derive our datarate from this */
if (buf->extra_info->total_time)
@@ -393,43 +538,41 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
if (this->rate && !buf->extra_info->input_time)
buf->extra_info->input_time = (int)((int64_t)buf->extra_info->input_pos
* 1000 / (this->rate * 50));
-
- if (bMpeg1) {
-
- if (stream_id == 0xBF) {
+ if (this->mpeg1) {
+ if (this->stream_id == 0xBF) {
buf->free_buffer (buf);
- return ;
+ return -1;
}
p += 6; /* packet_len -= 6; */
while ((p[0] & 0x80) == 0x80) {
p++;
- packet_len--;
+ this->packet_len--;
/* printf ("stuffing\n");*/
}
if ((p[0] & 0xc0) == 0x40) {
/* STD_buffer_scale, STD_buffer_size */
p += 2;
- packet_len -=2;
+ this->packet_len -=2;
}
- pts = 0;
+ this->pts = 0;
if ((p[0] & 0xf0) == 0x20) {
- pts = (p[ 0] & 0x0E) << 29 ;
- pts |= p[ 1] << 22 ;
- pts |= (p[ 2] & 0xFE) << 14 ;
- pts |= p[ 3] << 7 ;
- pts |= (p[ 4] & 0xFE) >> 1 ;
+ this->pts = (p[ 0] & 0x0E) << 29 ;
+ this->pts |= p[ 1] << 22 ;
+ this->pts |= (p[ 2] & 0xFE) << 14 ;
+ this->pts |= p[ 3] << 7 ;
+ this->pts |= (p[ 4] & 0xFE) >> 1 ;
p += 5;
- packet_len -=5;
+ this->packet_len -=5;
} else if ((p[0] & 0xf0) == 0x30) {
- pts = (p[ 0] & 0x0E) << 29 ;
- pts |= p[ 1] << 22 ;
- pts |= (p[ 2] & 0xFE) << 14 ;
- pts |= p[ 3] << 7 ;
- pts |= (p[ 4] & 0xFE) >> 1 ;
+ this->pts = (p[ 0] & 0x0E) << 29 ;
+ this->pts |= p[ 1] << 22 ;
+ this->pts |= (p[ 2] & 0xFE) << 14 ;
+ this->pts |= p[ 3] << 7 ;
+ this->pts |= (p[ 4] & 0xFE) >> 1 ;
/* DTS decoding code is working, but not used in xine
DTS = (p[ 5] & 0x0E) << 29 ;
DTS |= p[ 6] << 22 ;
@@ -438,13 +581,16 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
DTS |= (p[ 9] & 0xFE) >> 1 ;
*/
p += 10;
- packet_len -= 10;
+ this->packet_len -= 10;
} else {
p++;
- packet_len --;
+ this->packet_len --;
}
} else { /* mpeg 2 */
+
+
+
#if CHECK_DVD_PES_SCRAMBLED
/* check PES scrambling_control */
@@ -458,18 +604,18 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
if (p[7] & 0x80) { /* pts avail */
- pts = (p[ 9] & 0x0E) << 29 ;
- pts |= p[10] << 22 ;
- pts |= (p[11] & 0xFE) << 14 ;
- pts |= p[12] << 7 ;
- pts |= (p[13] & 0xFE) >> 1 ;
+ this->pts = (p[ 9] & 0x0E) << 29 ;
+ this->pts |= p[10] << 22 ;
+ this->pts |= (p[11] & 0xFE) << 14 ;
+ this->pts |= p[12] << 7 ;
+ this->pts |= (p[13] & 0xFE) >> 1 ;
#ifdef LOG
printf ("demux_mpeg_block: pts = %lld\n", pts);
#endif
} else
- pts = 0;
+ this->pts = 0;
/* code is working but not used in xine
if (p[7] & 0x40) {
@@ -487,33 +633,41 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
header_len = p[8];
- p += header_len + 9;
- packet_len -= header_len + 3;
+ this->packet_len -= header_len + 3;
+ return header_len + 9;
}
+ return 0;
+}
- if (stream_id == 0xbd) {
+static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
int track, spu_id;
-
+ int32_t result;
+
+ result = parse_pes_for_pts(this, p, buf);
+ if (result < 0) assert(0);
+
+ p += result;
track = p[0] & 0x0F; /* hack : ac3 track */
if((p[0] & 0xE0) == 0x20) {
spu_id = (p[0] & 0x1f);
buf->content = p+1;
- buf->size = packet_len-1;
+ buf->size = this->packet_len-1;
+
buf->type = BUF_SPU_DVD + spu_id;
buf->decoder_flags |= BUF_FLAG_SPECIAL;
buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
- buf->pts = pts;
+ buf->pts = this->pts;
this->video_fifo->put (this->video_fifo, buf);
#ifdef LOG
printf ("demux_mpeg_block: SPU PACK put on fifo\n");
#endif
- return;
+ return -1;
}
/* SVCD OGT subtitles in stream 0x70 */
@@ -521,19 +675,19 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
spu_id = p[1];
buf->content = p+1;
- buf->size = packet_len-1;
+ buf->size = this->packet_len-1;
buf->type = BUF_SPU_SVCD + spu_id;
- buf->pts = pts;
+ buf->pts = this->pts;
/* this is probably wrong:
if( !preview_mode )
- check_newpts( this, pts, PTS_VIDEO );
+ check_newpts( this, this->pts, PTS_VIDEO );
*/
this->video_fifo->put (this->video_fifo, buf);
#ifdef LOG
- printf ("demux_mpeg_block: SPU SVCD PACK (%lld, %d) put on fifo\n", pts, spu_id);
+ printf ("demux_mpeg_block: SPU SVCD PACK (%lld, %d) put on fifo\n", this->pts, spu_id);
#endif
- return;
+ return -1;
}
/* SVCD CVD subtitles in streams 0x00-0x03 */
@@ -541,37 +695,36 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
spu_id = (p[0] & 0x03);
buf->content = p+1;
- buf->size = packet_len-1;
+ buf->size = this->packet_len-1;
buf->type = BUF_SPU_CVD + spu_id;
- buf->pts = pts;
+ buf->pts = this->pts;
/* this is probably wrong:
if( !preview_mode )
- check_newpts( this, pts, PTS_VIDEO );
+ check_newpts( this, this->pts, PTS_VIDEO );
*/
this->video_fifo->put (this->video_fifo, buf);
#ifdef LOG
- printf ("demux_mpeg_block: SPU CVD PACK (%lld, %d) put on fifo\n", pts, spu_id);
+ printf ("demux_mpeg_block: SPU CVD PACK (%lld, %d) put on fifo\n", this->pts, spu_id);
#endif
- return;
+ return -1;
}
if ((p[0]&0xF0) == 0x80) {
- /* printf ( "ac3 PES packet, track %02x\n",track); */
buf->decoder_info[1] = p[1]; /* Number of frame headers */
buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */
buf->content = p+4;
- buf->size = packet_len-4;
+ buf->size = this->packet_len-4;
if (track & 0x8) {
buf->type = BUF_AUDIO_DTS + (track & 0x07); /* DVDs only have 8 tracks */
} else {
buf->type = BUF_AUDIO_A52 + track;
}
- buf->pts = pts;
- if( !preview_mode )
- check_newpts( this, pts, PTS_AUDIO );
+ buf->pts = this->pts;
+ if( !this->preview_mode )
+ check_newpts( this, this->pts, PTS_AUDIO );
if(this->audio_fifo) {
this->audio_fifo->put (this->audio_fifo, buf);
@@ -581,7 +734,6 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
} else
buf->free_buffer(buf);
- return ;
} else if ((p[0]&0xf0) == 0xa0) {
int pcm_offset;
@@ -631,11 +783,11 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
pcm_offset = 7;
buf->content = p+pcm_offset;
- buf->size = packet_len-pcm_offset;
+ buf->size = this->packet_len-pcm_offset;
buf->type = BUF_AUDIO_LPCM_BE + track;
- buf->pts = pts;
- if( !preview_mode )
- check_newpts( this, pts, PTS_AUDIO );
+ buf->pts = this->pts;
+ if( !this->preview_mode )
+ check_newpts( this, this->pts, PTS_AUDIO );
if(this->audio_fifo) {
this->audio_fifo->put (this->audio_fifo, buf);
@@ -645,52 +797,61 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m
} else
buf->free_buffer(buf);
- return ;
}
- } else if ((stream_id >= 0xbc) && ((stream_id & 0xf0) == 0xe0)) {
+ return -1;
+}
+static int32_t parse_video_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
+ int32_t result;
- buf->content = p;
- buf->size = packet_len;
- buf->type = BUF_VIDEO_MPEG;
- buf->pts = pts;
- if( !preview_mode )
- check_newpts( this, pts, PTS_VIDEO );
+ result = parse_pes_for_pts(this, p, buf);
+ if (result < 0) assert(0);
- this->video_fifo->put (this->video_fifo, buf);
+ p += result;
+
+ buf->content = p;
+ buf->size = this->packet_len;
+ buf->type = BUF_VIDEO_MPEG;
+ buf->pts = this->pts;
+ if( !this->preview_mode )
+ check_newpts( this, this->pts, PTS_VIDEO );
+
+ this->video_fifo->put (this->video_fifo, buf);
#ifdef LOG
- printf ("demux_mpeg_block: MPEG Video PACK put on fifo\n");
+ printf ("demux_mpeg_block: MPEG Video PACK put on fifo\n");
#endif
- return ;
+ return -1;
+}
- } else if ((stream_id & 0xe0) == 0xc0) {
- int track;
+static int32_t parse_audio_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) {
- track = stream_id & 0x1f;
+ int track;
+ int32_t result;
- buf->content = p;
- buf->size = packet_len;
- buf->type = BUF_AUDIO_MPEG + track;
- buf->pts = pts;
- if( !preview_mode )
- check_newpts( this, pts, PTS_AUDIO );
+ result = parse_pes_for_pts(this, p, buf);
+ if (result < 0) assert(0);
- if(this->audio_fifo) {
- this->audio_fifo->put (this->audio_fifo, buf);
-#ifdef LOG
- printf ("demux_mpeg_block: MPEG Audio PACK put on fifo\n");
-#endif
- } else
- buf->free_buffer(buf);
+ p += result;
- return ;
+ track = this->stream_id & 0x1f;
- }
- buf->free_buffer (buf);
+ buf->content = p;
+ buf->size = this->packet_len;
+ buf->type = BUF_AUDIO_MPEG + track;
+ buf->pts = this->pts;
+ if( !this->preview_mode )
+ check_newpts( this, this->pts, PTS_AUDIO );
- return ;
-
+ if(this->audio_fifo) {
+ this->audio_fifo->put (this->audio_fifo, buf);
+#ifdef LOG
+ printf ("demux_mpeg_block: MPEG Audio PACK put on fifo\n");
+#endif
+ }
+ buf->free_buffer(buf);
+
+ return -1;
}
static int demux_mpeg_block_send_chunk (demux_plugin_t *this_gen) {
@@ -856,6 +1017,7 @@ static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) {
break;
}
+}
#ifdef LOG
printf("demux_mpeg_block:est_rate=%d\n",rate);