1 /*
2 * Copyright (c) 2014 Intel Corporation. All rights reserved.
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 #ifndef LOG_DUMP_HELPER_INCLUDED
18 #define LOG_DUMP_HELPER_INCLUDED
19
20 #ifndef LOG_TAG
21 #error "Before including this file, must #define LOG_TAG and #include <utils/Log.h>"
22 #endif
23
24 #if LOG_NDEBUG == 0
25
26 // We have dump routines for the structures defined in the following files:
27 #include "VideoFrameInfo.h"
28 #include "ProtectedDataBuffer.h"
29
30 // The following helps to use these dump routines from command line unit tests:
31 #ifdef ANDROID
32 #define DUMP_EOL ""
33 #else
34 #define LOGV printf
35 #define LOGE printf
36 #define DUMP_EOL "\n"
37 #endif // ANDROID
38
39 #ifndef log_helper_min
40 #define log_helper_min(a,b) ((a) < (b) ? (a) : (b))
41 #endif // log_helper_min
42
Copy4Bytes(void * dst,const void * src)43 static inline void Copy4Bytes(void* dst, const void* src)
44 {
45 // Don't check input pointers for NULL: this is internal function,
46 // and if you pass NULL to it, your code deserves to crash.
47
48 uint8_t* bdst = (uint8_t*) dst ;
49 const uint8_t* bsrc = (const uint8_t*) src ;
50
51 *bdst++ = *bsrc++ ;
52 *bdst++ = *bsrc++ ;
53 *bdst++ = *bsrc++ ;
54 *bdst = *bsrc ;
55 }
56 // End of Copy4Bytes()
57
DumpBufferToString(char * str,uint32_t strSize,const uint8_t * start,uint32_t size)58 static void DumpBufferToString(char* str, uint32_t strSize, const uint8_t* start, uint32_t size)
59 {
60 if (str == NULL || strSize == 0 || start == NULL || size == 0)
61 {
62 LOGV("Error: invalid parameters to %s", __FUNCTION__) ;
63 return ;
64 }
65
66 char* s = str ;
67 char* send = str + strSize ;
68
69 const uint8_t* byte = start ;
70 const uint8_t* end = start + size ;
71
72 while (byte < end && s < send)
73 {
74 s += snprintf(s, strSize - (s - str), "%02x ", *byte) ;
75 ++byte ;
76 }
77 }
78 // End of DumpBufferToString()
79
DumpNaluDataBuffer(uint32_t nalu,const uint8_t * start,uint32_t size)80 static void DumpNaluDataBuffer(uint32_t nalu, const uint8_t* start, uint32_t size)
81 {
82 if (start == NULL || size == 0)
83 {
84 LOGV("NALU-dump: error: invalid parameters to %s", __FUNCTION__) ;
85 return ;
86 }
87
88 const uint32_t STR_SIZE = 1024 ;
89 char str[STR_SIZE] = {0} ;
90
91 DumpBufferToString(str, STR_SIZE, start, size) ;
92
93 LOGV("NALU-dump(nalu %u): data: %s" DUMP_EOL, nalu, str) ;
94 }
95 // End of DumpNaluDataBuffer()
96
DumpBuffer(const char * prefix,const uint8_t * start,uint32_t size)97 static void DumpBuffer(const char* prefix, const uint8_t* start, uint32_t size)
98 {
99 if (start == NULL || size == 0)
100 {
101 LOGV("Error: invalid parameters to %s", __FUNCTION__) ;
102 return ;
103 }
104
105 if (prefix == NULL)
106 {
107 prefix = "" ;
108 }
109
110 const uint32_t STR_SIZE = 1024 ;
111 char str[STR_SIZE] = {0} ;
112
113 DumpBufferToString(str, STR_SIZE, start, size) ;
114
115 LOGV("%s: ptr=%p, size=%u, data=%s" DUMP_EOL, prefix, start, size, str) ;
116 }
117 // End of DumpBuffer()
118
DumpNaluHeaderBuffer(const uint8_t * const start,uint32_t size)119 static void DumpNaluHeaderBuffer(const uint8_t* const start, uint32_t size)
120 {
121 if (start == NULL || size == 0)
122 {
123 LOGV("Error: invalid parameters to %s", __FUNCTION__) ;
124 return ;
125 }
126
127 const uint8_t* current = start ;
128
129 uint32_t numNALUs = 0 ;
130 Copy4Bytes(&numNALUs, current) ;
131 current += sizeof(numNALUs) ;
132
133 LOGV("NALU-dump: num NALUs = %u\n", numNALUs) ;
134
135 if (numNALUs > MAX_NALUS_IN_FRAME)
136 {
137 LOGE("NALU-dump: ERROR, num NALUs is too big (%u)" DUMP_EOL, numNALUs) ;
138 }
139
140 for (uint32_t nalu = 0; nalu < numNALUs; ++nalu)
141 {
142 uint32_t imr_offset = 0 ;
143 Copy4Bytes(&imr_offset, current) ;
144 current += sizeof(imr_offset) ;
145
146 uint32_t nalu_size = 0 ;
147 Copy4Bytes(&nalu_size, current) ;
148 current += sizeof(nalu_size) ;
149
150 uint32_t data_size = 0 ;
151 Copy4Bytes(&data_size, current) ;
152 current += sizeof(data_size) ;
153
154 LOGV("NALU-dump(nalu %u): imr_offset = %u, nalu_size = %u, data_size = %u" DUMP_EOL,
155 nalu, imr_offset, nalu_size, data_size) ;
156
157 DumpNaluDataBuffer(nalu, current, data_size) ;
158
159 // Skip past the data
160 current += data_size ;
161 }
162 // End of for
163 }
164 // End of DumpNaluHeaderBuffer()
165
DrmSchemeToString(uint32_t drmScheme)166 static const char* DrmSchemeToString(uint32_t drmScheme)
167 {
168 switch(drmScheme)
169 {
170 case DRM_SCHEME_NONE:
171 return "None" ;
172
173 case DRM_SCHEME_WV_CLASSIC:
174 return "WV Classic" ;
175
176 case DRM_SCHEME_WV_MODULAR:
177 return "WV Modular" ;
178
179 #ifdef DRM_SCHEME_MCAST_SINK
180 case DRM_SCHEME_MCAST_SINK:
181 return "MCast Sink" ;
182 #endif
183
184 #ifdef DRM_SCHEME_PLAYREADY_ASF
185 case DRM_SCHEME_PLAYREADY_ASF:
186 return "PlayReady/ASF" ;
187 #endif
188
189 default:
190 return "unknown" ;
191 }
192 }
193 // End of DrmSchemeToString()
194
DumpBuffer2(const char * prefix,const uint8_t * start,uint32_t size)195 static void DumpBuffer2(const char* prefix, const uint8_t* start, uint32_t size)
196 {
197 if (start == NULL || size == 0)
198 {
199 LOGV("Error: invalid parameters to %s", __FUNCTION__) ;
200 return ;
201 }
202
203 if (prefix == NULL)
204 {
205 prefix = "" ;
206 }
207
208 const uint32_t STR_SIZE = 1024 ;
209 char str[STR_SIZE] = {0} ;
210
211 DumpBufferToString(str, STR_SIZE, start, size) ;
212
213 LOGV("%s%s" DUMP_EOL, prefix, str) ;
214 }
215 // End of DumpBuffer2()
216
DumpProtectedDataBuffer(const char * prefix,ProtectedDataBuffer * buf)217 static void DumpProtectedDataBuffer(const char* prefix, ProtectedDataBuffer* buf)
218 {
219 if (buf == NULL)
220 {
221 LOGV("Error: invalid parameters to %s", __FUNCTION__) ;
222 return ;
223 }
224
225 if (prefix == NULL) { prefix = "" ; }
226
227 const uint32_t MAX_BUFFER_DUMP_LENGTH = 32 ;
228
229 if (buf->magic != PROTECTED_DATA_BUFFER_MAGIC)
230 {
231 const uint8_t* p = (uint8_t*) &buf->magic ;
232 LOGV("%sWrong magic: %02x %02x %02x %02x" DUMP_EOL, prefix, p[0], p[1], p[2], p[3]) ;
233 return ;
234 }
235
236 LOGV("%smagic: ok, drmScheme: %u (%s), clear: %u, size: %u, num PES: %u" DUMP_EOL, prefix,
237 buf->drmScheme, DrmSchemeToString(buf->drmScheme), buf->clear, buf->size, buf->numPesBuffers) ;
238
239 if (buf->numPesBuffers == 0)
240 {
241 uint32_t dumpLength = log_helper_min(buf->size, MAX_BUFFER_DUMP_LENGTH) ;
242 DumpBuffer2("data: ", buf->data, dumpLength) ;
243 }
244 else
245 {
246 for (uint32_t i = 0; i < buf->numPesBuffers; ++i)
247 {
248 const uint32_t STR_SIZE = 1024 ;
249 char str[STR_SIZE] = {0} ;
250
251 uint32_t dumpLength = log_helper_min(buf->pesBuffers[i].pesSize, MAX_BUFFER_DUMP_LENGTH) ;
252
253 DumpBufferToString(str, STR_SIZE,
254 buf->data + buf->pesBuffers[i].pesDataOffset, dumpLength) ;
255
256 LOGV("PES %u: streamCounter: %u, inputCounter: %llu, offset: %u, size: %u, PES data: %s" DUMP_EOL,
257 i, buf->pesBuffers[i].streamCounter, buf->pesBuffers[i].inputCounter,
258 buf->pesBuffers[i].pesDataOffset, buf->pesBuffers[i].pesSize, str) ;
259 }
260 }
261 }
262 // End of DumpProtectedDataBuffer
263
DumpVideoFrameInfo(frame_info_t * fInfo)264 static void DumpVideoFrameInfo(frame_info_t* fInfo)
265 {
266 if (fInfo == NULL)
267 {
268 LOGV("Error: invalid parameters to %s", __FUNCTION__) ;
269 return ;
270 }
271
272 LOGV("frame_info_t: data = %p, size = %u, num_nalus = %u", fInfo->data, fInfo->size, fInfo->num_nalus) ;
273
274 for (uint32_t i = 0; i < fInfo->num_nalus; ++i)
275 {
276 LOGV("nalu_info_t: type = %#x, offset = %u (%#x), data = %p, length = %u",
277 fInfo->nalus[i].type, fInfo->nalus[i].offset, fInfo->nalus[i].offset,
278 fInfo->nalus[i].data, fInfo->nalus[i].length) ;
279
280 if (fInfo->nalus[i].data != NULL && fInfo->nalus[i].length > 0)
281 {
282 DumpBuffer2("nalu_info_t::data: ", fInfo->nalus[i].data, fInfo->nalus[i].length) ;
283 }
284 }
285 }
286 // End of DumpVideoFrameInfo()
287
288 #else
289
290 // Avoid #ifdef around the dump code
291
292 #define DumpBuffer(...)
293 #define DumpBuffer2(...)
294 #define DumpNaluHeaderBuffer(...)
295 #define DumpProtectedDataBuffer(...)
296 #define DumpVideoFrameInfo(...)
297
298 #define DUMP_EOL
299
300 #endif // LOG_NDEBUG == 0
301
302 #endif // LOG_DUMP_HELPER_INCLUDED
303