+static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
+ int64_t *ppos, int64_t pos_limit)
+{
+ MpegTSContext *ts = s->priv_data;
+ int64_t pos, timestamp;
+ uint8_t buf[TS_PACKET_SIZE];
+ int pcr_l, pid;
+ const int find_next= 1;
+ pos = ((*ppos + ts->raw_packet_size - 1) / ts->raw_packet_size) * ts->raw_packet_size;
+ if (find_next) {
+ for(;;) {
+ url_fseek(&s->pb, pos, SEEK_SET);
+ if (get_buffer(&s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
+ return AV_NOPTS_VALUE;
+ pid = ((buf[1] & 0x1f) << 8) | buf[2];
+ if (pid == ts->pcr_pid &&
+ parse_pcr(×tamp, &pcr_l, buf) == 0) {
+ break;
+ }
+ pos += ts->raw_packet_size;
+ }
+ } else {
+ for(;;) {
+ pos -= ts->raw_packet_size;
+ if (pos < 0)
+ return AV_NOPTS_VALUE;
+ url_fseek(&s->pb, pos, SEEK_SET);
+ if (get_buffer(&s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
+ return AV_NOPTS_VALUE;
+ pid = ((buf[1] & 0x1f) << 8) | buf[2];
+ if (pid == ts->pcr_pid &&
+ parse_pcr(×tamp, &pcr_l, buf) == 0) {
+ break;
+ }
+ }
+ }
+ *ppos = pos;
+
+ return timestamp;
+}
+
+static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
+ MpegTSContext *ts = s->priv_data;
+ uint8_t buf[TS_PACKET_SIZE];
+ int64_t pos;
+
+ if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
+ return -1;
+
+ pos= url_ftell(&s->pb);
+
+ for(;;) {
+ url_fseek(&s->pb, pos, SEEK_SET);
+ if (get_buffer(&s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
+ return -1;
+// pid = ((buf[1] & 0x1f) << 8) | buf[2];
+ if(buf[1] & 0x40) break;
+ pos += ts->raw_packet_size;
+ }
+ url_fseek(&s->pb, pos, SEEK_SET);
+
+ return 0;
+}
+
+/**************************************************************/
+/* parsing functions - called from other demuxers such as RTP */
+
+MpegTSContext *mpegts_parse_open(AVFormatContext *s)
+{
+ MpegTSContext *ts;
+
+ ts = av_mallocz(sizeof(MpegTSContext));
+ if (!ts)
+ return NULL;
+ /* no stream case, currently used by RTP */
+ ts->raw_packet_size = TS_PACKET_SIZE;
+ ts->stream = s;
+ ts->auto_guess = 1;
+ return ts;
+}
+
+/* return the consumed length if a packet was output, or -1 if no
+ packet is output */
+int mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
+ const uint8_t *buf, int len)
+{
+ int len1;
+
+ len1 = len;
+ ts->pkt = pkt;
+ ts->stop_parse = 0;
+ for(;;) {
+ if (ts->stop_parse)
+ break;
+ if (len < TS_PACKET_SIZE)
+ return -1;
+ if (buf[0] != 0x47) {
+ buf++;
+ len--;
+ } else {
+ handle_packet(ts, buf);
+ buf += TS_PACKET_SIZE;
+ len -= TS_PACKET_SIZE;
+ }
+ }
+ return len1 - len;
+}
+
+void mpegts_parse_close(MpegTSContext *ts)
+{
+ int i;
+
+ for(i=0;i<NB_PID_MAX;i++)
+ av_free(ts->pids[i]);
+ av_free(ts);
+}
+
+AVInputFormat mpegts_demuxer = {