diff --git a/src/dvr/mkmux.c b/src/dvr/mkmux.c index 4e35d5b3..94f5931c 100644 --- a/src/dvr/mkmux.c +++ b/src/dvr/mkmux.c @@ -30,16 +30,15 @@ #include "dvr.h" #include "mkmux.h" #include "ebml.h" -#include "libavcodec/avcodec.h" TAILQ_HEAD(mk_cue_queue, mk_cue); #define MATROSKA_TIMESCALE 1000000 // in nS -static const AVRational mpeg_tc = {1, 90000}; -static const AVRational mkv_tc = {1, 1000}; -static const AVRational ns_tc = {1, 1000000000}; +static const Rational mpeg_tc = {1, 90000}; +static const Rational mkv_tc = {1, 1000}; +static const Rational ns_tc = {1, 1000000000}; /** * @@ -238,7 +237,7 @@ mk_build_tracks(mk_mux_t *mkm, const struct streaming_start *ss) } if(ssc->ssc_frameduration) { - int d = av_rescale_q(ssc->ssc_frameduration, mpeg_tc, ns_tc); + int d = rescale_q(ssc->ssc_frameduration, mpeg_tc, ns_tc); ebml_append_uint(t, 0x23e383, d); } @@ -581,8 +580,8 @@ mk_write_frame_i(mk_mux_t *mkm, mk_track *t, th_pkt_t *pkt) if(pts != PTS_UNSET) { t->nextpts = pts + (pkt->pkt_duration >> pkt->pkt_field); - nxt = av_rescale_q(t->nextpts, mpeg_tc, mkv_tc); - pts = av_rescale_q(pts, mpeg_tc, mkv_tc); + nxt = rescale_q(t->nextpts, mpeg_tc, mkv_tc); + pts = rescale_q(pts, mpeg_tc, mkv_tc); if(mkm->totduration < nxt) mkm->totduration = nxt; diff --git a/src/htsp.c b/src/htsp.c index de326cb2..fbeda54c 100644 --- a/src/htsp.c +++ b/src/htsp.c @@ -45,8 +45,6 @@ #include "settings.h" #include -#include "libavcodec/avcodec.h" - static void *htsp_server; #define HTSP_PROTO_VERSION 5 @@ -1374,7 +1372,8 @@ const static char frametypearray[PKT_NTYPES] = { [PKT_B_FRAME] = 'B', }; -const static AVRational mpeg_tc = {1, 90000}; +const static Rational mpeg_tc = {1, 90000}; +const static Rational htsp_tc = {1, 1000000}; /** * Build a htsmsg from a th_pkt and enqueue it on our HTSP transport @@ -1408,16 +1407,16 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) if(pkt->pkt_pts != PTS_UNSET) { - int64_t pts = av_rescale_q(pkt->pkt_pts, mpeg_tc, AV_TIME_BASE_Q); + int64_t pts = rescale_q(pkt->pkt_pts, mpeg_tc, htsp_tc); htsmsg_add_s64(m, "pts", pts); } if(pkt->pkt_dts != PTS_UNSET) { - int64_t dts = av_rescale_q(pkt->pkt_dts, mpeg_tc, AV_TIME_BASE_Q); + int64_t dts = rescale_q(pkt->pkt_dts, mpeg_tc, htsp_tc); htsmsg_add_s64(m, "dts", dts); } - uint32_t dur = av_rescale_q(pkt->pkt_duration, mpeg_tc, AV_TIME_BASE_Q); + uint32_t dur = rescale_q(pkt->pkt_duration, mpeg_tc, htsp_tc); htsmsg_add_u32(m, "duration", dur); pkt = pkt_merge_global(pkt); diff --git a/src/tvhead.h b/src/tvhead.h index 10d9925e..fe28e9d5 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -842,4 +842,11 @@ int base64_decode(uint8_t *out, const char *in, int out_size); int put_utf8(char *out, int c); +typedef struct Rational{ + int num; ///< numerator + int den; ///< denominator +} Rational; + +int64_t rescale_q(int64_t a, Rational bq, Rational cq); + #endif /* TV_HEAD_H */ diff --git a/src/utils.c b/src/utils.c index ec7be746..33e8b466 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2005 Michael Niedermayer * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) * Copyright (c) 2010 Andreas Ă–man * @@ -16,6 +17,8 @@ * along with this program. If not, see . */ +#include +#include #include "tvhead.h" /** @@ -207,3 +210,63 @@ put_utf8(char *out, int c) *out++ = 0x80 | (0x3f & c); return 6; } + + + +enum AVRounding { + AV_ROUND_ZERO = 0, ///< Round toward zero. + AV_ROUND_INF = 1, ///< Round away from zero. + AV_ROUND_DOWN = 2, ///< Round toward -infinity. + AV_ROUND_UP = 3, ///< Round toward +infinity. + AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. +}; + + +static int64_t rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ + int64_t r=0; + assert(c > 0); + assert(b >=0); + assert(rnd >=0 && rnd<=5 && rnd!=4); + + if(a<0 && a != INT64_MIN) return -rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); + + if(rnd==AV_ROUND_NEAR_INF) r= c/2; + else if(rnd&1) r= c-1; + + if(b<=INT_MAX && c<=INT_MAX){ + if(a<=INT_MAX) + return (a * b + r)/c; + else + return a/c*b + (a%c*b + r)/c; + }else{ + uint64_t a0= a&0xFFFFFFFF; + uint64_t a1= a>>32; + uint64_t b0= b&0xFFFFFFFF; + uint64_t b1= b>>32; + uint64_t t1= a0*b1 + a1*b0; + uint64_t t1a= t1<<32; + int i; + + a0 = a0*b0 + t1a; + a1 = a1*b1 + (t1>>32) + (a0=0; i--){ +// int o= a1 & 0x8000000000000000ULL; + a1+= a1 + ((a0>>i)&1); + t1+=t1; + if(/*o || */c <= a1){ + a1 -= c; + t1++; + } + } + return t1; + } +} + +int64_t rescale_q(int64_t a, Rational bq, Rational cq){ + int64_t b= bq.num * (int64_t)cq.den; + int64_t c= cq.num * (int64_t)bq.den; + return rescale_rnd(a, b, c, AV_ROUND_NEAR_INF); +}