Make file input slightly better (correctly compute duration and PTS)

This commit is contained in:
Andreas Öman 2008-02-05 11:27:36 +00:00
parent c36cfd3d69
commit c891a87e87
3 changed files with 52 additions and 20 deletions

View file

@ -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);

View file

@ -24,6 +24,7 @@
#include <string.h>
#include <errno.h>
#include <ffmpeg/avcodec.h>
#include <assert.h>
#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,

View file

@ -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 */