From 5ab0d84115d6aabd2a83f53f7134017ca405a8b0 Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Tue, 2 Aug 2011 20:41:20 +0300 Subject: demux_ts: Added defines for PMT stream info descriptors --- src/demuxers/demux_ts.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index f22526054..bef1780f7 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -205,6 +205,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 */ @@ -1142,7 +1152,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); @@ -1167,7 +1177,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]; @@ -1482,12 +1492,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 @@ -1504,7 +1515,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]); @@ -1517,7 +1528,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; -- cgit v1.2.3 From a7e71f3853bb31291052be74eba0334ee0d92078 Mon Sep 17 00:00:00 2001 From: Jose Alberto Reguero Date: Mon, 17 Oct 2011 11:06:50 +0300 Subject: Added E-AC-3 to demux_mpeg_pes --- src/demuxers/demux_mpeg_pes.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/demuxers/demux_mpeg_pes.c b/src/demuxers/demux_mpeg_pes.c index b2d0f2fa9..9ef7221f0 100644 --- a/src/demuxers/demux_mpeg_pes.c +++ b/src/demuxers/demux_mpeg_pes.c @@ -944,6 +944,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; -- cgit v1.2.3 From 75cf9bf734dc78164b5f257559a78a9e71d18e33 Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Mon, 17 Oct 2011 12:42:28 +0300 Subject: demux_ts: added rate estimation --- src/demuxers/demux_ts.c | 76 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index bef1780f7..5db87600b 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -257,6 +257,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 @@ -382,6 +393,11 @@ 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; typedef struct { @@ -394,6 +410,41 @@ typedef struct { config_values_t *config; } demux_ts_class_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; +} static void demux_ts_build_crc32_table(demux_ts_t*this) { uint32_t i, j, k; @@ -1090,6 +1141,12 @@ static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts, if (this->rate) { m->input_time = this->frame_pos * 1000 / (this->rate * 50); } + + /* 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 */ @@ -1668,6 +1725,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; @@ -2007,7 +2066,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. @@ -2239,9 +2302,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); @@ -2272,6 +2333,8 @@ static int demux_ts_seek (demux_plugin_t *this_gen, } + demux_ts_tbre_reset (this); + return this->status; } @@ -2281,7 +2344,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; } @@ -2467,7 +2530,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; -- cgit v1.2.3 From 0b6b1aa65cb5b072540b2a35d5e5237c528e814b Mon Sep 17 00:00:00 2001 From: Petri Hintukainen Date: Mon, 17 Oct 2011 12:52:05 +0300 Subject: Fixed input time calculation (was lost when splitting patch) --- src/demuxers/demux_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c index 5db87600b..65007fda4 100644 --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -1139,7 +1139,7 @@ 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 */ -- cgit v1.2.3