1 /*--------------------------------------------------------------------------
2 Copyright (c) 2013 - 2019, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6     * Redistributions of source code must retain the above copyright
7       notice, this list of conditions and the following disclaimer.
8     * Redistributions in binary form must reproduce the above copyright
9       notice, this list of conditions and the following disclaimer in the
10       documentation and/or other materials provided with the distribution.
11     * Neither the name of The Linux Foundation nor
12       the names of its contributors may be used to endorse or promote
13       products derived from this software without specific prior written
14       permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 
29 #ifndef __VIDC_DEBUG_H__
30 #define __VIDC_DEBUG_H__
31 
32 #ifdef _ANDROID_
33 #include <cstdio>
34 #include <pthread.h>
35 #include <sys/mman.h>
36 
37 enum {
38    PRIO_ERROR=0x1,
39    PRIO_INFO=0x1,
40    PRIO_HIGH=0x2,
41    PRIO_LOW=0x4,
42    PRIO_TRACE_HIGH = 0x10,
43    PRIO_TRACE_LOW = 0x20,
44 };
45 
46 extern int debug_level;
47 
48 #undef DEBUG_PRINT_ERROR
49 #define DEBUG_PRINT_ERROR(fmt, args...) ({ \
50       if (debug_level & PRIO_ERROR) \
51           ALOGE(fmt,##args); \
52       })
53 #undef DEBUG_PRINT_INFO
54 #define DEBUG_PRINT_INFO(fmt, args...) ({ \
55       if (debug_level & PRIO_INFO) \
56           ALOGI(fmt,##args); \
57       })
58 #undef DEBUG_PRINT_LOW
59 #define DEBUG_PRINT_LOW(fmt, args...) ({ \
60       if (debug_level & PRIO_LOW) \
61           ALOGD(fmt,##args); \
62       })
63 #undef DEBUG_PRINT_HIGH
64 #define DEBUG_PRINT_HIGH(fmt, args...) ({ \
65       if (debug_level & PRIO_HIGH) \
66           ALOGD(fmt,##args); \
67       })
68 #else
69 #define DEBUG_PRINT_ERROR printf
70 #define DEBUG_PRINT_INFO printf
71 #define DEBUG_PRINT_LOW printf
72 #define DEBUG_PRINT_HIGH printf
73 #endif
74 
75 #define VALIDATE_OMX_PARAM_DATA(ptr, paramType)                                \
76     {                                                                          \
77         if (ptr == NULL) { return OMX_ErrorBadParameter; }                     \
78         paramType *p = reinterpret_cast<paramType *>(ptr);                     \
79         if (p->nSize < sizeof(paramType)) {                                    \
80             ALOGE("Insufficient object size(%u) v/s expected(%zu) for type %s",\
81                     (unsigned int)p->nSize, sizeof(paramType), #paramType);    \
82             return OMX_ErrorBadParameter;                                      \
83         }                                                                      \
84     }                                                                          \
85 
86 /*
87  * Validate OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE type param
88  * *assumes* VALIDATE_OMX_PARAM_DATA checks have passed
89  * Checks for nParamCount cannot be generalized here. it is imperative that
90  *  the calling code handles it.
91  */
92 #define VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext)                                             \
93     {                                                                                             \
94         if (ext->nParamSizeUsed < 1 || ext->nParamSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) { \
95             ALOGE("VendorExtension: sub-params(%u) not in expected range(%u - %u)",               \
96                     ext->nParamSizeUsed, 1, OMX_MAX_ANDROID_VENDOR_PARAMCOUNT);                   \
97             return OMX_ErrorBadParameter;                                                         \
98         }                                                                                         \
99         OMX_U32 expectedSize = (OMX_U32)sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) +         \
100                 ((ext->nParamSizeUsed - 1) * (OMX_U32)sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE));\
101         if (ext->nSize < expectedSize) {                                                          \
102             ALOGE("VendorExtension: Insifficient size(%u) v/s expected(%u)",                      \
103                     ext->nSize, expectedSize);                                                    \
104             return OMX_ErrorBadParameter;                                                         \
105         }                                                                                         \
106     }                                                                                             \
107 
108 class auto_lock {
109     public:
auto_lock(pthread_mutex_t & lock)110         auto_lock(pthread_mutex_t &lock)
111             : mLock(lock) {
112                 pthread_mutex_lock(&mLock);
113             }
~auto_lock()114         ~auto_lock() {
115             pthread_mutex_unlock(&mLock);
116         }
117     private:
118         pthread_mutex_t &mLock;
119 };
120 
121 class Signal {
122     bool signalled;
123     pthread_mutex_t mutex;
124     pthread_cond_t condition;
125 public:
Signal()126     Signal() {
127         signalled = false;
128         pthread_cond_init(&condition, NULL);
129         pthread_mutex_init(&mutex, NULL);
130     }
131 
~Signal()132     ~Signal() {
133             pthread_cond_destroy(&condition);
134             pthread_mutex_destroy(&mutex);
135     }
136 
signal()137     void signal() {
138         pthread_mutex_lock(&mutex);
139         signalled = true;
140         pthread_cond_signal(&condition);
141         pthread_mutex_unlock(&mutex);
142     }
143 
wait(uint64_t timeout_nsec)144     int wait(uint64_t timeout_nsec) {
145         struct timespec ts;
146 
147         pthread_mutex_lock(&mutex);
148         if (signalled) {
149             signalled = false;
150             pthread_mutex_unlock(&mutex);
151             return 0;
152         }
153         clock_gettime(CLOCK_REALTIME, &ts);
154         ts.tv_sec += timeout_nsec / 1000000000;
155         ts.tv_nsec += timeout_nsec % 1000000000;
156         if (ts.tv_nsec >= 1000000000) {
157             ts.tv_nsec -= 1000000000;
158             ts.tv_sec  += 1;
159         }
160         int ret = pthread_cond_timedwait(&condition, &mutex, &ts);
161         //as the mutex lock is released inside timedwait first
162         //the singalled variant maybe changed by the main thread in some rare cases
163         //meanwhile still returns wait time out
164         //need to double check it and return 0 to process the last cmd/event during time out
165         if (signalled)
166             ret = 0;
167         signalled = false;
168         pthread_mutex_unlock(&mutex);
169         return ret;
170     }
171 };
172 
173 #ifdef _ANDROID_
174 #define ATRACE_TAG ATRACE_TAG_VIDEO
175 #include <cutils/trace.h>
176 #include <utils/Trace.h>
177 
178 class AutoTracer {
179     int mPrio;
180 public:
AutoTracer(int prio,const char * msg)181     AutoTracer(int prio, const char* msg)
182         : mPrio(prio) {
183         if (debug_level & prio) {
184             ATRACE_BEGIN(msg);
185         }
186     }
~AutoTracer()187     ~AutoTracer() {
188         if (debug_level & mPrio) {
189             ATRACE_END();
190         }
191     }
192 };
193 
194 struct __attribute__((packed)) IvfFileHeader {
195     uint8_t signature[4];
196     uint16_t version;
197     uint16_t size;
198     uint8_t fourCC[4];
199     uint16_t width;
200     uint16_t height;
201     uint32_t rate;
202     uint32_t scale;
203     uint32_t frameCount;
204     uint32_t unused;
205 
206     IvfFileHeader();
207     IvfFileHeader(bool isVp9, int width, int height,
208                 int rate, int scale, int nFrameCount);
209 };
210 
211 struct __attribute__((packed)) IvfFrameHeader {
212     uint32_t filledLen;
213     uint64_t timeStamp;
214 
215     IvfFrameHeader();
216     IvfFrameHeader(uint32_t size, uint64_t timeStamp);
217 };
218 
219 #define VIDC_TRACE_NAME_LOW(_name) AutoTracer _tracer(PRIO_TRACE_LOW, _name);
220 #define VIDC_TRACE_NAME_HIGH(_name) AutoTracer _tracer(PRIO_TRACE_HIGH, _name);
221 
222 #define VIDC_TRACE_INT_LOW(_name, _int) \
223     if (debug_level & PRIO_TRACE_LOW) { \
224         ATRACE_INT(_name, _int);        \
225     }
226 
227 #define VIDC_TRACE_INT_HIGH(_name, _int) \
228     if (debug_level & PRIO_TRACE_HIGH) { \
229         ATRACE_INT(_name, _int);        \
230     }
231 
232 #else // _ANDROID_
233 
234 #define VIDC_TRACE_NAME_LOW(_name)
235 #define VIDC_TRACE_NAME_HIGH(_name)
236 #define VIDC_TRACE_INT_LOW(_name, _int)
237 #define VIDC_TRACE_INT_HIGH(_name, _int)
238 
239 #endif // !_ANDROID_
240 
241 #endif
242