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