#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};
/**
*
}
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);
}
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;
#include "settings.h"
#include <sys/time.h>
-#include "libavcodec/avcodec.h"
-
static void *htsp_server;
#define HTSP_PROTO_VERSION 5
[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
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);
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 */
/*
+ * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
* Copyright (c) 2010 Andreas Öman
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <limits.h>
+#include <assert.h>
#include "tvhead.h"
/**
*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<t1a);
+ a0 += r;
+ a1 += a0<r;
+
+ for(i=63; i>=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);
+}