diff options
author | James Courtier-Dutton <jcdutton@users.sourceforge.net> | 2003-05-10 21:14:44 +0000 |
---|---|---|
committer | James Courtier-Dutton <jcdutton@users.sourceforge.net> | 2003-05-10 21:14:44 +0000 |
commit | b56000c3f13b7272d3cf5eb287f409c291e8f328 (patch) | |
tree | fff84fab8c78c65c0665d68a9aa0a212de7388e4 | |
parent | f90c12d614d5d50a1bd00b297aea60a61fb69c35 (diff) | |
download | xine-lib-b56000c3f13b7272d3cf5eb287f409c291e8f328.tar.gz xine-lib-b56000c3f13b7272d3cf5eb287f409c291e8f328.tar.bz2 |
Re-write of demux_mpeg_block.
DVDs play fine, but VCDs need testing.
Todo: remove asserts and report nice error messages back to the user.
This should fix the VCD problem, but "padding" still neads to be implemented.
So, if we see a "padding" stream, we currently assert(0).
This will at least prove that the VCD input plugin does not have to touch the scrambling tag.
CVS patchset: 4816
CVS date: 2003/05/10 21:14:44
-rw-r--r-- | src/demuxers/demux_mpeg_block.c | 600 |
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); |