diff options
Diffstat (limited to 'src/video.c')
-rw-r--r-- | src/video.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/src/video.c b/src/video.c index 595f472..43f7c9d 100644 --- a/src/video.c +++ b/src/video.c @@ -99,11 +99,13 @@ struct vtx { struct list filtl; /**< Filters in encoding order */ char device[64]; /**< Source device name */ int muted_frames; /**< # of muted frames sent */ - uint32_t ts_tx; /**< Outgoing RTP timestamp */ + uint32_t ts_offset; /**< Random timestamp offset */ bool picup; /**< Send picture update */ bool muted; /**< Muted flag */ int frames; /**< Number of frames sent */ int efps; /**< Estimated frame-rate */ + uint32_t ts_min; + uint32_t ts_max; }; @@ -140,6 +142,8 @@ struct vrx { int efps; /**< Estimated frame-rate */ unsigned n_intra; /**< Intra-frames decoded */ unsigned n_picup; /**< Picture updates sent */ + uint32_t ts_min; + uint32_t ts_max; }; @@ -337,15 +341,27 @@ static int get_fps(const struct video *v) } -static int packet_handler(bool marker, const uint8_t *hdr, size_t hdr_len, - const uint8_t *pld, size_t pld_len, void *arg) +static int packet_handler(bool marker, uint32_t ts, + const uint8_t *hdr, size_t hdr_len, + const uint8_t *pld, size_t pld_len, + void *arg) { struct vtx *vtx = arg; struct stream *strm = vtx->video->strm; struct vidqent *qent; + uint32_t rtp_ts; int err; - err = vidqent_alloc(&qent, marker, strm->pt_enc, vtx->ts_tx, + /* NOTE: does not handle timestamp wrap around */ + if (ts < vtx->ts_min) + vtx->ts_min = ts; + if (ts > vtx->ts_max) + vtx->ts_max = ts; + + /* add random timestamp offset */ + rtp_ts = vtx->ts_offset + ts; + + err = vidqent_alloc(&qent, marker, strm->pt_enc, rtp_ts, hdr, hdr_len, pld, pld_len); if (err) return err; @@ -424,7 +440,6 @@ static void encode_rtp_send(struct vtx *vtx, struct vidframe *frame) if (err) return; - vtx->ts_tx += (SRATE/vtx->vsrc_prm.fps); vtx->picup = false; } @@ -478,12 +493,16 @@ static int vtx_alloc(struct vtx *vtx, struct video *video) tmr_init(&vtx->tmr_rtp); vtx->video = video; - vtx->ts_tx = 160; + + /* The initial value of the timestamp SHOULD be random */ + vtx->ts_offset = rand_u16(); str_ncpy(vtx->device, video->cfg.src_dev, sizeof(vtx->device)); tmr_start(&vtx->tmr_rtp, 1, rtp_tmr_handler, vtx); + vtx->ts_min = ~0; + return err; } @@ -502,6 +521,8 @@ static int vrx_alloc(struct vrx *vrx, struct video *video) str_ncpy(vrx->device, video->cfg.disp_dev, sizeof(vrx->device)); + vrx->ts_min = ~0; + return err; } @@ -564,6 +585,13 @@ static int video_stream_decode(struct vrx *vrx, const struct rtp_header *hdr, goto out; } + /* todo: check if RTP timestamp wraps */ + + if (hdr->ts < vrx->ts_min) + vrx->ts_min = hdr->ts; + if (hdr->ts > vrx->ts_max) + vrx->ts_max = hdr->ts; + frame->data[0] = NULL; err = vrx->vc->dech(vrx->dec, frame, &intra, hdr->m, hdr->seq, mb); if (err) { @@ -1295,11 +1323,16 @@ int video_debug(struct re_printf *pf, const struct video *v) vtx->vsrc_size.w, vtx->vsrc_size.h, vtx->vsrc_prm.fps); err |= re_hprintf(pf, " skipc=%u\n", vtx->skipc); + err |= re_hprintf(pf, " time = %.3f sec\n", + video_calc_seconds(vtx->ts_max - vtx->ts_min)); err |= re_hprintf(pf, " rx: %u x %u\n", vrx->size.w, vrx->size.h); err |= re_hprintf(pf, " pt=%d\n", vrx->pt_rx); + err |= re_hprintf(pf, " n_intra=%u, n_picup=%u\n", vrx->n_intra, vrx->n_picup); + err |= re_hprintf(pf, " time = %.3f sec\n", + video_calc_seconds(vrx->ts_max - vrx->ts_min)); if (!list_isempty(baresip_vidfiltl())) { err |= vtx_print_pipeline(pf, vtx); @@ -1375,3 +1408,14 @@ uint32_t video_calc_rtp_timestamp(int64_t pts, unsigned fps) return (uint32_t)rtp_ts; } + + +double video_calc_seconds(uint32_t rtp_ts) +{ + double timestamp; + + /* convert from RTP clockrate to seconds */ + timestamp = (double)rtp_ts / (double)SRATE; + + return timestamp; +} |