1 /*--------------------------------------------------------------------------
2 Copyright (c) 2013 - 2020, 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
34 #include <cstdio>
35 #include <string.h>
36 #include <pthread.h>
37 #include <sys/mman.h>
38 extern "C" {
39 #include <utils/Log.h>
40 }
41
42 #include <linux/videodev2.h>
43 #include "OMX_Core.h"
44 #include "vidc_common.h"
45 #include <color_metadata.h>
46 #define STRINGIFY_ENUMS
47 #include "media/hardware/VideoAPI.h"
48 #include "media/msm_vidc_utils.h"
49
50 using android::ColorAspects;
51 using android::HDRStaticInfo;
52
53 enum {
54 PRIO_ERROR=0x1,
55 PRIO_INFO=0x1,
56 PRIO_HIGH=0x2,
57 PRIO_LOW=0x4,
58 PRIO_TRACE_HIGH = 0x10,
59 PRIO_TRACE_LOW = 0x20,
60 };
61
62 extern int debug_level;
63
64 #undef DEBUG_PRINT_ERROR
65 #define DEBUG_PRINT_ERROR(fmt, args...) ({ \
66 if (debug_level & PRIO_ERROR) \
67 ALOGE(fmt,##args); \
68 })
69 #undef DEBUG_PRINT_INFO
70 #define DEBUG_PRINT_INFO(fmt, args...) ({ \
71 if (debug_level & PRIO_INFO) \
72 ALOGI(fmt,##args); \
73 })
74 #undef DEBUG_PRINT_LOW
75 #define DEBUG_PRINT_LOW(fmt, args...) ({ \
76 if (debug_level & PRIO_LOW) \
77 ALOGD(fmt,##args); \
78 })
79 #undef DEBUG_PRINT_HIGH
80 #define DEBUG_PRINT_HIGH(fmt, args...) ({ \
81 if (debug_level & PRIO_HIGH) \
82 ALOGD(fmt,##args); \
83 })
84 #else
85 #define DEBUG_PRINT_ERROR printf
86 #define DEBUG_PRINT_INFO printf
87 #define DEBUG_PRINT_LOW printf
88 #define DEBUG_PRINT_HIGH printf
89 #endif
90
91 struct debug_cap {
92 bool in_buffer_log;
93 bool out_buffer_log;
94 bool out_cc_buffer_log;
95 bool out_meta_buffer_log;
96 char infile_name[PROPERTY_VALUE_MAX + 36];
97 char outfile_name[PROPERTY_VALUE_MAX + 36];
98 char ccoutfile_name[PROPERTY_VALUE_MAX + 36];
99 char out_ymetafile_name[PROPERTY_VALUE_MAX + 36];
100 char out_uvmetafile_name[PROPERTY_VALUE_MAX + 36];
101 char log_loc[PROPERTY_VALUE_MAX];
102 FILE *infile;
103 FILE *outfile;
104 FILE *ccoutfile;
105 FILE *out_ymeta_file;
106 FILE *out_uvmeta_file;
107 int64_t session_id;
108 int seq_count;
109 };
110
111 #define VALIDATE_OMX_PARAM_DATA(ptr, paramType) \
112 { \
113 if (ptr == NULL) { return OMX_ErrorBadParameter; } \
114 paramType *p = reinterpret_cast<paramType *>(ptr); \
115 if (p->nSize < sizeof(paramType)) { \
116 ALOGE("Insufficient object size(%u) v/s expected(%zu) for type %s",\
117 (unsigned int)p->nSize, sizeof(paramType), #paramType); \
118 return OMX_ErrorBadParameter; \
119 } \
120 } \
121
122 /*
123 * Validate OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE type param
124 * *assumes* VALIDATE_OMX_PARAM_DATA checks have passed
125 * Checks for nParamCount cannot be generalized here. it is imperative that
126 * the calling code handles it.
127 */
128 #define VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext) \
129 { \
130 if (ext->nParamSizeUsed < 1 || ext->nParamSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) { \
131 ALOGE("VendorExtension: sub-params(%u) not in expected range(%u - %u)", \
132 ext->nParamSizeUsed, 1, OMX_MAX_ANDROID_VENDOR_PARAMCOUNT); \
133 return OMX_ErrorBadParameter; \
134 } \
135 OMX_U32 expectedSize = (OMX_U32)sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) + \
136 ((ext->nParamSizeUsed - 1) * (OMX_U32)sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE));\
137 if (ext->nSize < expectedSize) { \
138 ALOGE("VendorExtension: Insifficient size(%u) v/s expected(%u)", \
139 ext->nSize, expectedSize); \
140 return OMX_ErrorBadParameter; \
141 } \
142 } \
143
144 void print_debug_color_aspects(ColorAspects *a, const char *prefix);
145 void print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix);
146 void print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata);
147 void print_debug_hdr10plus_metadata(ColorMetaData& color_mdata);
148
print_omx_buffer(const char * str,OMX_BUFFERHEADERTYPE * pHeader)149 static inline void print_omx_buffer(const char *str, OMX_BUFFERHEADERTYPE *pHeader)
150 {
151 if (!pHeader)
152 return;
153
154 DEBUG_PRINT_HIGH("%s: Header %p buffer %p alloclen %d offset %d filledlen %d timestamp %lld flags %#x",
155 str, pHeader, pHeader->pBuffer, pHeader->nAllocLen,
156 pHeader->nOffset, pHeader->nFilledLen,
157 pHeader->nTimeStamp, pHeader->nFlags);
158 }
159
print_v4l2_buffer(const char * str,struct v4l2_buffer * v4l2)160 static inline void print_v4l2_buffer(const char *str, struct v4l2_buffer *v4l2)
161 {
162 if (!v4l2)
163 return;
164
165 if (v4l2->length == 1)
166 DEBUG_PRINT_HIGH(
167 "%s: %s: idx %2d userptr %#lx fd %d off %d size %d filled %d flags %#x\n",
168 str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
169 "OUTPUT" : "CAPTURE", v4l2->index,
170 v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[MSM_VIDC_BUFFER_FD],
171 v4l2->m.planes[0].reserved[MSM_VIDC_DATA_OFFSET], v4l2->m.planes[0].length,
172 v4l2->m.planes[0].bytesused, v4l2->flags);
173 else
174 DEBUG_PRINT_HIGH(
175 "%s: %s: idx %2d userptr %#lx fd %d off %d size %d filled %d flags %#x, extradata: fd %d off %d size %d filled %d\n",
176 str, v4l2->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ?
177 "OUTPUT" : "CAPTURE", v4l2->index,
178 v4l2->m.planes[0].m.userptr, v4l2->m.planes[0].reserved[MSM_VIDC_BUFFER_FD],
179 v4l2->m.planes[0].reserved[MSM_VIDC_DATA_OFFSET], v4l2->m.planes[0].length,
180 v4l2->m.planes[0].bytesused, v4l2->flags, v4l2->m.planes[1].reserved[MSM_VIDC_BUFFER_FD],
181 v4l2->m.planes[1].reserved[MSM_VIDC_DATA_OFFSET], v4l2->m.planes[1].length,
182 v4l2->m.planes[1].bytesused);
183 }
184
185 class auto_lock {
186 public:
auto_lock(pthread_mutex_t & lock)187 auto_lock(pthread_mutex_t &lock)
188 : mLock(lock) {
189 pthread_mutex_lock(&mLock);
190 }
~auto_lock()191 ~auto_lock() {
192 pthread_mutex_unlock(&mLock);
193 }
194 private:
195 pthread_mutex_t &mLock;
196 };
197
198 class Signal {
199 bool signalled;
200 pthread_mutex_t mutex;
201 pthread_cond_t condition;
202 public:
Signal()203 Signal() {
204 pthread_condattr_t attr;
205 signalled = false;
206 pthread_condattr_init(&attr);
207 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
208 pthread_cond_init(&condition, &attr);
209 pthread_mutex_init(&mutex, NULL);
210 }
211
~Signal()212 ~Signal() {
213 pthread_cond_destroy(&condition);
214 pthread_mutex_destroy(&mutex);
215 }
216
signal()217 void signal() {
218 pthread_mutex_lock(&mutex);
219 signalled = true;
220 pthread_cond_signal(&condition);
221 pthread_mutex_unlock(&mutex);
222 }
223
wait(uint64_t timeout_nsec)224 int wait(uint64_t timeout_nsec) {
225 struct timespec ts;
226
227 pthread_mutex_lock(&mutex);
228 if (signalled) {
229 signalled = false;
230 pthread_mutex_unlock(&mutex);
231 return 0;
232 }
233 clock_gettime(CLOCK_MONOTONIC, &ts);
234 ts.tv_sec += timeout_nsec / 1000000000;
235 ts.tv_nsec += timeout_nsec % 1000000000;
236 if (ts.tv_nsec >= 1000000000) {
237 ts.tv_nsec -= 1000000000;
238 ts.tv_sec += 1;
239 }
240 int ret = pthread_cond_timedwait(&condition, &mutex, &ts);
241 //as the mutex lock is released inside timedwait first
242 //the singalled variant maybe changed by the main thread in some rare cases
243 //meanwhile still returns wait time out
244 //need to double check it and return 0 to process the last cmd/event during time out
245 if (signalled)
246 ret = 0;
247 signalled = false;
248 pthread_mutex_unlock(&mutex);
249 return ret;
250 }
251 };
252
253 #ifdef _ANDROID_
254 #define ATRACE_TAG ATRACE_TAG_VIDEO
255 #include <cutils/trace.h>
256 #include <utils/Trace.h>
257
258 class AutoTracer {
259 int mPrio;
260 public:
AutoTracer(int prio,const char * msg)261 AutoTracer(int prio, const char* msg)
262 : mPrio(prio) {
263 if (debug_level & prio) {
264 ATRACE_BEGIN(msg);
265 }
266 }
~AutoTracer()267 ~AutoTracer() {
268 if (debug_level & mPrio) {
269 ATRACE_END();
270 }
271 }
272 };
273
274 struct __attribute__((packed)) IvfFileHeader {
275 uint8_t signature[4];
276 uint16_t version;
277 uint16_t size;
278 uint8_t fourCC[4];
279 uint16_t width;
280 uint16_t height;
281 uint32_t rate;
282 uint32_t scale;
283 uint32_t frameCount;
284 uint32_t unused;
285
286 IvfFileHeader();
287 IvfFileHeader(bool isVp9, int width, int height,
288 int rate, int scale, int nFrameCount);
289 };
290
291 struct __attribute__((packed)) IvfFrameHeader {
292 uint32_t filledLen;
293 uint64_t timeStamp;
294
295 IvfFrameHeader();
296 IvfFrameHeader(uint32_t size, uint64_t timeStamp);
297 };
298
299 #define VIDC_TRACE_NAME_LOW(_name) AutoTracer _tracer(PRIO_TRACE_LOW, _name);
300 #define VIDC_TRACE_NAME_HIGH(_name) AutoTracer _tracer(PRIO_TRACE_HIGH, _name);
301
302 #define VIDC_TRACE_INT_LOW(_name, _int) \
303 if (debug_level & PRIO_TRACE_LOW) { \
304 ATRACE_INT(_name, _int); \
305 }
306
307 #define VIDC_TRACE_INT_HIGH(_name, _int) \
308 if (debug_level & PRIO_TRACE_HIGH) { \
309 ATRACE_INT(_name, _int); \
310 }
311
312 #else // _ANDROID_
313
314 #define VIDC_TRACE_NAME_LOW(_name)
315 #define VIDC_TRACE_NAME_HIGH(_name)
316 #define VIDC_TRACE_INT_LOW(_name, _int)
317 #define VIDC_TRACE_INT_HIGH(_name, _int)
318
319 #endif // !_ANDROID_
320
321 #endif
322