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