diff options
author | Petri Hintukainen <phintuka@users.sourceforge.net> | 2011-10-17 14:51:30 +0300 |
---|---|---|
committer | Petri Hintukainen <phintuka@users.sourceforge.net> | 2011-10-17 14:51:30 +0300 |
commit | a88050e9a4993e903201a9882378e9d88e89dd79 (patch) | |
tree | 5fcee2fee3c4042b6f358537614cde5a62ae76dc | |
parent | 4467de60c581f2a5f7ae737c30ab63be0e3f6e25 (diff) | |
parent | 0b6b1aa65cb5b072540b2a35d5e5237c528e814b (diff) | |
download | xine-lib-a88050e9a4993e903201a9882378e9d88e89dd79.tar.gz xine-lib-a88050e9a4993e903201a9882378e9d88e89dd79.tar.bz2 |
Merge from 1.1
-rw-r--r-- | src/demuxers/demux_mpeg_pes.c | 28 | ||||
-rw-r--r-- | src/demuxers/demux_ts.c | 103 |
2 files changed, 118 insertions, 13 deletions
diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c index 5ad959d51..8d1f4b8af 100644 --- a/src/demuxers/demux_mpeg_pes.c +++ b/src/demuxers/demux_mpeg_pes.c @@ -949,6 +949,34 @@ static int32_t parse_private_stream_1(demux_mpeg_pes_t *this, uint8_t *p, buf_el } return this->packet_len + result; + /* EVOB AC3/E-AC-3 */ + } else if ((p[0]&0xf0) == 0xc0) { + + track = p[0] & 0x0F; /* hack : ac3 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 = this->packet_len-4; + if (p[4] == 0x0b && p[5] == 0x77 && ((p[9] >> 3) & 0x1f) <= 8) { + buf->type = BUF_AUDIO_A52 + track; + } else { + buf->type = BUF_AUDIO_EAC3 + track; + buf->decoder_flags |= BUF_FLAG_FRAME_END; + } + 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); + lprintf ("A52/EAC3 PACK put on fifo\n"); + + } else { + buf->free_buffer(buf); + } + return this->packet_len + result; + } else if ((p[0]&0xf0) == 0xa0) { int pcm_offset; diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 4736a9c82..45e822075 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -212,6 +212,16 @@ #define ISO13522_STREAM 0xF3 #define PROG_STREAM_DIR 0xFF +/* descriptors in PMT stream info */ +#define DESCRIPTOR_REG_FORMAT 0x05 +#define DESCRIPTOR_LANG 0x0a +#define DESCRIPTOR_TELETEXT 0x56 +#define DESCRIPTOR_DVBSUB 0x59 +#define DESCRIPTOR_AC3 0x6a +#define DESCRIPTOR_EAC3 0x7a +#define DESCRIPTOR_DTS 0x7b +#define DESCRIPTOR_AAC 0x7c + typedef enum { ISO_11172_VIDEO = 0x01, /* ISO/IEC 11172 Video */ @@ -254,6 +264,17 @@ #define PTS_AUDIO 0 #define PTS_VIDEO 1 +/* bitrate estimation */ +#define TBRE_MIN_TIME ( 2 * 90000) +#define TBRE_TIME (480 * 90000) + +#define TBRE_MODE_PROBE 0 +#define TBRE_MODE_AUDIO_PTS 1 +#define TBRE_MODE_AUDIO_PCR 2 +#define TBRE_MODE_PCR 3 +#define TBRE_MODE_DONE 4 + + #undef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #undef MAX @@ -393,8 +414,50 @@ typedef struct { off_t frame_pos; /* current ts packet position in input stream (bytes from beginning) */ + /* bitrate estimation */ + off_t tbre_bytes, tbre_lastpos; + int64_t tbre_time, tbre_lasttime; + unsigned int tbre_mode, tbre_pid; + } demux_ts_t; + +static void demux_ts_tbre_reset (demux_ts_t *this) { + if (this->tbre_time <= TBRE_TIME) { + this->tbre_pid = INVALID_PID; + this->tbre_mode = TBRE_MODE_PROBE; + } +} + +static void demux_ts_tbre_update (demux_ts_t *this, int mode, int64_t now) { + /* select best available timesource on the fly */ + if ((mode < this->tbre_mode) || (now <= 0)) + return; + + if (mode == this->tbre_mode) { + /* skip discontinuities */ + int64_t diff = now - this->tbre_lasttime; + if ((diff < 0 ? -diff : diff) < 220000) { + /* add this step */ + this->tbre_bytes += this->frame_pos - this->tbre_lastpos; + this->tbre_time += diff; + /* update bitrate */ + if (this->tbre_time > TBRE_MIN_TIME) + this->rate = this->tbre_bytes * 90000 / this->tbre_time; + /* stop analyzing */ + if (this->tbre_time > TBRE_TIME) + this->tbre_mode = TBRE_MODE_DONE; + } + } else { + /* upgrade timesource */ + this->tbre_mode = mode; + } + + /* remember where and when */ + this->tbre_lastpos = this->frame_pos; + this->tbre_lasttime = now; +} + /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) @@ -1065,8 +1128,14 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, m->input_normpos = (double)this->frame_pos * 65535.0 / length; } if (this->rate) { - m->input_time = this->frame_pos * 1000 / (this->rate * 50); + m->input_time = this->frame_pos * 1000 / this->rate; } + + /* rate estimation */ + if ((this->tbre_pid == INVALID_PID) && (this->audio_fifo == m->fifo)) + this->tbre_pid = m->pid; + if (m->pid == this->tbre_pid) + demux_ts_tbre_update (this, TBRE_MODE_AUDIO_PTS, m->pts); } } else if (!m->corrupted_pes) { /* no pus -- PES packet continuation */ @@ -1129,7 +1198,7 @@ static void demux_ts_get_lang_desc(demux_ts_t *this, char *dest, while (d < (data + length)) { - if (d[0] == 10 && d[1] >= 4) + if (d[0] == DESCRIPTOR_LANG && d[1] >= 4) { memcpy(dest, d + 2, 3); @@ -1154,7 +1223,7 @@ static void demux_ts_get_reg_desc(demux_ts_t *this, uint32_t *dest, while (d < (data + length)) { - if (d[0] == 5 && d[1] >= 4) + if (d[0] == DESCRIPTOR_REG_FORMAT && d[1] >= 4) { *dest = (d[2] << 24) | (d[3] << 16) | (d[4] << 8) | d[5]; @@ -1469,12 +1538,13 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num break; case ISO_13818_PES_PRIVATE: for (i = 5; i < coded_length; i += stream[i+1] + 2) { - if (((stream[i] == 0x6a) || (stream[i] == 0x7a)) && (this->audio_tracks_count < MAX_AUDIO_TRACKS)) { + if (((stream[i] == DESCRIPTOR_AC3) || (stream[i] == DESCRIPTOR_EAC3)) && + (this->audio_tracks_count < MAX_AUDIO_TRACKS)) { if (apid_check(this, pid) < 0) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif - if (stream[i] == 0x6a) + if (stream[i] == DESCRIPTOR_AC3) demux_ts_pes_new(this, this->media_num, pid, this->audio_fifo, STREAM_AUDIO_AC3); else @@ -1491,7 +1561,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num } } /* Teletext */ - else if (stream[i] == 0x56) + else if (stream[i] == DESCRIPTOR_TELETEXT) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT Teletext, pid: 0x%.4x type %2.2x\n", pid, stream[0]); @@ -1504,7 +1574,7 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num } /* DVBSUB */ - else if (stream[i] == 0x59) + else if (stream[i] == DESCRIPTOR_DVBSUB) { int pos; for (pos = i + 2; @@ -1644,6 +1714,8 @@ printf("Program Number is %i, looking for %i\n",program_number,this->program_num if ( this->stream->spu_channel>=0 && this->spu_langs_count>0 ) demux_ts_update_spu_channel( this ); + demux_ts_tbre_reset (this); + /* Inform UI of channels changes */ xine_event_t ui_event; ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; @@ -1983,7 +2055,11 @@ static void demux_ts_parse_packet (demux_ts_t*this) { if( adaptation_field_control & 0x2 ){ uint32_t adaptation_field_length = originalPkt[4]; if (adaptation_field_length > 0) { - demux_ts_adaptation_field_parse (originalPkt+5, adaptation_field_length); + int64_t pcr = demux_ts_adaptation_field_parse (originalPkt+5, adaptation_field_length); + if (pid == this->pcr_pid) + demux_ts_tbre_update (this, TBRE_MODE_PCR, pcr); + else if (pid == this->tbre_pid) + demux_ts_tbre_update (this, TBRE_MODE_AUDIO_PCR, pcr); } /* * Skip adaptation header. @@ -2213,9 +2289,7 @@ static int demux_ts_seek (demux_plugin_t *this_gen, if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) { if ((!start_pos) && (start_time)) { - start_pos = start_time; - start_pos *= this->rate; - start_pos *= 50; + start_pos = (int64_t)start_time * this->rate / 1000; } this->input->seek (this->input, start_pos, SEEK_SET); @@ -2246,6 +2320,8 @@ static int demux_ts_seek (demux_plugin_t *this_gen, } + demux_ts_tbre_reset (this); + return this->status; } @@ -2255,7 +2331,7 @@ static int demux_ts_get_stream_length (demux_plugin_t *this_gen) { if (this->rate) return (int)((int64_t) this->input->get_length (this->input) - * 1000 / (this->rate * 50)); + * 1000 / this->rate); else return 0; } @@ -2412,7 +2488,8 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->audio_tracks_count = 0; this->last_pmt_crc = 0; - this->rate = 16000; /* FIXME */ + this->rate = 1000000; /* byte/sec */ + this->tbre_pid = INVALID_PID; this->status = DEMUX_FINISHED; |