1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tv.tuner.tvinput;
18 
19 import android.os.SystemClock;
20 import android.util.Log;
21 
22 /**
23  * A class to maintain various debugging information.
24  */
25 public class TunerDebug {
26     private static final String TAG = "TunerDebug";
27     public static final boolean ENABLED = false;
28 
29     private int mVideoFrameDrop;
30     private int mBytesInQueue;
31 
32     private long mAudioPositionUs;
33     private long mAudioPtsUs;
34     private long mVideoPtsUs;
35 
36     private long mLastAudioPositionUs;
37     private long mLastAudioPtsUs;
38     private long mLastVideoPtsUs;
39     private long mLastCheckTimestampMs;
40 
41     private long mAudioPositionUsRate;
42     private long mAudioPtsUsRate;
43     private long mVideoPtsUsRate;
44 
TunerDebug()45     private TunerDebug() {
46         mVideoFrameDrop = 0;
47         mLastCheckTimestampMs = SystemClock.elapsedRealtime();
48     }
49 
50     private static class LazyHolder {
51         private static final TunerDebug INSTANCE = new TunerDebug();
52     }
53 
getInstance()54     public static TunerDebug getInstance() {
55         return LazyHolder.INSTANCE;
56     }
57 
notifyVideoFrameDrop(long delta)58     public static void notifyVideoFrameDrop(long delta) {
59         // TODO: provide timestamp mismatch information using delta
60         TunerDebug sTunerDebug = getInstance();
61         sTunerDebug.mVideoFrameDrop++;
62     }
63 
getVideoFrameDrop()64     public static int getVideoFrameDrop() {
65         TunerDebug sTunerDebug = getInstance();
66         int videoFrameDrop = sTunerDebug.mVideoFrameDrop;
67         if (videoFrameDrop > 0) {
68             Log.d(TAG, "Dropped video frame: " + videoFrameDrop);
69         }
70         sTunerDebug.mVideoFrameDrop = 0;
71         return videoFrameDrop;
72     }
73 
setBytesInQueue(int bytesInQueue)74     public static void setBytesInQueue(int bytesInQueue) {
75         TunerDebug sTunerDebug = getInstance();
76         sTunerDebug.mBytesInQueue = bytesInQueue;
77     }
78 
getBytesInQueue()79     public static int getBytesInQueue() {
80         TunerDebug sTunerDebug = getInstance();
81         return sTunerDebug.mBytesInQueue;
82     }
83 
setAudioPositionUs(long audioPositionUs)84     public static void setAudioPositionUs(long audioPositionUs) {
85         TunerDebug sTunerDebug = getInstance();
86         sTunerDebug.mAudioPositionUs = audioPositionUs;
87     }
88 
getAudioPositionUs()89     public static long getAudioPositionUs() {
90         TunerDebug sTunerDebug = getInstance();
91         return sTunerDebug.mAudioPositionUs;
92     }
93 
setAudioPtsUs(long audioPtsUs)94     public static void setAudioPtsUs(long audioPtsUs) {
95         TunerDebug sTunerDebug = getInstance();
96         sTunerDebug.mAudioPtsUs = audioPtsUs;
97     }
98 
getAudioPtsUs()99     public static long getAudioPtsUs() {
100         TunerDebug sTunerDebug = getInstance();
101         return sTunerDebug.mAudioPtsUs;
102     }
103 
setVideoPtsUs(long videoPtsUs)104     public static void setVideoPtsUs(long videoPtsUs) {
105         TunerDebug sTunerDebug = getInstance();
106         sTunerDebug.mVideoPtsUs = videoPtsUs;
107     }
108 
getVideoPtsUs()109     public static long getVideoPtsUs() {
110         TunerDebug sTunerDebug = getInstance();
111         return sTunerDebug.mVideoPtsUs;
112     }
113 
calculateDiff()114     public static void calculateDiff() {
115         TunerDebug sTunerDebug = getInstance();
116         long currentTime = SystemClock.elapsedRealtime();
117         long duration = currentTime - sTunerDebug.mLastCheckTimestampMs;
118         if (duration != 0) {
119             sTunerDebug.mAudioPositionUsRate =
120                     (sTunerDebug.mAudioPositionUs - sTunerDebug.mLastAudioPositionUs) * 1000
121                     / duration;
122             sTunerDebug.mAudioPtsUsRate =
123                     (sTunerDebug.mAudioPtsUs - sTunerDebug.mLastAudioPtsUs) * 1000
124                     / duration;
125             sTunerDebug.mVideoPtsUsRate =
126                     (sTunerDebug.mVideoPtsUs - sTunerDebug.mLastVideoPtsUs) * 1000
127                     / duration;
128         }
129 
130         sTunerDebug.mLastAudioPositionUs = sTunerDebug.mAudioPositionUs;
131         sTunerDebug.mLastAudioPtsUs = sTunerDebug.mAudioPtsUs;
132         sTunerDebug.mLastVideoPtsUs = sTunerDebug.mVideoPtsUs;
133         sTunerDebug.mLastCheckTimestampMs = currentTime;
134     }
135 
getAudioPositionUsRate()136     public static long getAudioPositionUsRate() {
137         TunerDebug sTunerDebug = getInstance();
138         return sTunerDebug.mAudioPositionUsRate;
139     }
140 
getAudioPtsUsRate()141     public static long getAudioPtsUsRate() {
142         TunerDebug sTunerDebug = getInstance();
143         return sTunerDebug.mAudioPtsUsRate;
144     }
145 
getVideoPtsUsRate()146     public static long getVideoPtsUsRate() {
147         TunerDebug sTunerDebug = getInstance();
148         return sTunerDebug.mVideoPtsUsRate;
149     }
150 }
151