]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Borrow av_rescale() from libavutil
authorAndreas Öman <andreas@lonelycoder.com>
Wed, 23 Jun 2010 22:38:24 +0000 (22:38 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Wed, 23 Jun 2010 22:38:24 +0000 (22:38 +0000)
src/dvr/mkmux.c
src/htsp.c
src/tvhead.h
src/utils.c

index 4e35d5b3e5f12185926c6d2caa852cbd1a748041..94f5931c3509e155990acbddd6f1a7abea464438 100644 (file)
 #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;
index de326cb2b05c34a08b02c84fd6c6057e60aeb470..fbeda54cd77ea06a4d994540e91f447ef263946c 100644 (file)
@@ -45,8 +45,6 @@
 #include "settings.h"
 #include <sys/time.h>
 
-#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);
index 10d9925e34cde4d6b66224ffa5313fceb231edd2..fe28e9d525340651fd2c7a3e6313d42ed2006cad 100644 (file)
@@ -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 */
index ec7be746b9468ed1989e58936d8d0e77c0e5e5c2..33e8b466331460df139233e9e219c83c3348bf02 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
  * Copyright (c) 2010 Andreas Öman
  *
@@ -16,6 +17,8 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <limits.h>
+#include <assert.h>
 #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<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);
+}