1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010 - 2013, 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 #include <stdio.h>
29 #include <stddef.h>
30 #include <stdlib.h>
31 #include <fcntl.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <unistd.h>
36 #include <pthread.h>
37 #include <ctype.h>
38 #include <sys/stat.h>
39 #include <sys/ioctl.h>
40 #include <sys/mman.h>
41 #include <sys/time.h>
42 #include <sys/poll.h>
43 #include <stdint.h>
44
45 #include "frameparser.h"
46 //#include "omx_vdec.h"
47
48 #ifdef _ANDROID_
49 extern "C" {
50 #include<utils/Log.h>
51 }
52 #endif//_ANDROID_
53
54 #undef DEBUG_PRINT_LOW
55 #undef DEBUG_PRINT_HIGH
56 #undef DEBUG_PRINT_ERROR
57
58 #define DEBUG_PRINT_LOW ALOGV
59 #define DEBUG_PRINT_HIGH ALOGV
60 #define DEBUG_PRINT_ERROR ALOGE
61
62 static unsigned char H264_mask_code[4] = {0xFF,0xFF,0xFF,0xFF};
63 static unsigned char H264_start_code[4] = {0x00,0x00,0x00,0x01};
64
65 static unsigned char MPEG4_start_code[4] = {0x00,0x00,0x01,0xB6};
66 static unsigned char MPEG4_mask_code[4] = {0xFF,0xFF,0xFF,0xFF};
67
68 static unsigned char H263_start_code[4] = {0x00,0x00,0x80,0x00};
69 static unsigned char H263_mask_code[4] = {0xFF,0xFF,0xFC,0x00};
70
71 static unsigned char VC1_AP_start_code[4] = {0x00,0x00,0x01,0x0C};
72 static unsigned char VC1_AP_mask_code[4] = {0xFF,0xFF,0xFF,0xFC};
73
74 static unsigned char MPEG2_start_code[4] = {0x00, 0x00, 0x01, 0x00};
75 static unsigned char MPEG2_mask_code[4] = {0xFF, 0xFF, 0xFF, 0xFF};
76
frame_parse()77 frame_parse::frame_parse():mutils(NULL),
78 parse_state(A0),
79 start_code(NULL),
80 mask_code(NULL),
81 last_byte_h263(0),
82 last_byte(0),
83 header_found(false),
84 skip_frame_boundary(false),
85 state_nal(NAL_LENGTH_ACC),
86 nal_length(0),
87 accum_length(0),
88 bytes_tobeparsed(0)
89 {
90 }
91
~frame_parse()92 frame_parse::~frame_parse ()
93 {
94 if (mutils)
95 delete mutils;
96
97 mutils = NULL;
98 }
99
init_start_codes(codec_type codec_type_parse)100 int frame_parse::init_start_codes (codec_type codec_type_parse)
101 {
102 /*Check if Codec Type is proper and we are in proper state*/
103 if (codec_type_parse > CODEC_TYPE_MAX || parse_state != A0) {
104 return -1;
105 }
106
107 switch (codec_type_parse) {
108 case CODEC_TYPE_MPEG4:
109 start_code = MPEG4_start_code;
110 mask_code = MPEG4_mask_code;
111 break;
112 case CODEC_TYPE_H263:
113 start_code = H263_start_code;
114 mask_code = H263_mask_code;
115 break;
116 case CODEC_TYPE_H264:
117 case CODEC_TYPE_HEVC:
118 start_code = H264_start_code;
119 mask_code = H264_mask_code;
120 break;
121 case CODEC_TYPE_VC1:
122 start_code = VC1_AP_start_code;
123 mask_code = VC1_AP_mask_code;
124 break;
125 case CODEC_TYPE_MPEG2:
126 start_code = MPEG2_start_code;
127 mask_code = MPEG2_mask_code;
128 break;
129 #ifdef _MSM8974_
130 case CODEC_TYPE_VP8:
131 break;
132 #endif
133 default:
134 return -1;
135 }
136
137 return 1;
138 }
139
140
init_nal_length(unsigned int nal_len)141 int frame_parse::init_nal_length (unsigned int nal_len)
142 {
143 if (nal_len == 0 || nal_len > 4 || state_nal != NAL_LENGTH_ACC) {
144 return -1;
145 }
146
147 nal_length = nal_len;
148
149 return 1;
150 }
151
parse_sc_frame(OMX_BUFFERHEADERTYPE * source,OMX_BUFFERHEADERTYPE * dest,OMX_U32 * partialframe)152 int frame_parse::parse_sc_frame ( OMX_BUFFERHEADERTYPE *source,
153 OMX_BUFFERHEADERTYPE *dest ,
154 OMX_U32 *partialframe)
155 {
156 OMX_U8 *pdest = NULL,*psource = NULL, match_found = FALSE, is_byte_match = 0;
157 OMX_U32 dest_len =0, source_len = 0, temp_len = 0;
158 OMX_U32 parsed_length = 0,i=0;
159 int residue_byte = 0;
160
161 if (source == NULL || dest == NULL || partialframe == NULL) {
162 return -1;
163 }
164
165 /*Calculate how many bytes are left in source and destination*/
166 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset);
167 psource = source->pBuffer + source->nOffset;
168 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset);
169 source_len = source->nFilledLen;
170
171 /*Need Minimum Start Code size for destination to copy atleast Start code*/
172 if ((start_code == H263_start_code && dest_len < 3) ||
173 (start_code != H263_start_code && dest_len < 4) || (source_len == 0)) {
174 DEBUG_PRINT_LOW("\n FrameParser: dest_len %d source_len %d",dest_len,source_len);
175
176 if (source_len == 0 && (source->nFlags & 0x01)) {
177 DEBUG_PRINT_LOW("\n FrameParser: EOS rxd!! Notify it as a complete frame");
178 *partialframe = 0;
179 return 1;
180 }
181
182 DEBUG_PRINT_LOW("\n FrameParser: Bitstream Parsing error");
183 return -1;
184 }
185
186 /*Check if State of the previous find is a Start code*/
187 if (parse_state == A4 || parse_state == A5) {
188 /*Check for minimun size should be 4*/
189 dest->nFlags = source->nFlags;
190 dest->nTimeStamp = source->nTimeStamp;
191
192 if (start_code == H263_start_code) {
193 memcpy (pdest,start_code,2);
194 pdest[2] = last_byte_h263;
195 dest->nFilledLen += 3;
196 pdest += 3;
197 } else {
198 memcpy (pdest,start_code,4);
199
200 if (start_code == VC1_AP_start_code
201 || start_code == MPEG4_start_code
202 || start_code == MPEG2_start_code) {
203 pdest[3] = last_byte;
204 update_skip_frame();
205 }
206
207 dest->nFilledLen += 4;
208 pdest += 4;
209 }
210
211 parse_state = A0;
212 }
213
214 /*Entry State Machine*/
215 while ( source->nFilledLen > 0 && parse_state != A0
216 && parse_state != A4 && parse_state != A5 && dest_len > 0
217 ) {
218 //printf ("\n In the Entry Loop");
219 switch (parse_state) {
220 case A3:
221 parse_additional_start_code(psource,&parsed_length);
222
223 if (parse_state == A4) {
224 source->nFilledLen--;
225 source->nOffset++;
226 psource++;
227 break;
228 }
229
230 /*If fourth Byte is matching then start code is found*/
231 if ((*psource & mask_code [3]) == start_code [3]) {
232 parse_state = A4;
233 last_byte = *psource;
234 source->nFilledLen--;
235 source->nOffset++;
236 psource++;
237 } else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) {
238 parse_state = A2;
239 memcpy (pdest,start_code,1);
240 pdest++;
241 dest->nFilledLen++;
242 dest_len--;
243 } else if (start_code [2] == start_code [0]) {
244 parse_state = A1;
245 memcpy (pdest,start_code,2);
246 pdest += 2;
247 dest->nFilledLen += 2;
248 dest_len -= 2;
249 } else {
250 parse_state = A0;
251 memcpy (pdest,start_code,3);
252 pdest += 3;
253 dest->nFilledLen +=3;
254 dest_len -= 3;
255 }
256
257 break;
258
259 case A2:
260 is_byte_match = ((*psource & mask_code [2]) == start_code [2]);
261 match_found = FALSE;
262
263 if (start_code == H263_start_code) {
264 if (is_byte_match) {
265 last_byte_h263 = *psource;
266 parse_state = A5;
267 match_found = TRUE;
268 }
269 } else if (start_code == H264_start_code &&
270 (*psource & mask_code [3]) == start_code [3]) {
271 parse_state = A5;
272 match_found = TRUE;
273 } else {
274 if (is_byte_match) {
275 parse_state = A3;
276 match_found = TRUE;
277 }
278 }
279
280 if (match_found) {
281 source->nFilledLen--;
282 source->nOffset++;
283 psource++;
284 } else if (start_code [1] == start_code [0]) {
285 parse_state = A1;
286 memcpy (pdest,start_code,1);
287 dest->nFilledLen +=1;
288 dest_len--;
289 pdest++;
290 } else {
291 parse_state = A0;
292 memcpy (pdest,start_code,2);
293 dest->nFilledLen +=2;
294 dest_len -= 2;
295 pdest += 2;
296 }
297
298 break;
299
300 case A1:
301
302 if ((*psource & mask_code [1]) == start_code [1]) {
303 parse_state = A2;
304 source->nFilledLen--;
305 source->nOffset++;
306 psource++;
307 } else {
308 memcpy (pdest,start_code,1);
309 dest->nFilledLen +=1;
310 pdest++;
311 dest_len--;
312 parse_state = A0;
313 }
314
315 break;
316 case A4:
317 case A0:
318 case A5:
319 break;
320 }
321
322 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset);
323 }
324
325 if (parse_state == A4 || parse_state == A5) {
326 *partialframe = 0;
327 check_skip_frame_boundary(partialframe);
328 DEBUG_PRINT_LOW("\n FrameParser: Parsed Len = %d", dest->nFilledLen);
329 return 1;
330 }
331
332 /*Partial Frame is true*/
333 *partialframe = 1;
334
335 /*Calculate how many bytes are left in source and destination*/
336 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset);
337 psource = source->pBuffer + source->nOffset;
338 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset);
339 source_len = source->nFilledLen;
340
341 temp_len = (source_len < dest_len)?source_len:dest_len;
342
343 /*Check if entry state machine consumed source or destination*/
344 if (temp_len == 0) {
345 return 1;
346 }
347
348 /*Parsing State Machine*/
349 while (parsed_length < temp_len) {
350 switch (parse_state) {
351 case A0:
352
353 if ((psource [parsed_length] & mask_code [0]) == start_code[0]) {
354 parse_state = A1;
355 }
356
357 parsed_length++;
358 break;
359 case A1:
360
361 if ((psource [parsed_length] & mask_code [1]) == start_code [1]) {
362 parsed_length++;
363 parse_state = A2;
364 } else {
365 parse_state = A0;
366 }
367
368 break;
369 case A2:
370 is_byte_match = ((psource[parsed_length] & mask_code [2]) == start_code [2]);
371 match_found = FALSE;
372
373 if (start_code == H263_start_code) {
374 if (is_byte_match) {
375 last_byte_h263 = psource[parsed_length];
376 parse_state = A5;
377 match_found = TRUE;
378 }
379 } else if (start_code == H264_start_code &&
380 (psource[parsed_length] & mask_code [3]) == start_code [3]) {
381 parse_state = A5;
382 match_found = TRUE;
383 } else {
384 if (is_byte_match) {
385 parse_state = A3;
386 match_found = TRUE;
387 }
388 }
389
390 if (match_found) {
391 parsed_length++;
392 } else if (start_code [1] == start_code [0]) {
393 parse_state = A1;
394 } else {
395 parse_state = A0;
396 }
397
398 break;
399 case A3:
400 parse_additional_start_code(psource,&parsed_length);
401
402 if (parse_state == A4) break;
403
404 if ((psource [parsed_length] & mask_code [3]) == start_code [3]) {
405 last_byte = psource [parsed_length];
406 parsed_length++;
407 parse_state = A4;
408 } else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) {
409 parse_state = A2;
410 } else if (start_code [2] == start_code [0]) {
411 parse_state = A1;
412 } else {
413 parse_state = A0;
414 }
415
416 break;
417 case A4:
418 case A5:
419 break;
420 }
421
422 /*Found the code break*/
423 if (parse_state == A4 || parse_state == A5) {
424 break;
425 }
426 }
427
428 /*Exit State Machine*/
429 psource = source->pBuffer + source->nOffset;
430 int bytes_to_skip = 0;
431 switch (parse_state) {
432 case A5:
433 *partialframe = 0;
434 check_skip_frame_boundary(partialframe);
435 bytes_to_skip = 3;
436 break;
437 case A4:
438 *partialframe = 0;
439 check_skip_frame_boundary(partialframe);
440 bytes_to_skip = 4;
441 break;
442 case A3:
443 if (source->nFlags & OMX_BUFFERFLAG_EOS) {
444 bytes_to_skip = 0;
445 } else {
446 bytes_to_skip = 3;
447 }
448 break;
449 case A2:
450 if (source->nFlags & OMX_BUFFERFLAG_EOS) {
451 bytes_to_skip = 0;
452 } else {
453 bytes_to_skip = 2;
454 }
455 break;
456 case A1:
457 if (source->nFlags & OMX_BUFFERFLAG_EOS) {
458 bytes_to_skip = 0;
459 } else {
460 bytes_to_skip = 1;
461 }
462 break;
463 case A0:
464 bytes_to_skip = 0;
465 break;
466 }
467
468 if (source->nFilledLen < parsed_length) {
469 printf ("\n FATAL Error");
470 return -1;
471 }
472
473 if (parsed_length > bytes_to_skip) {
474 memcpy (pdest, psource, (parsed_length-bytes_to_skip));
475 dest->nFilledLen += (parsed_length-bytes_to_skip);
476 }
477
478 source->nFilledLen -= parsed_length;
479 source->nOffset += parsed_length;
480
481 return 1;
482 }
483
484
parse_h264_nallength(OMX_BUFFERHEADERTYPE * source,OMX_BUFFERHEADERTYPE * dest,OMX_U32 * partialframe)485 int frame_parse::parse_h264_nallength (OMX_BUFFERHEADERTYPE *source,
486 OMX_BUFFERHEADERTYPE *dest ,
487 OMX_U32 *partialframe)
488 {
489 OMX_U8 *pdest = NULL,*psource = NULL;
490 OMX_U32 dest_len =0, source_len = 0, temp_len = 0,parsed_length = 0;
491
492 if (source == NULL || dest == NULL || partialframe == NULL) {
493 return -1;
494 }
495
496 /*Calculate the length's*/
497 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset);
498 source_len = source->nFilledLen;
499
500 if (dest_len < 4 || source_len == 0 || nal_length == 0) {
501 DEBUG_PRINT_LOW("\n FrameParser: NAL Parsing Error! dest_len %d "
502 "source_len %d nal_length %d", dest_len, source_len, nal_length);
503 return -1;
504 }
505
506 *partialframe = 1;
507 temp_len = (source_len < dest_len)?source_len:dest_len;
508 psource = source->pBuffer + source->nOffset;
509 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset);
510
511 /* Find the Bytes to Accumalte*/
512 if (state_nal == NAL_LENGTH_ACC) {
513 while (parsed_length < temp_len ) {
514 bytes_tobeparsed |= (((OMX_U32)(*psource))) << (((nal_length-accum_length-1) << 3));
515
516 /*COPY THE DATA FOR C-SIM TO BE REOMVED ON TARGET*/
517 //*pdest = *psource;
518 accum_length++;
519 source->nFilledLen--;
520 source->nOffset++;
521 psource++;
522 //dest->nFilledLen++;
523 //pdest++;
524 parsed_length++;
525
526 if (accum_length == nal_length) {
527 accum_length = 0;
528 state_nal = NAL_PARSING;
529 memcpy (pdest,H264_start_code,4);
530 dest->nFilledLen += 4;
531 break;
532 }
533 }
534 }
535
536 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset);
537 source_len = source->nFilledLen;
538 temp_len = (source_len < dest_len)?source_len:dest_len;
539
540 psource = source->pBuffer + source->nOffset;
541 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset);
542
543 dest->nTimeStamp = source->nTimeStamp;
544 dest->nFlags = source->nFlags;
545
546 /*Already in Parsing state go ahead and copy*/
547 if (state_nal == NAL_PARSING && temp_len > 0) {
548 if (temp_len < bytes_tobeparsed) {
549 memcpy (pdest,psource,temp_len);
550 dest->nFilledLen += temp_len;
551 source->nOffset += temp_len;
552 source->nFilledLen -= temp_len;
553 bytes_tobeparsed -= temp_len;
554 } else {
555 memcpy (pdest,psource,bytes_tobeparsed);
556 temp_len -= bytes_tobeparsed;
557 dest->nFilledLen += bytes_tobeparsed;
558 source->nOffset += bytes_tobeparsed;
559 source->nFilledLen -= bytes_tobeparsed;
560 bytes_tobeparsed = 0;
561 }
562 }
563
564 if (bytes_tobeparsed == 0 && state_nal == NAL_PARSING) {
565 *partialframe = 0;
566 state_nal = NAL_LENGTH_ACC;
567 }
568
569 return 1;
570 }
571
flush()572 void frame_parse::flush ()
573 {
574 parse_state = A0;
575 state_nal = NAL_LENGTH_ACC;
576 accum_length = 0;
577 bytes_tobeparsed = 0;
578 header_found = false;
579 skip_frame_boundary = false;
580 }
581
parse_additional_start_code(OMX_U8 * psource,OMX_U32 * parsed_length)582 void frame_parse::parse_additional_start_code(OMX_U8 *psource,
583 OMX_U32 *parsed_length)
584 {
585
586 if (((start_code == MPEG4_start_code) ||
587 (start_code == MPEG2_start_code)) &&
588 psource &&
589 parsed_length) {
590 OMX_U32 index = *parsed_length;
591
592 if ((start_code == MPEG4_start_code &&
593 (psource [index] & 0xF0) == 0x20) ||
594 (start_code == MPEG2_start_code &&
595 psource [index] == 0xB3)) {
596 if (header_found) {
597 last_byte = psource [index];
598 index++;
599 parse_state = A4;
600 } else
601 header_found = true;
602 }
603
604 *parsed_length = index;
605 }
606 }
607
check_skip_frame_boundary(OMX_U32 * partialframe)608 void frame_parse::check_skip_frame_boundary(OMX_U32 *partialframe)
609 {
610 if ((start_code == MPEG4_start_code ||
611 start_code == MPEG2_start_code) &&
612 partialframe) {
613
614 *partialframe = 1;
615
616 if (!skip_frame_boundary)
617 *partialframe = 0;
618
619 skip_frame_boundary = false;
620 }
621 }
622
update_skip_frame()623 void frame_parse::update_skip_frame()
624 {
625 if (((start_code == MPEG4_start_code) &&
626 ((last_byte & 0xF0) == 0x20)) ||
627 ((start_code == MPEG2_start_code) &&
628 (last_byte == 0xB3))) {
629
630 skip_frame_boundary = true;
631 }
632 }
633