diff -Naur MPlayer-20030724/libmpdemux/demuxer.h MPlayer-20030724-new/libmpdemux/demuxer.h --- MPlayer-20030724/libmpdemux/demuxer.h 2003-06-09 02:24:22.000000000 +0200 +++ MPlayer-20030724-new/libmpdemux/demuxer.h 2003-07-24 22:33:32.000000000 +0200 @@ -155,6 +155,21 @@ return dp; } + +inline static void resize_demux_packet(demux_packet_t* dp, int len) +{ + if(len){ + dp->buffer=realloc(dp->buffer,len+8); + memset(dp->buffer+len,0,8); + } else { + if(dp->buffer) free(dp->buffer); + dp->buffer=NULL; + } + dp->len=len; +} + + + inline static demux_packet_t* clone_demux_packet(demux_packet_t* pack){ demux_packet_t* dp=(demux_packet_t*)malloc(sizeof(demux_packet_t)); while(pack->master) pack=pack->master; // find the master diff -Naur MPlayer-20030724/libmpdemux/demux_ts.c MPlayer-20030724-new/libmpdemux/demux_ts.c --- MPlayer-20030724/libmpdemux/demux_ts.c 2003-06-19 20:20:15.000000000 +0200 +++ MPlayer-20030724-new/libmpdemux/demux_ts.c 2003-07-24 22:21:18.000000000 +0200 @@ -81,7 +81,20 @@ typedef struct { + demux_stream_t *ds; + demux_packet_t *pack; + int offset, buffer_size; +} av_fifo_t; + +typedef struct { MpegTSContext ts; + int is_synced; //synced to the beginning of priv->last_pid PES header + int buffer_size;//last dp buffer_size allocated + int last_afc; //bytes read from the last adaption field + int last_pid; // + int is_start; + int eof; + av_fifo_t fifo[2]; //0 for audio, 1 for video } ts_priv_t; @@ -219,6 +232,11 @@ unsigned char tmp[TS_FEC_PACKET_SIZE]; ts_priv_t *priv = (ts_priv_t*) demuxer->priv; + priv->is_synced = 0; + priv->last_afc = 0; + priv->last_pid = 8192; //invalid pid + priv->is_start = 0; + priv->eof = 0; mp_msg(MSGT_DEMUXER, MSGL_INFO, "PROBING UP TO %u\n", MAX_PROBE_SIZE); while(pos <= MAX_PROBE_SIZE) @@ -354,7 +372,7 @@ ts_detect_streams(demuxer, &at, &vt, &demuxer->audio->id, &demuxer->video->id); - mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer2, audio: %x(pid %d), video: %x(pid %d)...\n", at, demuxer->audio->id, vt, demuxer->video->id); + mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer, audio: %x(pid %d), video: %x(pid %d)...\n", at, demuxer->audio->id, vt, demuxer->video->id); if(vt) @@ -364,7 +382,7 @@ sh_video->format = vt; demuxer->video->sh = sh_video; - mp_msg(MSGT_DEMUXER,MSGL_INFO, "OPENED_SH_VIDEO, VD: %x\n"); + mp_msg(MSGT_DEMUXER,MSGL_INFO, "OPENED_SH_VIDEO\n"); } if(at) @@ -378,13 +396,32 @@ } - mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer..."); + mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer2\n"); demuxer->movi_start = 0; demuxer->movi_end = demuxer->stream->end_pos; - stream_seek(demuxer->stream, 0); //IF IT'S FROM A PIPE IT WILL FAIL, BUT WHO CARES? + stream_seek(demuxer->stream, 0); //IF IT'S FROM A PIPE IT WILL FAIL, BUT WHO CARES? + + priv->is_synced = 0; + priv->buffer_size = 65535; //initial value + + priv->last_afc = 0; + priv->last_pid = 8192; //invalid pid + priv->is_start = 0; + + for(i=0; i< 2; i++) + { + priv->fifo[i].pack = NULL; + priv->fifo[i].offset = 0; + } + priv->fifo[0].ds = demuxer->audio; + priv->fifo[1].ds = demuxer->video; + + priv->fifo[0].buffer_size = 1536; + priv->fifo[1].buffer_size = 32767; + priv->eof = 0; return demuxer; } @@ -411,11 +448,14 @@ { unsigned char *p; uint32_t header_len; - int64_t pts, escr, dts; + int64_t pts; uint32_t stream_id; - uint32_t pkt_len, es_rate; - //NEXT might be needed: + uint32_t pkt_len; + + //NEXT might be needed in the future: //uint8_t es_rate_flag, escr_flag, pts_flag; + //int64_t escr, dts; + //uint32_t es_rate; //Here we are always at the start of a PES packet mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2(%X, %d): \n", buf, packet_len); @@ -512,7 +552,7 @@ if (stream_id == 0xbd) { /* hack : ac3 track */ - int track, spu_id; + int track; //, spu_id; mp_msg(MSGT_DEMUX, MSGL_DBG3, "pes_parse2: audio buf = %02X %02X %02X %02X %02X %02X %02X %02X, 80: %d\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[0] & 0x80); @@ -642,7 +682,21 @@ } +void ts_dump_streams(ts_priv_t *priv) +{ + int i; + + for(i = 0; i < 2; i++) + { + if((priv->fifo[i].pack != NULL) && (priv->fifo[i].offset != 0)) + { + resize_demux_packet(priv->fifo[i].pack, priv->fifo[i].offset); + ds_add_packet(priv->fifo[i].ds, priv->fifo[i].pack); + } + } + priv->eof = 1; +} @@ -653,29 +707,53 @@ ES_stream_t *tss; uint8_t done = 0; int buf_size, is_start; - int len, pid, last_pid, cc, cc_ok, afc, _read; + int len, pid, cc, cc_ok, afc, _read; ts_priv_t * priv = (ts_priv_t*) demuxer->priv; stream_t *stream = demuxer->stream; char *p, tmp[TS_FEC_PACKET_SIZE]; - demux_stream_t *ds; - demux_packet_t *dp; + demux_stream_t *ds = NULL; + demux_packet_t **dp = NULL; + int *dp_offset = 0, *buffer_size = 0; - while(! done) //while pid=last_pid add_to_buffer + while(! done) //while pid==priv->last_pid add_to_buffer { - if(! ts_sync(stream)) + if(stream_eof(stream)) { - mp_msg(MSGT_DEMUX, MSGL_V, "TS_PARSE: COULDN'T SYNC\n"); - return 0; + if(! priv->eof) + { + ts_dump_streams(priv); + return -1; + } + else + return 0; } - len = stream_read(stream, &packet[1], 3); - if (len != 3) - return 0; + + if(! priv->is_synced) + { + if(! ts_sync(stream)) + { + mp_msg(MSGT_DEMUX, MSGL_V, "TS_PARSE: COULDN'T SYNC\n"); + return 0; + } + + len = stream_read(stream, &packet[1], 3); + if (len != 3) + return 0; + } _read = 4; - is_start = packet[1] & 0x40; - pid = ((packet[1] & 0x1f) << 8) | packet[2]; + if(! priv->is_synced) + { + is_start = packet[1] & 0x40; + pid = ((packet[1] & 0x1f) << 8) | packet[2]; + } + else + { + is_start = priv->is_start; + pid = priv->last_pid; + } tss = priv->ts.pids[pid]; //an ES stream if(tss == NULL) @@ -689,11 +767,12 @@ tss->type = UNKNOWN; tss->payload_size = 0; priv->ts.pids[pid] = tss; - mp_msg(MSGT_DEMUX, MSGL_V, "new TS pid=%u\n", pid); + mp_msg(MSGT_DEMUX, MSGL_INFO, "\nNew TS pid=%u\n", pid); } if((pid < 16) || (pid == 8191)) //invalid pid continue; + cc = (packet[3] & 0xf); cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc)); if(! cc_ok) @@ -702,49 +781,118 @@ } tss->last_cc = cc; - /* skip adaptation field */ - afc = (packet[3] >> 4) & 3; - if (afc == 0) /* reserved value */ - continue; - if (afc == 2) /* adaptation field only */ - continue; - if (afc == 3) + + if(! priv->is_synced) { - int c; - stream_read(stream, &packet[_read], 1); - c = packet[_read]; - _read++; - - c = min(c, priv->ts.packet_size - _read); - stream_read(stream, &packet[_read], c); - _read += c; + priv->last_afc = 0; + /* skip adaptation field */ + afc = (packet[3] >> 4) & 3; + if (afc == 0) /* reserved value */ + continue; + if (afc == 2) /* adaptation field only */ + continue; + if (afc == 3) + { + int c; + stream_read(stream, &packet[_read], 1); + c = packet[_read]; + _read++; - if(_read == priv->ts.packet_size) - continue; + c = min(c, priv->ts.packet_size - _read); + stream_read(stream, &packet[_read], c); + _read += c; + + priv->last_afc = c + 1; + mp_msg(MSGT_DEMUX, MSGL_DBG2, "AFC: %d\n", priv->last_afc); + + if(_read == priv->ts.packet_size) + continue; + } + } + else + { + _read += priv->last_afc; + priv->last_afc = 0; } // PES CONTENT STARTS HERE buf_size = priv->ts.packet_size - _read; + if(! probe) { + //mp_msg(MSGT_DEMUX, MSGL_V, "demux_VID: %d, demux_AID: %d, TSSID: %d\n", demuxer->video->id, demuxer->audio->id, tss->pid); if((tss->type == VIDEO_MPEG2) && (demuxer->video->id == tss->pid)) + { ds = demuxer->video; + + dp = &priv->fifo[1].pack; + dp_offset = &priv->fifo[1].offset; + buffer_size = &priv->fifo[1].buffer_size; + } else if(((tss->type == AUDIO_MP2) || (tss->type == AUDIO_A52) || (tss->type == AUDIO_LPCM_BE)) && (demuxer->audio->id == tss->pid)) + { ds = demuxer->audio; + + dp = &priv->fifo[0].pack; + dp_offset = &priv->fifo[0].offset; + buffer_size = &priv->fifo[0].buffer_size; + } else { - stream_read(stream, tmp, buf_size); + //mp_msg(MSGT_DEMUX, MSGL_V, "SKIPPING %d bytes\n", buf_size); + stream_skip(stream, buf_size); _read += buf_size; continue; } + + //IS IT TIME TO QUEUE DATA? + if(is_start && (*dp != NULL) && (*dp_offset > 0)) + { + int ret = *dp_offset; + resize_demux_packet(*dp, ret); //shrinked to the right size + ds_add_packet(ds, *dp); + + mp_msg(MSGT_DEMUX, MSGL_V, "ADDED %d bytes to %s fifo\n", ret, (ds == demuxer->audio ? "audio" : "video")); + + priv->last_pid = pid; + priv->is_synced = 1; + priv->is_start = is_start; + + *dp = NULL; + *dp_offset = 0; + + return -ret; + } + + priv->last_pid = pid; + + if(*dp == NULL) + { + *dp = new_demux_packet(*buffer_size); //es->size + *dp_offset = 0; + if(! *dp) + { + fprintf(stderr, "fill_buffer, NEW_ADD_PACKET(%d)FAILED\n", *buffer_size); + continue; + } + mp_msg(MSGT_DEMUX, MSGL_DBG2, "CREATED DP(%d)\n", *buffer_size); + } + + mp_msg(MSGT_DEMUX, MSGL_DBG2, "NOW PACKET_SIZE = %d, DP_OFFSET = %d\n", *buffer_size, *dp_offset); } + priv->is_synced = 0; + if(is_start) { + mp_msg(MSGT_DEMUX, MSGL_V, "IS_START\n"); + + //priv->is_synced = 0; + p = &packet[_read]; stream_read(stream, p, buf_size); _read += buf_size; @@ -772,27 +920,28 @@ tss->payload_size = es->payload_size; - mp_msg(MSGT_DEMUX, MSGL_V, "ts_parse, NOW tss->PSIZE=%u\n", tss->payload_size); + mp_msg(MSGT_DEMUX, MSGL_DBG2, "ts_parse, NOW tss->PSIZE=%u\n", tss->payload_size); if(probe) return es->size; else { - dp = new_demux_packet(es->size); - if(! dp || ! dp->buffer) + if(*dp_offset + es->size > *buffer_size) { - fprintf(stderr, "fill_buffer, NEW_ADD_PACKET(%d)FAILED\n", es->size); - continue; + *buffer_size = *dp_offset + es->size + TS_FEC_PACKET_SIZE; + resize_demux_packet(*dp, *buffer_size); + //we'll skip at least one RESIZE() in the next iteration of ts_parse() + mp_msg(MSGT_DEMUX, MSGL_DBG2, "RESIZE DP TO %d\n", *buffer_size); } + memcpy(&((*dp)->buffer[*dp_offset]), es->start, es->size); + *dp_offset += es->size; + (*dp)->flags = 0; + (*dp)->pts = es->pts; + (*dp)->pos = stream_tell(demuxer->stream); + mp_msg(MSGT_DEMUX, MSGL_DBG2, "INIT PACKET, TYPE=%x, PTS: %f\n", es->type, es->pts); - memcpy(dp->buffer, es->start, es->size); - dp->flags = 0; - dp->pts = es->pts; - dp->pos = stream_tell(demuxer->stream); - ds_add_packet(ds, dp); - - return -es->size; + continue; } } } @@ -802,7 +951,7 @@ if(tss->type == UNKNOWN) { - stream_read(stream, tmp, buf_size); + stream_skip(stream, buf_size); continue; } @@ -824,22 +973,30 @@ sz = es->size = buf_size; else { - stream_read(stream, tmp, buf_size); + stream_skip(stream, buf_size); continue; } } - if(! probe) { - ds_read_packet(ds, stream, sz, tss->last_pts, stream_tell(stream), 0); - if(buf_size - sz) - stream_read(stream, tmp, buf_size - sz); + if(*dp_offset + sz > *buffer_size) + { + *buffer_size = *dp_offset + sz + TS_FEC_PACKET_SIZE; + resize_demux_packet(*dp, *buffer_size); + //we'll skip at least one RESIZE() in the next iteration of ts_parse() + mp_msg(MSGT_DEMUX, MSGL_DBG2, "RESIZE DP TO %d\n", *buffer_size); + } - mp_msg(MSGT_DEMUX, MSGL_V, "DOPO DS_READ_PACKET pid %d, size %d DS=%p\n", tss->pid, sz, ds); - return -sz; + stream_read(stream, &((*dp)->buffer[*dp_offset]), sz); + *dp_offset += sz; + + if(buf_size - sz) + stream_skip(stream, buf_size - sz); + + continue; } else { @@ -860,6 +1017,7 @@ } + int demux_ts_fill_buffer(demuxer_t * demuxer) { ES_stream_t es; @@ -875,7 +1033,6 @@ { int total_bitrate=0; off_t dest_offset; - ts_priv_t * priv = demuxer->priv; int a_bps, v_bps; demux_stream_t *d_audio=demuxer->audio; demux_stream_t *d_video=demuxer->video; @@ -895,13 +1052,13 @@ if(demuxer->audio->id != -2) { - a_bps = ((sh_audio_t *)demuxer->audio->sh)->i_bps; + a_bps = sh_audio->i_bps; total_bitrate += a_bps; } if(demuxer->video->id != -2) { - v_bps = ((sh_video_t *)demuxer->video->sh)->i_bps; + v_bps = sh_video->i_bps; total_bitrate += v_bps; }