From: Andreas Ă–man Date: Wed, 6 Feb 2008 21:51:09 +0000 (+0000) Subject: make file_input work again X-Git-Tag: 2.12~1243 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=63d6786f83fd3abd8eb7ce062bb8530540332fbd;p=thirdparty%2Ftvheadend.git make file_input work again --- diff --git a/file_input.c b/file_input.c index 01e241da4..ce0f80531 100644 --- a/file_input.c +++ b/file_input.c @@ -51,8 +51,10 @@ typedef struct file_input { const char *fi_name; dtimer_t fi_timer; int64_t fi_refclock; - int64_t fi_last_dts; int64_t fi_dts_offset; + int64_t fi_last_dts; + + th_pkt_t *fi_next; } file_input_t; @@ -62,7 +64,7 @@ static void file_input_stop_feed(th_transport_t *t); static int file_input_start_feed(th_transport_t *t, unsigned int weight, int status); -static void fi_timer_callback(void *aux, int64_t now); +static void fi_deliver(void *aux, int64_t now); static void file_input_get_pkt(th_transport_t *t, file_input_t *fi, int64_t now); @@ -200,8 +202,9 @@ file_input_start_feed(th_transport_t *t, unsigned int weight, int status) file_input_reset(t, fi); fi->fi_refclock = getclock_hires(); + fi->fi_dts_offset = AV_NOPTS_VALUE; - dtimer_arm(&fi->fi_timer, fi_timer_callback, t, 1); + dtimer_arm(&fi->fi_timer, fi_deliver, t, 1); return 0; } @@ -215,90 +218,73 @@ file_input_get_pkt(th_transport_t *t, file_input_t *fi, int64_t now) AVPacket ffpkt; th_pkt_t *pkt; th_stream_t *st; - int i, frametype; - int64_t dts, pts, d = 1; - uint32_t sc; - - do { - i = av_read_frame(fi->fi_fctx, &ffpkt); - if(i < 0) { - file_input_reset(t, fi); - d = 20000; - fi->fi_dts_offset += fi->fi_last_dts; - break; + int i; + int64_t dts, pts, errcnt = 0, dt; + + again: + i = av_read_frame(fi->fi_fctx, &ffpkt); + if(i < 0) { + fi->fi_dts_offset += fi->fi_last_dts; + file_input_reset(t, fi); + fi->fi_next = NULL; + + if(errcnt == 0) { + errcnt++; + goto again; } - - LIST_FOREACH(st, &t->tht_streams, st_link) - if(st->st_pid == ffpkt.stream_index) - break; - - if(st == NULL) - continue; - - if(t->tht_dts_start == AV_NOPTS_VALUE) - t->tht_dts_start = ffpkt.dts; - - /* Figure frametype */ - - switch(st->st_type) { - case HTSTV_MPEG2VIDEO: - sc = ffpkt.data[0] << 24 | ffpkt.data[1] << 16 | ffpkt.data[2] << 8 | - ffpkt.data[3]; - if(sc == 0x100) { - frametype = (ffpkt.data[5] >> 3) & 7; - } else { - frametype = PKT_I_FRAME; - } - if(frametype == PKT_B_FRAME) - ffpkt.pts = ffpkt.dts; + syslog(LOG_ERR, "streamedfile: Unable to read from file \"%s\"", + fi->fi_name); + return; + } + LIST_FOREACH(st, &t->tht_streams, st_link) + if(st->st_pid == ffpkt.stream_index) break; - default: - frametype = 0; - break; - } - assert(ffpkt.dts != AV_NOPTS_VALUE); /* fixme */ + + if(st == NULL) + goto again; - pts = ffpkt.pts; - if(pts != AV_NOPTS_VALUE) - pts += fi->fi_dts_offset; + /* Update stream timebase */ + st->st_tb = fi->fi_fctx->streams[ffpkt.stream_index]->time_base; - 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; + assert(ffpkt.dts != AV_NOPTS_VALUE); /* fixme */ - avgstat_add(&st->st_rate, ffpkt.size, dispatch_clock); + if(fi->fi_dts_offset == AV_NOPTS_VALUE) + fi->fi_dts_offset = ffpkt.dts; - switch(st->st_type) { - case HTSTV_MPEG2VIDEO: - parse_compute_pts(t, st, pkt); - break; + dts = ffpkt.dts - fi->fi_dts_offset; + fi->fi_last_dts = dts; - default: - parser_compute_duration(t, st, pkt); - break; - } + pts = ffpkt.pts; + if(pts != AV_NOPTS_VALUE) + pts -= fi->fi_dts_offset; - 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); + pkt = pkt_alloc(ffpkt.data, ffpkt.size, pts, dts); + pkt->pkt_duration = 0; + pkt->pkt_stream = st; - av_free_packet(&ffpkt); + fi->fi_next = pkt; + + /* compute delivery time */ - d = dts - 1000000 - (now - fi->fi_refclock); - } while(d <= 0); - - dtimer_arm_hires(&fi->fi_timer, fi_timer_callback, t, now + d); + dt = av_rescale_q(dts, st->st_tb, AV_TIME_BASE_Q) + fi->fi_refclock; + dtimer_arm_hires(&fi->fi_timer, fi_deliver, t, dt); } static void -fi_timer_callback(void *aux, int64_t now) +fi_deliver(void *aux, int64_t now) { th_transport_t *t = aux; - file_input_get_pkt(t, t->tht_file_input, now); + file_input_t *fi = t->tht_file_input; + th_stream_t *st; + + if(fi->fi_next != NULL) { + st = fi->fi_next->pkt_stream; + fi->fi_next->pkt_stream = NULL; /* this must be null upon enqueue */ + parser_enqueue_packet(t, st, fi->fi_next); + fi->fi_next = NULL; + } + + file_input_get_pkt(t, fi, now); }