1/*--------------------------------------------------------------------------
2Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED 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
61static unsigned char H264_mask_code[4] = {0xFF,0xFF,0xFF,0xFF};
62static unsigned char H264_start_code[4] = {0x00,0x00,0x00,0x01};
63
64static unsigned char MPEG4_start_code[4] = {0x00,0x00,0x01,0xB6};
65static unsigned char MPEG4_mask_code[4] = {0xFF,0xFF,0xFF,0xFF};
66
67static unsigned char H263_start_code[4] = {0x00,0x00,0x80,0x00};
68static unsigned char H263_mask_code[4] = {0xFF,0xFF,0xFC,0x00};
69
70static unsigned char VC1_AP_start_code[4] = {0x00,0x00,0x01,0x0C};
71static unsigned char VC1_AP_mask_code[4] = {0xFF,0xFF,0xFF,0xFC};
72
73static unsigned char MPEG2_start_code[4] = {0x00, 0x00, 0x01, 0x00};
74static unsigned char MPEG2_mask_code[4] = {0xFF, 0xFF, 0xFF, 0xFF};
75
76frame_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
90frame_parse::~frame_parse ()
91{
92    if (mutils)
93        delete mutils;
94
95    mutils = NULL;
96}
97
98int 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
133int 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
144int 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
520int 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
616void 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
626void 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
653void 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
666void 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