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