Make file input slightly better (correctly compute duration and PTS)
This commit is contained in:
parent
c36cfd3d69
commit
c891a87e87
3 changed files with 52 additions and 20 deletions
36
file_input.c
36
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);
|
||||
|
|
34
parsers.c
34
parsers.c
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue