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