diff options
author | phintuka <phintuka> | 2009-02-08 20:24:00 +0000 |
---|---|---|
committer | phintuka <phintuka> | 2009-02-08 20:24:00 +0000 |
commit | b1c7f0b01f04ffda5c9a3d917b8fcefb318d5318 (patch) | |
tree | 7e7ed3eb965cf0e326993545d9ebffef980b3a3a | |
parent | 6df9533dfa1008167c3b9f2a1e854a315afb8df4 (diff) | |
download | xineliboutput-b1c7f0b01f04ffda5c9a3d917b8fcefb318d5318.tar.gz xineliboutput-b1c7f0b01f04ffda5c9a3d917b8fcefb318d5318.tar.bz2 |
Removed code that is not used in xineliboutput
-rw-r--r-- | xine/demux_xvdr.c | 859 |
1 files changed, 40 insertions, 819 deletions
diff --git a/xine/demux_xvdr.c b/xine/demux_xvdr.c index 8b32eeb3..cd2409b6 100644 --- a/xine/demux_xvdr.c +++ b/xine/demux_xvdr.c @@ -1,18 +1,18 @@ /* * Copyright (C) 2000-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA @@ -20,10 +20,6 @@ * demultiplexer for mpeg 1/2 program streams * used with fixed blocksize devices (like dvd/vcd) */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include <stdlib.h> #include <stdio.h> @@ -31,26 +27,15 @@ #include <unistd.h> #include <string.h> -#ifdef HAVE_FFMPEG_AVUTIL_H -# include <mem.h> -#else -# include <libavutil/mem.h> -#endif - #define LOG_MODULE "demux_mpeg_block" -#define LOG_VERBOSE -/* -#define LOG -*/ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/demux.h> -#define NUM_PREVIEW_BUFFERS 250 #define DISC_TRESHOLD 90000 -#define WRAP_THRESHOLD 120000 +#define WRAP_THRESHOLD 120000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 @@ -62,37 +47,25 @@ typedef struct demux_mpeg_block_s { demux_plugin_t demux_plugin; - xine_stream_t *stream; + xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; - - int blocksize; - int rate; char cur_mrl[256]; - uint8_t *scratch; - - int64_t nav_last_end_pts; - 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; int64_t dts; uint32_t stream_id; int32_t mpeg1; - int64_t last_cell_time; - off_t last_cell_pos; - int last_begin_time; } demux_mpeg_block_t ; typedef struct { @@ -107,60 +80,17 @@ typedef struct { 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); - - -/* OK, i think demux_mpeg_block discontinuity handling demands some - explanation: - - - The preferred discontinuity handling/detection for DVD is based on - NAV packets information. Most of the time it will provide us very - accurate and reliable information. - - - Has been shown that sometimes a DVD discontinuity may happen before - a new NAV packet arrives (seeking?). To avoid sending wrong PTS to - decoders we _used_ to check for SCR discontinuities. Unfortunately - some VCDs have very broken SCR values causing false triggering. - - - To fix the above problem (also note that VCDs don't have NAV - packets) we fallback to the same PTS-based wrap detection as used - in demux_mpeg. The only trick is to not send discontinuity information - if NAV packets have already done the job. - - [Miguel 02-05-2002] -*/ + static void check_newpts( demux_mpeg_block_t *this, int64_t pts, int video ) { int64_t diff; - + diff = pts - this->last_pts[video]; - - if( pts && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { - /* check if pts is outside nav pts range. any stream without nav must enter here. */ - if( pts > this->nav_last_end_pts || pts < this->nav_last_start_pts ) - { - lprintf("discontinuity detected by pts wrap\n"); + if( pts && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); @@ -169,25 +99,21 @@ static void check_newpts( demux_mpeg_block_t *this, int64_t pts, int video ) _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; - } else { - lprintf("no wrap detected\n" ); - } - + this->last_pts[1-video] = 0; } - + if( pts ) this->last_pts[video] = pts; } -static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_mode) { +static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this) { buf_element_t *buf = NULL; uint8_t *p; int32_t result; this->scr = 0; - this->preview_mode = preview_mode; lprintf ("read_block\n"); @@ -224,14 +150,7 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m } p = buf->content; /* len = this->blocksize; */ - if (preview_mode) - buf->decoder_flags = BUF_FLAG_PREVIEW; - else - buf->decoder_flags = 0; - - if( this->input->get_length (this->input) ) - buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * - 65535 / this->input->get_length (this->input) ); + buf->decoder_flags = 0; while(p < (buf->content + this->blocksize)) { if (p[0] || p[1] || (p[2] != 1)) { @@ -249,51 +168,16 @@ static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_m 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) { + 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 { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("xine-lib:demux_mpeg_block: " @@ -317,246 +201,6 @@ static int32_t parse_padding_stream(demux_mpeg_block_t *this, uint8_t *p, buf_el buf->free_buffer (buf); return -1; } -static int32_t parse_program_stream_map(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x.\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_ecm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_emm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_dsmcc_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_iec_13522_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_h222_typeA_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_h222_typeB_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_h222_typeC_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_h222_typeD_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_h222_typeE_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_program_stream_directory(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -1; -} -static int32_t parse_ancillary_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* FIXME: Implement */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); - buf->free_buffer (buf); - return -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 */ - - this->mpeg1 = (p[4] & 0x40) == 0; - - if (this->mpeg1) { - /* system_clock_reference */ - - this->scr = (int64_t)(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; - - /* buf->scr = scr; */ - - /* mux_rate */ - - if (!this->rate) { - this->rate = (p[9] & 0x7F) << 15; - this->rate |= (p[10] << 7); - this->rate |= (p[11] >> 1); - } - - return 12; - - } else { /* mpeg2 */ - - int num_stuffing_bytes; - - /* system_clock_reference */ - - this->scr = (int64_t)(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) ); - */ - - lprintf ("SCR=%"PRId64"\n", this->scr); - - /* mux_rate */ - - if (!this->rate) { - this->rate = (p[0xA] << 14); - this->rate |= (p[0xB] << 6); - this->rate |= (p[0xC] >> 2); - } - - num_stuffing_bytes = p[0xD] & 0x07; - - return 14 + num_stuffing_bytes; - } - -} - -static int32_t parse_program_stream_system_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - /* program stream system header */ - - int32_t header_len; - - header_len = (p[4] << 8) | p[5]; - return 6 + header_len; -} - -static int32_t parse_private_stream_2(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { - int64_t start_pts, end_pts; - - /* NAV Packet */ - this->packet_len = p[4] << 8 | p[5]; - - start_pts = ((int64_t)p[7+12] << 24); - start_pts |= (p[7+13] << 16); - start_pts |= (p[7+14] << 8); - start_pts |= p[7+15]; - - end_pts = ((int64_t)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; - - 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 = this->input->get_current_pos (this->input); - this->last_begin_time = buf->extra_info->input_time; - } - - lprintf ("NAV packet, start pts = %"PRId64", end_pts = %"PRId64"\n", - start_pts, end_pts); - - if (this->nav_last_end_pts != start_pts && !this->preview_mode) { - - lprintf("discontinuity detected by nav packet\n" ); - - if (this->buf_flag_seek) { - _x_demux_control_newpts(this->stream, start_pts, BUF_FLAG_SEEK); - this->buf_flag_seek = 0; - } else { - _x_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 = 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; -} /* FIXME: Extension data is not parsed, and is also not skipped. */ @@ -564,27 +208,13 @@ static int32_t parse_pes_for_pts(demux_mpeg_block_t *this, uint8_t *p, buf_eleme 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) - this->rate = (int)((int64_t)this->input->get_length (this->input) * 1000 / - (buf->extra_info->total_time * 50)); - - if (this->rate && this->last_cell_time) { - if( this->last_begin_time == buf->extra_info->input_time ) - buf->extra_info->input_time = this->last_cell_time + buf->extra_info->input_time + - ((this->input->get_current_pos (this->input) - this->last_cell_pos) * 1000 / (this->rate * 50)); - } - if (this->rate && !buf->extra_info->input_time) - buf->extra_info->input_time = (int)((int64_t)this->input->get_current_pos (this->input) - * 1000 / (this->rate * 50)); if (this->mpeg1) { header_len = 6; p += 6; /* packet_len -= 6; */ while ((p[0] & 0x80) == 0x80) { - p++; + p++; header_len++; this->packet_len--; /* printf ("stuffing\n");*/ @@ -597,9 +227,9 @@ static int32_t parse_pes_for_pts(demux_mpeg_block_t *this, uint8_t *p, buf_eleme this->packet_len -= 2; } - this->pts = 0; + this->pts = 0; this->dts = 0; - + if ((p[0] & 0xf0) == 0x20) { this->pts = (int64_t)(p[ 0] & 0x0E) << 29 ; this->pts |= p[ 1] << 22 ; @@ -616,19 +246,19 @@ static int32_t parse_pes_for_pts(demux_mpeg_block_t *this, uint8_t *p, buf_eleme this->pts |= (p[ 2] & 0xFE) << 14 ; this->pts |= p[ 3] << 7 ; this->pts |= (p[ 4] & 0xFE) >> 1 ; - + this->dts = (int64_t)(p[ 5] & 0x0E) << 29 ; this->dts |= p[ 6] << 22 ; this->dts |= (p[ 7] & 0xFE) << 14 ; this->dts |= p[ 8] << 7 ; this->dts |= (p[ 9] & 0xFE) >> 1 ; - + p += 10; header_len += 10; this->packet_len -= 10; return header_len; } else { - p++; + p++; header_len++; this->packet_len--; return header_len; @@ -672,13 +302,13 @@ static int32_t parse_pes_for_pts(demux_mpeg_block_t *this, uint8_t *p, buf_eleme this->pts = 0; if (p[7] & 0x40) { /* dts avail */ - + this->dts = (int64_t)(p[14] & 0x0E) << 29 ; this->dts |= p[15] << 22 ; this->dts |= (p[16] & 0xFE) << 14 ; this->dts |= p[17] << 7 ; this->dts |= (p[18] & 0xFE) >> 1 ; - + } else this->dts = 0; @@ -707,71 +337,35 @@ static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_ buf->content = p+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 = this->pts; - - this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU PACK put on fifo\n"); - - return -1; - } - - /* SVCD OGT subtitles in stream 0x70 */ - if(p[0] == 0x70 && (p[1] & 0xFC) == 0x00) { - spu_id = p[1]; - buf->content = p+1; - buf->size = this->packet_len-1; - buf->type = BUF_SPU_SVCD + spu_id; - buf->pts = this->pts; - /* this is probably wrong: - if( !preview_mode ) - check_newpts( this, this->pts, PTS_VIDEO ); - */ - this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU SVCD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); - - return -1; - } - - /* SVCD CVD subtitles in streams 0x00-0x03 */ - if((p[0] & 0xFC) == 0x00) { - spu_id = (p[0] & 0x03); + this->video_fifo->put (this->video_fifo, buf); + lprintf ("SPU PACK put on fifo\n"); - buf->content = p+1; - buf->size = this->packet_len-1; - buf->type = BUF_SPU_CVD + spu_id; - buf->pts = this->pts; - /* this is probably wrong: - if( !preview_mode ) - check_newpts( this, this->pts, PTS_VIDEO ); - */ - this->video_fifo->put (this->video_fifo, buf); - lprintf ("SPU CVD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); - return -1; } if ((p[0]&0xF0) == 0x80) { - + track = p[0] & 0x0F; /* hack : ac3 track */ - /* Number of frame headers + /* Number of frame headers * * Describes the number of a52 frame headers that start in this pack (One pack per DVD sector). * * Likely values: 1 or 2. */ buf->decoder_info[1] = p[1]; - /* First access unit pointer. + /* First access unit pointer. * * Describes the byte offset within this pack to the beginning of the first A52 frame header. * The PTS from this pack applies to the beginning of the first A52 frame that starts in this pack. - * Any bytes before this offset should be considered to belong to the previous A52 frame. + * Any bytes before this offset should be considered to belong to the previous A52 frame. * and therefore be tagged with a PTS value derived from the previous pack. * * Likely values: Anything from 1 to the size of an A52 frame. @@ -872,7 +466,7 @@ static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_ buf->free_buffer(buf); return -1; } - + } else if ((p[0]&0xf0) == 0xa0) { int pcm_offset; @@ -919,7 +513,7 @@ static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_ buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG; buf->decoder_info[2] = p[5]; - + pcm_offset = 7; buf->content = p+pcm_offset; @@ -938,7 +532,7 @@ static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_ buf->free_buffer(buf); return -1; } - + } /* Some new streams have been encountered. 1) DVD+RW disc recorded with a Philips DVD recorder: - new unknown sub-stream id of 0xff @@ -1005,182 +599,15 @@ static int demux_mpeg_block_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - demux_mpeg_block_parse_pack(this, 0); + demux_mpeg_block_parse_pack(this); return this->status; } -#ifdef ESTIMATE_RATE_FIXED -/*! - Estimate bitrate by looking inside the MPEG file for presentation - time stamps (PTS) and computing how far apart these are - in bytes and in time. - - On failure return 0. - - This might be used after deciding that mux_rate in a stream is faulty. - -*/ - -/* How many *sucessful* PTS samples do we take? */ -#define MAX_SAMPLES 5 - -/* How many times we read blocks before giving up. */ -#define MAX_READS 30 - -/* TRUNCATE x to the nearest multiple of y. */ -#define TRUNC(x,y) (((x) / (y)) * (y)) - -static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) { - - buf_element_t *buf = NULL; - unsigned char *p; - int is_mpeg1=0; - off_t pos, last_pos=0; - off_t step, mpeg_length; - off_t blocksize = this->blocksize; - int64_t pts, last_pts=0; - int reads=0 /* Number of blocks read so far */; - int count=0; /* Number of sucessful PTS found so far */ - int rate=0; /* The return rate value */ - int stream_id; - - /* We can't estimate by sampling if we don't thave the ability to - randomly access the and more importantly reset after accessessing. */ - if (!(this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE)) - return 0; - - mpeg_length= this->input->get_length (this->input); - step = TRUNC((mpeg_length/MAX_SAMPLES), blocksize); - if (step <= 0) step = blocksize; /* avoid endless loop for tiny files */ - pos = step; - - /* At this point "pos", and "step" are a multiple of blocksize and - they should continue to be so throughout. - */ - - this->input->seek (this->input, pos, SEEK_SET); - - while ( (buf = this->input->read_block (this->input, this->video_fifo, blocksize)) - && count < MAX_SAMPLES && reads++ < MAX_READS ) { - - p = buf->content; /* len = this->mnBlocksize; */ - - if (p[3] == 0xBA) { /* program stream pack header */ - - is_mpeg1 = (p[4] & 0x40) == 0; - - if (is_mpeg1) - p += 12; - else - p += 14 + (p[0xD] & 0x07); - } - - if (p[3] == 0xbb) /* program stream system header */ - p += 6 + ((p[4] << 8) | p[5]); - - /* we should now have a PES packet here */ - - if (p[0] || p[1] || (p[2] != 1)) { - xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_mpeg_block: error %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]); - buf->free_buffer (buf); - return rate; - } - - stream_id = p[3]; - pts = 0; - - if ((stream_id < 0xbc) || ((stream_id & 0xf0) != 0xe0)) { - pos += (off_t) blocksize; - buf->free_buffer (buf); - buf = NULL; - continue; /* only use video packets */ - } - - if (is_mpeg1) { - - if (p[3] != 0xBF) { /* stream_id */ - - p += 6; /* packet_len -= 6; */ - - while ((p[0] & 0x80) == 0x80) { - p++; /* stuffing */ - } - - if ((p[0] & 0xc0) == 0x40) { - /* STD_buffer_scale, STD_buffer_size */ - p += 2; - } - - if ( ((p[0] & 0xf0) == 0x20) || ((p[0] & 0xf0) == 0x30) ) { - pts = (int64_t)(p[ 0] & 0x0E) << 29 ; - pts |= p[ 1] << 22 ; - pts |= (p[ 2] & 0xFE) << 14 ; - pts |= p[ 3] << 7 ; - pts |= (p[ 4] & 0xFE) >> 1 ; - } - } - } else { /* mpeg 2 */ - - if (p[7] & 0x80) { /* pts avail */ - - 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 ; - - } else - pts = 0; - } - - if (pts) { - - - if ( (pos>last_pos) && (pts>last_pts) ) { - int cur_rate; - - cur_rate = ((pos - last_pos)*90000) / ((pts - last_pts) * 50); - - rate = (count * rate + cur_rate) / (count+1); - - count ++; - - /* - printf ("demux_mpeg_block: stream_id %02x, pos: %"PRId64", pts: %d, cur_rate = %d, overall rate : %d\n", - stream_id, pos, pts, cur_rate, rate); - */ - } - - last_pos = pos; - last_pts = pts; - pos += step; - } else - pos += blocksize; - - buf->free_buffer (buf); - buf = NULL; - - if (pos > mpeg_length || this->input->seek (this->input, pos, SEEK_SET) == (off_t)-1) - break; - - } - - if( buf ) - buf->free_buffer (buf); -} - - lprintf("est_rate=%d\n",rate); - return rate; - -} -#endif /*ESTIMATE_RATE_FIXED*/ - static void demux_mpeg_block_dispose (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - + av_free (this->scratch); free (this); } @@ -1191,28 +618,6 @@ static int demux_mpeg_block_get_status (demux_plugin_t *this_gen) { return this->status; } -static int demux_mpeg_detect_blocksize(demux_mpeg_block_t *this, - input_plugin_t *input) -{ - input->seek(input, 2048, SEEK_SET); - if (input->read(input, this->scratch, 4) != 4) - return 0; - - if (this->scratch[0] || this->scratch[1] - || (this->scratch[2] != 0x01) || (this->scratch[3] != 0xba)) { - - input->seek(input, 2324, SEEK_SET); - if (input->read(input, this->scratch, 4) != 4) - return 0; - if (this->scratch[0] || this->scratch[1] - || (this->scratch[2] != 0x01) || (this->scratch[3] != 0xba)) - return 0; - - return 2324; - } else - return 2048; -} - static void demux_mpeg_block_send_headers (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; @@ -1220,42 +625,11 @@ static void demux_mpeg_block_send_headers (demux_plugin_t *this_gen) { this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; - if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { - if (!this->blocksize) - this->blocksize = demux_mpeg_detect_blocksize( this, this->input ); - - if (!this->blocksize) - return; - } - - /* + /* * send start buffer */ - + _x_demux_control_start(this->stream); - -#ifdef USE_ILL_ADVISED_ESTIMATE_RATE_INITIALLY - if (!this->rate) - this->rate = demux_mpeg_block_estimate_rate (this); -#else - /* Set to Use rate given in by stream initially. */ - this->rate = 0; -#endif - - if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { - - int num_buffers = NUM_PREVIEW_BUFFERS; - - this->input->seek (this->input, 0, SEEK_SET); - - this->status = DEMUX_OK ; - while ( (num_buffers>0) && (this->status == DEMUX_OK) ) { - - demux_mpeg_block_parse_pack(this, 1); - num_buffers --; - } - } - /* else FIXME: implement preview generation from PREVIEW data */ this->status = DEMUX_OK; @@ -1269,82 +643,23 @@ static int demux_mpeg_block_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; - start_pos = (off_t) ( (double) start_pos / 65535 * - this->input->get_length (this->input) ); - - if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { - - if (start_pos) { - start_pos /= (off_t) this->blocksize; - start_pos *= (off_t) this->blocksize; - - this->input->seek (this->input, start_pos, SEEK_SET); - } else if (start_time) { - - if( this->input->seek_time ) { - this->input->seek_time (this->input, start_time, SEEK_SET); - } else { - start_time /= 1000; - - if (this->last_cell_time) { - start_pos = start_time - (this->last_cell_time + this->last_begin_time)/1000; - start_pos *= this->rate; - start_pos *= 50; - start_pos += this->last_cell_pos; - } else { - start_pos = start_time; - start_pos *= this->rate; - start_pos *= 50; - } - start_pos /= (off_t) this->blocksize; - start_pos *= (off_t) this->blocksize; - - this->input->seek (this->input, start_pos, SEEK_SET); - } - } else - this->input->seek (this->input, 0, SEEK_SET); - } - + /* * now start demuxing */ - this->last_cell_time = 0; this->send_newpts = 1; if( !playing ) { - + this->buf_flag_seek = 0; - this->nav_last_end_pts = this->nav_last_start_pts = 0; this->status = DEMUX_OK ; this->last_pts[0] = 0; this->last_pts[1] = 0; } else { this->buf_flag_seek = 1; - this->nav_last_end_pts = this->nav_last_start_pts = 0; _x_demux_flush_engine(this->stream); } - - return this->status; -} - - -static void demux_mpeg_block_accept_input (demux_mpeg_block_t *this, - input_plugin_t *input) { - - this->input = input; - - if (strcmp (this->cur_mrl, input->get_mrl(input))) { - - this->rate = 0; - - strncpy (this->cur_mrl, input->get_mrl(input), 256); - lprintf ("mrl %s is new\n", this->cur_mrl); - - } - else { - lprintf ("mrl %s is known, bitrate: %d\n", - this->cur_mrl, this->rate * 50 * 8); - } + return this->status; } static int demux_mpeg_block_get_stream_length (demux_plugin_t *this_gen) { @@ -1354,10 +669,6 @@ static int demux_mpeg_block_get_stream_length (demux_plugin_t *this_gen) { * find input plugin */ - if (this->rate) - return (int)((int64_t) 1000 * this->input->get_length (this->input) / - (this->rate * 50)); - else return 0; } @@ -1379,7 +690,7 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this = calloc(1, sizeof(demux_mpeg_block_t)); this->stream = stream; this->input = input; - + this->demux_plugin.send_headers = demux_mpeg_block_send_headers; this->demux_plugin.send_chunk = demux_mpeg_block_send_chunk; this->demux_plugin.seek = demux_mpeg_block_seek; @@ -1393,96 +704,6 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *str this->scratch = av_mallocz(4096); this->status = DEMUX_FINISHED; - lprintf ("open_plugin:detection_method=%d\n", - stream->content_detection_method); - - switch (stream->content_detection_method) { - - case METHOD_BY_CONTENT: { - - /* use demux_mpeg for non-block devices */ - if (!(input->get_capabilities(input) & INPUT_CAP_BLOCK)) { - av_free (this->scratch); - free (this); - return NULL; - } - - if (((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) ) { - - this->blocksize = input->get_blocksize(input); - lprintf("open_plugin:blocksize=%d\n",this->blocksize); - - if (!this->blocksize) - this->blocksize = demux_mpeg_detect_blocksize( this, input ); - - if (!this->blocksize) { - av_free (this->scratch); - free (this); - return NULL; - } - - input->seek(input, 0, SEEK_SET); - if (input->read(input, this->scratch, this->blocksize) == this->blocksize) { - lprintf("open_plugin:read worked\n"); - - if (this->scratch[0] || this->scratch[1] - || (this->scratch[2] != 0x01) || (this->scratch[3] != 0xba)) { - lprintf("open_plugin:scratch failed\n"); - - av_free (this->scratch); - free (this); - return NULL; - } - - /* if it's a file then make sure it's mpeg-2 */ - if ( !input->get_blocksize(input) - && ((this->scratch[4]>>4) != 4) ) { - av_free (this->scratch); - free (this); - return NULL; - } - - input->seek(input, 0, SEEK_SET); - - demux_mpeg_block_accept_input (this, input); - lprintf("open_plugin:Accepting detection_method XINE_DEMUX_CONTENT_STRATEGY blocksize=%d\n", - this->blocksize); - - break; - } - } - av_free (this->scratch); - free (this); - return NULL; - } - break; - - case METHOD_BY_MRL: - case METHOD_EXPLICIT: { - - this->blocksize = input->get_blocksize(input); - lprintf("open_plugin:blocksize=%d\n",this->blocksize); - - if (!this->blocksize && - ((input->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0)) - this->blocksize = demux_mpeg_detect_blocksize( this, input ); - - if (!this->blocksize) { - av_free (this->scratch); - free (this); - return NULL; - } - - demux_mpeg_block_accept_input (this, input); - } - break; - - default: - av_free (this->scratch); - free (this); - return NULL; - } - return &this->demux_plugin; } |