summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfred E. Heggestad <alfred.heggestad@gmail.com>2017-07-29 15:13:00 +0200
committerGitHub <noreply@github.com>2017-07-29 15:13:00 +0200
commit6c56980cbeecaaeac0367ad9aa48eaa84fd8314b (patch)
tree062e0fa2e0ecf1a3072386972a87886fa38fe3ec
parent5d297b1594765b681466b13257af0a59bf765ff8 (diff)
Video timestamp (#286)
* add timestamp to video encoder/decoder * update vp8 vp9 * random offset * revert decoder timestamp * cleanup * gst_video1: add timestamp * change timestamp to RTP-timestamp * update modules * timestamp things * save rtp timestamp * packet_handler: align params same as RTP header * align parameters same way like RTP-header * avcodec: calc ts for old FFmpeg versions * cleanup * fix gst avcodec: use correct AVPacket * minor cleanup
-rw-r--r--include/baresip.h15
-rw-r--r--modules/avcodec/encode.c31
-rw-r--r--modules/gst_video1/encode.c16
-rw-r--r--modules/h265/encode.c16
-rw-r--r--modules/v4l2_codec/v4l2_codec.c14
-rw-r--r--modules/vidloop/vidloop.c6
-rw-r--r--modules/vp8/encode.c12
-rw-r--r--modules/vp9/encode.c21
-rw-r--r--src/h264.c19
-rw-r--r--src/video.c56
-rw-r--r--test/mock/mock_vidcodec.c8
11 files changed, 163 insertions, 51 deletions
diff --git a/include/baresip.h b/include/baresip.h
index d59d23f..d75d8fb 100644
--- a/include/baresip.h
+++ b/include/baresip.h
@@ -875,8 +875,10 @@ struct videnc_state;
struct viddec_state;
struct vidcodec;
-typedef int (videnc_packet_h)(bool marker, const uint8_t *hdr, size_t hdr_len,
- const uint8_t *pld, size_t pld_len, void *arg);
+typedef int (videnc_packet_h)(bool marker, uint32_t rtp_ts,
+ const uint8_t *hdr, size_t hdr_len,
+ const uint8_t *pld, size_t pld_len,
+ void *arg);
typedef int (videnc_update_h)(struct videnc_state **vesp,
const struct vidcodec *vc,
@@ -991,6 +993,7 @@ void video_set_devicename(struct video *v, const char *src, const char *disp);
void video_encoder_cycle(struct video *video);
int video_debug(struct re_printf *pf, const struct video *v);
uint32_t video_calc_rtp_timestamp(int64_t pts, unsigned fps);
+double video_calc_seconds(uint32_t rtp_ts);
/*
@@ -1113,11 +1116,11 @@ int h264_fu_hdr_decode(struct h264_fu *fu, struct mbuf *mb);
const uint8_t *h264_find_startcode(const uint8_t *p, const uint8_t *end);
-int h264_packetize(const uint8_t *buf, size_t len, size_t pktsize,
- videnc_packet_h *pkth, void *arg);
+int h264_packetize(uint32_t rtp_ts, const uint8_t *buf, size_t len,
+ size_t pktsize, videnc_packet_h *pkth, void *arg);
int h264_nal_send(bool first, bool last,
- bool marker, uint32_t ihdr, const uint8_t *buf,
- size_t size, size_t maxsz,
+ bool marker, uint32_t ihdr, uint32_t rtp_ts,
+ const uint8_t *buf, size_t size, size_t maxsz,
videnc_packet_h *pkth, void *arg);
static inline bool h264_is_keyframe(int type)
{
diff --git a/modules/avcodec/encode.c b/modules/avcodec/encode.c
index 9aeea34..11d30a0 100644
--- a/modules/avcodec/encode.c
+++ b/modules/avcodec/encode.c
@@ -341,7 +341,7 @@ static void param_handler(const struct pl *name, const struct pl *val,
}
-static int general_packetize(struct mbuf *mb, size_t pktsize,
+static int general_packetize(uint32_t rtp_ts, struct mbuf *mb, size_t pktsize,
videnc_packet_h *pkth, void *arg)
{
int err = 0;
@@ -355,7 +355,8 @@ static int general_packetize(struct mbuf *mb, size_t pktsize,
sz = last ? left : pktsize;
- err = pkth(last, NULL, 0, mbuf_buf(mb), sz, arg);
+ err = pkth(last, rtp_ts, NULL, 0, mbuf_buf(mb), sz,
+ arg);
mbuf_advance(mb, sz);
}
@@ -364,7 +365,8 @@ static int general_packetize(struct mbuf *mb, size_t pktsize,
}
-static int h263_packetize(struct videnc_state *st, struct mbuf *mb,
+static int h263_packetize(struct videnc_state *st,
+ uint32_t rtp_ts, struct mbuf *mb,
videnc_packet_h *pkth, void *arg)
{
struct h263_strm h263_strm;
@@ -399,7 +401,7 @@ static int h263_packetize(struct videnc_state *st, struct mbuf *mb,
st->mb_frag->pos = 0;
- err = pkth(last, NULL, 0, mbuf_buf(st->mb_frag),
+ err = pkth(last, rtp_ts, NULL, 0, mbuf_buf(st->mb_frag),
mbuf_get_left(st->mb_frag), arg);
mbuf_advance(mb, sz);
@@ -562,6 +564,7 @@ int encode_x264(struct videnc_state *st, bool update,
int i_nal;
int i, err, ret;
int csp, pln;
+ uint32_t ts;
if (!st || !frame)
return EINVAL;
@@ -618,6 +621,8 @@ int encode_x264(struct videnc_state *st, bool update,
if (i_nal == 0)
return 0;
+ ts = video_calc_rtp_timestamp(pic_out.i_pts, st->encprm.fps);
+
err = 0;
for (i=0; i<i_nal && !err; i++) {
const uint8_t hdr = nal[i].i_ref_idc<<5 | nal[i].i_type<<0;
@@ -639,10 +644,11 @@ int encode_x264(struct videnc_state *st, bool update,
if (nal[i].i_type == H264_NAL_SEI)
continue;
- err = h264_nal_send(true, true, (i+1)==i_nal, hdr,
+ err = h264_nal_send(true, true, (i+1)==i_nal, hdr, ts,
nal[i].p_payload + offset,
nal[i].i_payload - offset,
- st->encprm.pktsize, st->pkth, st->arg);
+ st->encprm.pktsize,
+ st->pkth, st->arg);
}
return err;
@@ -654,6 +660,7 @@ int encode(struct videnc_state *st, bool update, const struct vidframe *frame)
{
int i, err, ret;
int pix_fmt;
+ uint32_t ts;
if (!st || !frame)
return EINVAL;
@@ -722,6 +729,8 @@ int encode(struct videnc_state *st, bool update, const struct vidframe *frame)
return 0;
}
+ ts = video_calc_rtp_timestamp(pkt->dts, st->encprm.fps);
+
err = mbuf_write_mem(st->mb, pkt->data, pkt->size);
st->mb->pos = 0;
@@ -749,6 +758,8 @@ int encode(struct videnc_state *st, bool update, const struct vidframe *frame)
mbuf_set_end(st->mb, avpkt.size);
+ ts = video_calc_rtp_timestamp(avpkt.dts, st->encprm.fps);
+
} while (0);
#else
ret = avcodec_encode_video(st->ctx, st->mb->buf,
@@ -764,22 +775,24 @@ int encode(struct videnc_state *st, bool update, const struct vidframe *frame)
}
mbuf_set_end(st->mb, ret);
+
+ ts = video_calc_rtp_timestamp(st->pict->pts, st->encprm.fps);
#endif
switch (st->codec_id) {
case AV_CODEC_ID_H263:
- err = h263_packetize(st, st->mb, st->pkth, st->arg);
+ err = h263_packetize(st, ts, st->mb, st->pkth, st->arg);
break;
case AV_CODEC_ID_H264:
- err = h264_packetize(st->mb->buf, st->mb->end,
+ err = h264_packetize(ts, st->mb->buf, st->mb->end,
st->encprm.pktsize,
st->pkth, st->arg);
break;
case AV_CODEC_ID_MPEG4:
- err = general_packetize(st->mb, st->encprm.pktsize,
+ err = general_packetize(ts, st->mb, st->encprm.pktsize,
st->pkth, st->arg);
break;
diff --git a/modules/gst_video1/encode.c b/modules/gst_video1/encode.c
index b563d07..d0a3d44 100644
--- a/modules/gst_video1/encode.c
+++ b/modules/gst_video1/encode.c
@@ -122,13 +122,27 @@ static GstFlowReturn appsink_new_sample_cb(GstAppSink *sink,
sample = gst_app_sink_pull_sample(sink);
if (sample) {
+ GstClockTime ts;
+ uint32_t rtp_ts;
+
buffer = gst_sample_get_buffer(sample);
gst_buffer_map( buffer, &info, (GstMapFlags)(GST_MAP_READ) );
data = info.data;
size = info.size;
- h264_packetize(data, size, st->encoder.pktsize,
+ ts = GST_BUFFER_DTS_OR_PTS(buffer);
+
+ if (ts == GST_CLOCK_TIME_NONE) {
+ warning("gst_video: timestamp is unknown\n");
+ rtp_ts = 0;
+ }
+ else {
+ /* convert from nanoseconds to RTP clock */
+ rtp_ts = (uint32_t)((90000ULL * ts) / 1000000000UL);
+ }
+
+ h264_packetize(rtp_ts, data, size, st->encoder.pktsize,
st->pkth, st->arg);
gst_buffer_unmap(buffer, &info);
diff --git a/modules/h265/encode.c b/modules/h265/encode.c
index 239abe6..f4835a3 100644
--- a/modules/h265/encode.c
+++ b/modules/h265/encode.c
@@ -140,12 +140,13 @@ static int open_encoder(struct videnc_state *st, const struct vidsz *size)
static inline int packetize(bool marker, const uint8_t *buf, size_t len,
- size_t maxlen, videnc_packet_h *pkth, void *arg)
+ size_t maxlen, uint32_t rtp_ts,
+ videnc_packet_h *pkth, void *arg)
{
int err = 0;
if (len <= maxlen) {
- err = pkth(marker, NULL, 0, buf, len, arg);
+ err = pkth(marker, rtp_ts, NULL, 0, buf, len, arg);
}
else {
struct h265_nal nal;
@@ -168,7 +169,8 @@ static inline int packetize(bool marker, const uint8_t *buf, size_t len,
len-=2;
while (len > flen) {
- err |= pkth(false, fu_hdr, 3, buf, flen, arg);
+ err |= pkth(false, rtp_ts, fu_hdr, 3, buf, flen,
+ arg);
buf += flen;
len -= flen;
@@ -177,7 +179,8 @@ static inline int packetize(bool marker, const uint8_t *buf, size_t len,
fu_hdr[2] |= 1<<6; /* set END bit */
- err |= pkth(marker, fu_hdr, 3, buf, len, arg);
+ err |= pkth(marker, rtp_ts, fu_hdr, 3, buf, len,
+ arg);
}
return err;
@@ -192,6 +195,7 @@ int h265_encode(struct videnc_state *st, bool update,
uint32_t i, nalc = 0;
int colorspace;
int n, err = 0;
+ uint32_t ts;
if (!st || !frame)
return EINVAL;
@@ -253,6 +257,8 @@ int h265_encode(struct videnc_state *st, bool update,
if (n <= 0)
goto out;
+ ts = video_calc_rtp_timestamp(pic_out.pts, st->fps);
+
for (i=0; i<nalc; i++) {
x265_nal *nal = &nalv[i];
@@ -273,7 +279,7 @@ int h265_encode(struct videnc_state *st, bool update,
marker = (i+1)==nalc; /* last NAL */
err = packetize(marker, p, len, st->pktsize,
- st->pkth, st->arg);
+ ts, st->pkth, st->arg);
if (err)
goto out;
}
diff --git a/modules/v4l2_codec/v4l2_codec.c b/modules/v4l2_codec/v4l2_codec.c
index d688dad..814a477 100644
--- a/modules/v4l2_codec/v4l2_codec.c
+++ b/modules/v4l2_codec/v4l2_codec.c
@@ -277,7 +277,7 @@ static void enc_destructor(void *arg)
}
-static void encoders_read(const uint8_t *buf, size_t sz)
+static void encoders_read(uint32_t rtp_ts, const uint8_t *buf, size_t sz)
{
struct le *le;
int err;
@@ -285,8 +285,9 @@ static void encoders_read(const uint8_t *buf, size_t sz)
for (le = v4l2.encoderl.head; le; le = le->next) {
struct videnc_state *st = le->data;
- err = h264_packetize(buf, sz,
- st->encprm.pktsize, st->pkth, st->arg);
+ err = h264_packetize(rtp_ts, buf, sz,
+ st->encprm.pktsize,
+ st->pkth, st->arg);
if (err) {
warning("h264_packetize error (%m)\n", err);
}
@@ -299,6 +300,8 @@ static void read_handler(int flags, void *arg)
struct vidsrc_st *st = arg;
struct v4l2_buffer buf;
bool keyframe = false;
+ struct timeval ts;
+ uint32_t rtp_ts;
int err;
if (flags & FD_EXCEPT) {
@@ -342,6 +345,9 @@ static void read_handler(int flags, void *arg)
}
}
+ ts = buf.timestamp;
+ rtp_ts = (90000ULL * (1000000*ts.tv_sec + ts.tv_usec)) / 1000000;
+
#if 0
debug("v4l2_codec: %s frame captured at %ldsec, %ldusec (%zu bytes)\n",
keyframe ? "KEY" : " ",
@@ -350,7 +356,7 @@ static void read_handler(int flags, void *arg)
#endif
/* pass the frame to the encoders */
- encoders_read(st->buffer, buf.bytesused);
+ encoders_read(rtp_ts, st->buffer, buf.bytesused);
err = query_buffer(st->fd);
if (err) {
diff --git a/modules/vidloop/vidloop.c b/modules/vidloop/vidloop.c
index a7cecf8..99575e6 100644
--- a/modules/vidloop/vidloop.c
+++ b/modules/vidloop/vidloop.c
@@ -122,8 +122,10 @@ static int display(struct video_loop *vl, struct vidframe *frame)
}
-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 rtp_ts,
+ const uint8_t *hdr, size_t hdr_len,
+ const uint8_t *pld, size_t pld_len,
+ void *arg)
{
struct video_loop *vl = arg;
struct vidframe frame;
diff --git a/modules/vp8/encode.c b/modules/vp8/encode.c
index 99560de..83f136b 100644
--- a/modules/vp8/encode.c
+++ b/modules/vp8/encode.c
@@ -157,7 +157,8 @@ static inline void hdr_encode(uint8_t hdr[HDR_SIZE], bool noref, bool start,
static inline int packetize(bool marker, const uint8_t *buf, size_t len,
size_t maxlen, bool noref, uint8_t partid,
- uint16_t picid, videnc_packet_h *pkth, void *arg)
+ uint16_t picid, uint32_t rtp_ts,
+ videnc_packet_h *pkth, void *arg)
{
uint8_t hdr[HDR_SIZE];
bool start = true;
@@ -169,7 +170,8 @@ static inline int packetize(bool marker, const uint8_t *buf, size_t len,
hdr_encode(hdr, noref, start, partid, picid);
- err |= pkth(false, hdr, sizeof(hdr), buf, maxlen, arg);
+ err |= pkth(false, rtp_ts, hdr, sizeof(hdr), buf, maxlen,
+ arg);
buf += maxlen;
len -= maxlen;
@@ -178,7 +180,7 @@ static inline int packetize(bool marker, const uint8_t *buf, size_t len,
hdr_encode(hdr, noref, start, partid, picid);
- err |= pkth(marker, hdr, sizeof(hdr), buf, len, arg);
+ err |= pkth(marker, rtp_ts, hdr, sizeof(hdr), buf, len, arg);
return err;
}
@@ -234,6 +236,7 @@ int vp8_encode(struct videnc_state *ves, bool update,
bool keyframe = false, marker = true;
const vpx_codec_cx_pkt_t *pkt;
uint8_t partid = 0;
+ uint32_t ts;
pkt = vpx_codec_get_cx_data(&ves->ctx, &iter);
if (!pkt)
@@ -253,10 +256,13 @@ int vp8_encode(struct videnc_state *ves, bool update,
partid = pkt->data.frame.partition_id;
#endif
+ ts = video_calc_rtp_timestamp(pkt->data.frame.pts, ves->fps);
+
err = packetize(marker,
pkt->data.frame.buf,
pkt->data.frame.sz,
ves->pktsize, !keyframe, partid, ves->picid,
+ ts,
ves->pkth, ves->arg);
if (err)
return err;
diff --git a/modules/vp9/encode.c b/modules/vp9/encode.c
index 749a5bb..9de4d73 100644
--- a/modules/vp9/encode.c
+++ b/modules/vp9/encode.c
@@ -171,17 +171,20 @@ static inline void hdr_encode(uint8_t hdr[HDR_SIZE], bool start, bool end,
static int send_packet(struct videnc_state *ves, bool marker,
const uint8_t *hdr, size_t hdr_len,
- const uint8_t *pld, size_t pld_len)
+ const uint8_t *pld, size_t pld_len,
+ uint32_t rtp_ts)
{
ves->n_bytes += (hdr_len + pld_len);
- return ves->pkth(marker, hdr, hdr_len, pld, pld_len, ves->arg);
+ return ves->pkth(marker, rtp_ts, hdr, hdr_len, pld, pld_len,
+ ves->arg);
}
static inline int packetize(struct videnc_state *ves,
bool marker, const uint8_t *buf, size_t len,
- size_t maxlen, uint16_t picid)
+ size_t maxlen, uint16_t picid,
+ uint32_t rtp_ts)
{
uint8_t hdr[HDR_SIZE];
bool start = true;
@@ -193,7 +196,8 @@ static inline int packetize(struct videnc_state *ves,
hdr_encode(hdr, start, false, picid);
- err |= send_packet(ves, false, hdr, sizeof(hdr), buf, maxlen);
+ err |= send_packet(ves, false, hdr, sizeof(hdr), buf, maxlen,
+ rtp_ts);
buf += maxlen;
len -= maxlen;
@@ -202,7 +206,8 @@ static inline int packetize(struct videnc_state *ves,
hdr_encode(hdr, start, true, picid);
- err |= send_packet(ves, marker, hdr, sizeof(hdr), buf, len);
+ err |= send_packet(ves, marker, hdr, sizeof(hdr), buf, len,
+ rtp_ts);
return err;
}
@@ -275,6 +280,7 @@ int vp9_encode(struct videnc_state *ves, bool update,
for (;;) {
bool marker = true;
const vpx_codec_cx_pkt_t *pkt;
+ uint32_t ts;
pkt = vpx_codec_get_cx_data(&ves->ctx, &iter);
if (!pkt)
@@ -291,11 +297,14 @@ int vp9_encode(struct videnc_state *ves, bool update,
if (pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT)
marker = false;
+ ts = video_calc_rtp_timestamp(pkt->data.frame.pts, ves->fps);
+
err = packetize(ves,
marker,
pkt->data.frame.buf,
pkt->data.frame.sz,
- ves->pktsize, ves->picid);
+ ves->pktsize, ves->picid,
+ ts);
if (err)
return err;
}
diff --git a/src/h264.c b/src/h264.c
index 8da811d..2bb4a26 100644
--- a/src/h264.c
+++ b/src/h264.c
@@ -103,23 +103,24 @@ const uint8_t *h264_find_startcode(const uint8_t *p, const uint8_t *end)
static int rtp_send_data(const uint8_t *hdr, size_t hdr_sz,
- const uint8_t *buf, size_t sz, bool eof,
+ const uint8_t *buf, size_t sz,
+ bool eof, uint32_t rtp_ts,
videnc_packet_h *pkth, void *arg)
{
- return pkth(eof, hdr, hdr_sz, buf, sz, arg);
+ return pkth(eof, rtp_ts, hdr, hdr_sz, buf, sz, arg);
}
int h264_nal_send(bool first, bool last,
- bool marker, uint32_t ihdr, const uint8_t *buf,
- size_t size, size_t maxsz,
+ bool marker, uint32_t ihdr, uint32_t rtp_ts,
+ const uint8_t *buf, size_t size, size_t maxsz,
videnc_packet_h *pkth, void *arg)
{
uint8_t hdr = (uint8_t)ihdr;
int err = 0;
if (first && last && size <= maxsz) {
- err = rtp_send_data(&hdr, 1, buf, size, marker,
+ err = rtp_send_data(&hdr, 1, buf, size, marker, rtp_ts,
pkth, arg);
}
else {
@@ -133,6 +134,7 @@ int h264_nal_send(bool first, bool last,
while (size > sz) {
err |= rtp_send_data(fu_hdr, 2, buf, sz, false,
+ rtp_ts,
pkth, arg);
buf += sz;
size -= sz;
@@ -143,6 +145,7 @@ int h264_nal_send(bool first, bool last,
fu_hdr[1] |= 1<<6; /* end bit */
err |= rtp_send_data(fu_hdr, 2, buf, size, marker && last,
+ rtp_ts,
pkth, arg);
}
@@ -150,8 +153,8 @@ int h264_nal_send(bool first, bool last,
}
-int h264_packetize(const uint8_t *buf, size_t len, size_t pktsize,
- videnc_packet_h *pkth, void *arg)
+int h264_packetize(uint32_t rtp_ts, const uint8_t *buf, size_t len,
+ size_t pktsize, videnc_packet_h *pkth, void *arg)
{
const uint8_t *start = buf;
const uint8_t *end = buf + len;
@@ -170,7 +173,7 @@ int h264_packetize(const uint8_t *buf, size_t len, size_t pktsize,
r1 = h264_find_startcode(r, end);
err |= h264_nal_send(true, true, (r1 >= end), r[0],
- r+1, r1-r-1, pktsize,
+ rtp_ts, r+1, r1-r-1, pktsize,
pkth, arg);
r = r1;
}
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;
+}
diff --git a/test/mock/mock_vidcodec.c b/test/mock/mock_vidcodec.c
index 745e43f..9609e65 100644
--- a/test/mock/mock_vidcodec.c
+++ b/test/mock/mock_vidcodec.c
@@ -21,6 +21,8 @@ struct hdr {
};
struct videnc_state {
+ int64_t pts;
+ unsigned fps;
videnc_packet_h *pkth;
void *arg;
};
@@ -73,6 +75,7 @@ static int mock_encode_update(struct videnc_state **vesp,
*vesp = ves;
}
+ ves->fps = prm->fps;
ves->pkth = pkth;
ves->arg = arg;
@@ -85,6 +88,7 @@ static int mock_encode(struct videnc_state *ves, bool update,
{
struct mbuf *hdr;
uint8_t payload[2] = {0,0};
+ uint32_t rtp_ts;
int err;
(void)update;
@@ -99,7 +103,9 @@ static int mock_encode(struct videnc_state *ves, bool update,
if (err)
goto out;
- err = ves->pkth(true, hdr->buf, hdr->end,
+ rtp_ts = video_calc_rtp_timestamp(++ves->pts, ves->fps);
+
+ err = ves->pkth(true, rtp_ts, hdr->buf, hdr->end,
payload, sizeof(payload), ves->arg);
if (err)
goto out;