From c891a87e87c6d7eeb86c053f1267e7523aa90eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Tue, 5 Feb 2008 11:27:36 +0000 Subject: [PATCH] Make file input slightly better (correctly compute duration and PTS) --- file_input.c | 36 ++++++++++++++++++++++++------------ parsers.c | 34 ++++++++++++++++++++++++++-------- parsers.h | 2 ++ 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/file_input.c b/file_input.c index db211e8e..a4c531d8 100644 --- a/file_input.c +++ b/file_input.c @@ -216,7 +216,7 @@ file_input_get_pkt(th_transport_t *t, file_input_t *fi, int64_t now) th_pkt_t *pkt; th_stream_t *st; int i, frametype; - int64_t pts, d = 1; + int64_t dts, pts, d = 1; uint32_t sc; do { @@ -225,6 +225,7 @@ file_input_get_pkt(th_transport_t *t, file_input_t *fi, int64_t now) file_input_reset(t, fi); d = 20000; fi->fi_dts_offset += fi->fi_last_dts; + printf("File wrap\n"); break; } @@ -239,11 +240,7 @@ file_input_get_pkt(th_transport_t *t, file_input_t *fi, int64_t now) if(t->tht_dts_start == AV_NOPTS_VALUE) t->tht_dts_start = ffpkt.dts; - pts = av_rescale_q(ffpkt.pts, - fi->fi_fctx->streams[ffpkt.stream_index]->time_base, - AV_TIME_BASE_Q); - - /* Figure frametype */ + /* Figure frametype */ switch(st->st_type) { case HTSTV_MPEG2VIDEO: @@ -254,32 +251,47 @@ file_input_get_pkt(th_transport_t *t, file_input_t *fi, int64_t now) } else { frametype = PKT_I_FRAME; } + if(frametype == PKT_B_FRAME) + ffpkt.pts = ffpkt.dts; + break; default: frametype = 0; break; } + assert(ffpkt.dts != AV_NOPTS_VALUE); /* fixme */ - pkt = pkt_alloc(ffpkt.data, ffpkt.size, - ffpkt.pts + fi->fi_dts_offset, + pts = ffpkt.pts; + if(pts != AV_NOPTS_VALUE) + pts += fi->fi_dts_offset; + + pkt = pkt_alloc(ffpkt.data, ffpkt.size, pts, ffpkt.dts + fi->fi_dts_offset); pkt->pkt_frametype = frametype; - + pkt->pkt_duration = 0; pkt->pkt_stream = st; st->st_tb = fi->fi_fctx->streams[ffpkt.stream_index]->time_base; fi->fi_last_dts = ffpkt.dts; avgstat_add(&st->st_rate, ffpkt.size, dispatch_clock); - parser_compute_duration(t, st, pkt); + switch(st->st_type) { + case HTSTV_MPEG2VIDEO: + parse_compute_pts(t, st, pkt); + break; - pts = av_rescale_q(ffpkt.pts - t->tht_dts_start, + default: + parser_compute_duration(t, st, pkt); + break; + } + + dts = av_rescale_q(ffpkt.dts - t->tht_dts_start + fi->fi_dts_offset, fi->fi_fctx->streams[ffpkt.stream_index]->time_base, AV_TIME_BASE_Q); av_free_packet(&ffpkt); - d = pts - 1000000 - (now - fi->fi_refclock); + d = dts - 1000000 - (now - fi->fi_refclock); } while(d <= 0); dtimer_arm_hires(&fi->fi_timer, fi_timer_callback, t, now + d); diff --git a/parsers.c b/parsers.c index 7e80549b..399f035a 100644 --- a/parsers.c +++ b/parsers.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "tvhead.h" #include "parsers.h" @@ -88,8 +89,7 @@ static void parse_mpegaudio(th_transport_t *t, th_stream_t *st, uint8_t *data, static void parse_ac3(th_transport_t *t, th_stream_t *st, uint8_t *data, int len); -static void parse_compute_pts(th_transport_t *t, th_stream_t *st, - th_pkt_t *pkt); +void parse_compute_pts(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); static void parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); @@ -676,20 +676,24 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len, * We do this by placing packets on a queue and wait for next I/P * frame to appear */ -static void +void parse_compute_pts(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt) { th_pkt_t *p; if(pkt->pkt_pts != AV_NOPTS_VALUE && st->st_ptsq_len == 0) { /* PTS known and no other packets in queue, deliver at once */ - parser_deliver(t, st, pkt); + + if(pkt->pkt_duration == 0) + parser_compute_duration(t, st, pkt); + else + parser_deliver(t, st, pkt); return; } TAILQ_INSERT_TAIL(&st->st_ptsq, pkt, pkt_queue_link); st->st_ptsq_len++; - + while((pkt = TAILQ_FIRST(&st->st_ptsq)) != NULL) { switch(pkt->pkt_frametype) { case PKT_B_FRAME: @@ -716,7 +720,11 @@ parse_compute_pts(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt) TAILQ_REMOVE(&st->st_ptsq, pkt, pkt_queue_link); st->st_ptsq_len--; - parser_deliver(t, st, pkt); + + if(pkt->pkt_duration == 0) + parser_compute_duration(t, st, pkt); + else + parser_deliver(t, st, pkt); } } @@ -738,6 +746,13 @@ parser_compute_duration(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt) d = next->pkt_dts - pkt->pkt_dts; TAILQ_REMOVE(&st->st_durationq, pkt, pkt_queue_link); + if(d < 10) { + printf("%s: duration is %lld, pkt dropped\n", + htstvstreamtype2txt(st->st_type), d); + pkt_deref(pkt); + return; + } + pkt->pkt_duration = d; parser_deliver(t, st, pkt); @@ -754,6 +769,10 @@ parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt) th_muxer_t *tm; int64_t dts, pts, ptsoff; + assert(pkt->pkt_dts != AV_NOPTS_VALUE); + assert(pkt->pkt_pts != AV_NOPTS_VALUE); + assert(pkt->pkt_duration > 10); + if(t->tht_dts_start == AV_NOPTS_VALUE) { pkt_deref(pkt); return; @@ -789,8 +808,7 @@ parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt) pkt->pkt_pts =av_rescale_q(pts, st->st_tb, AV_TIME_BASE_Q); pkt->pkt_duration=av_rescale_q(pkt->pkt_duration, st->st_tb, AV_TIME_BASE_Q); #if 0 - printf("%20lld: %-12s %d %10lld %10lld %d\n", - getclock_hires(), + printf("%-12s %d %10lld %10lld %d\n", htstvstreamtype2txt(st->st_type), pkt->pkt_frametype, pkt->pkt_dts, diff --git a/parsers.h b/parsers.h index fcbffe41..d9a73792 100644 --- a/parsers.h +++ b/parsers.h @@ -25,4 +25,6 @@ void parse_raw_mpeg(th_transport_t *t, th_stream_t *st, uint8_t *data, void parser_compute_duration(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); +void parse_compute_pts(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); + #endif /* PARSERS_H */