xref: /utopia/UTPA2-700.0.x/modules/mfe/drv/mfe_ex/cModel/vlc.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 
79 
80 
81 #include "MFE_chip.h"
82 #include "mfe_type.h"
83 #include "mfe_common.h"
84 #include "ms_dprintf.h"
85 
86 #include "vlc.h"
87 #include "nalucommon.h"
88 
89 #include <stdio.h>
90 #include <string.h>
91 
92 
93 //Start code and Emulation Prevention need this to be defined in identical manner at encoder and decoder
94 #define ZEROBYTES_SHORTSTARTCODE 2UL //indicates the number of zero bytes in the short start-code prefix
95 
96 
97 
98 
99 
iabs(MS_S32 x)100 static __inline MS_S32 iabs(MS_S32 x)
101 {
102     return ((x) < 0) ? -(x) : (x);
103 }
104 
105 
106 /*!
107 ************************************************************************
108 * \brief
109 *    Converts String Of Data Bits (SODB) to Raw Byte Sequence
110 *    Packet (RBSP)
111 * \param currStream
112 *        Bitstream which contains data bits.
113 * \return None
114 * \note currStream is byte-aligned at the end of this function
115 *
116 ************************************************************************
117 */
118 
SODBtoRBSP(Bitstream * currStream)119 void SODBtoRBSP(Bitstream *currStream)
120 {
121     currStream->byte_buf <<= 1;
122     currStream->byte_buf |= 1;
123     currStream->bits_to_go--;
124     currStream->byte_buf <<= currStream->bits_to_go;
125     if (currStream->streamBuffer)
126         currStream->streamBuffer[currStream->byte_pos++] = currStream->byte_buf;
127     currStream->bits_to_go = 8;
128     currStream->byte_buf = 0;
129 }
130 
131 /*!
132 ************************************************************************
133 *  \brief
134 *     This function converts a RBSP payload to an EBSP payload
135 *
136 *  \param streamBuffer
137 *       pointer to data bits
138 *  \param begin_bytepos
139 *            The byte position after start-code, after which stuffing to
140 *            prevent start-code emulation begins.
141 *  \param end_bytepos
142 *           Size of streamBuffer in bytes.
143 *  \param min_num_bytes
144 *           Minimum number of bytes in payload. Should be 0 for VLC entropy
145 *           coding mode. Determines number of stuffed words for CABAC mode.
146 *  \return
147 *           Size of streamBuffer after stuffing.
148 *  \note
149 *      NAL_Payload_buffer is used as temporary buffer to store data.
150 *
151 *
152 ************************************************************************
153 */
154 
RBSPtoEBSP(MS_U8 * streamBuffer,MS_S32 begin_bytepos,MS_S32 end_bytepos,MS_S32 min_num_bytes)155 MS_S32 RBSPtoEBSP(MS_U8 *streamBuffer, MS_S32 begin_bytepos, MS_S32 end_bytepos, MS_S32 min_num_bytes)
156 {
157 
158     MS_S32 i, j, count;
159     MS_U8* NAL_Payload_buffer = NULL;
160 
161     NAL_Payload_buffer = (MS_U8*)malloc(MAXRBSPSIZE << 1);
162     if (NAL_Payload_buffer == NULL)
163     {
164         ms_dprintk(DRV_L4, "[RBSPtoEBSP] NAL_Payload_buffer is null!\n");
165         return -1;
166     }
167     memset(NAL_Payload_buffer, 0, MAXRBSPSIZE << 1);
168 
169     memcpy(&NAL_Payload_buffer[begin_bytepos],&streamBuffer[begin_bytepos], (end_bytepos - begin_bytepos) * sizeof(MS_U8));
170     count = 0;
171     j = begin_bytepos;
172     for(i = begin_bytepos; i < end_bytepos; i++)
173     {
174         if(count == ZEROBYTES_SHORTSTARTCODE && !(NAL_Payload_buffer[i] & 0xFC))
175         {
176             streamBuffer[j] = 0x03;
177             j++;
178             count = 0;
179         }
180         streamBuffer[j] = NAL_Payload_buffer[i];
181         if(NAL_Payload_buffer[i] == 0x00)
182             count++;
183         else
184             count = 0;
185         j++;
186     }
187 
188     for (i = 0; i< (min_num_bytes - end_bytepos); i+=3 )
189     {
190         streamBuffer[j]   = 0x00; // CABAC zero word
191         streamBuffer[j+1] = 0x00;
192         streamBuffer[j+2] = 0x03;
193         j += 3;
194     }
195 
196     free(NAL_Payload_buffer);
197     return j;
198 }
199 
200 /*!
201 *************************************************************************************
202 * \brief
203 *    Converts an RBSP to a NALU
204 *
205 * \param rbsp
206 *    byte buffer with the rbsp
207 * \param nalu
208 *    nalu structure to be filled
209 * \param rbsp_size
210 *    size of the rbsp in bytes
211 * \param nal_unit_type
212 *    as in JVT doc
213 * \param nal_reference_idc
214 *    as in JVT doc
215 * \param min_num_bytes
216 *    some incomprehensible CABAC stuff
217 * \param UseAnnexbLongStartcode
218 *    when 1 and when using AnnexB bytestreams, then use a long startcode prefix
219 *
220 * \return
221 *    length of the NALU in bytes
222 *************************************************************************************
223 */
224 
RBSPtoNALU(MS_U8 * rbsp,NALU_t * nalu,MS_S32 rbsp_size,MS_S32 nal_unit_type,MS_S32 nal_reference_idc,MS_S32 min_num_bytes,MS_S32 UseAnnexbLongStartcode)225 MS_S32 RBSPtoNALU (MS_U8 *rbsp, NALU_t *nalu, MS_S32 rbsp_size, MS_S32 nal_unit_type, MS_S32 nal_reference_idc,
226                 MS_S32 min_num_bytes, MS_S32 UseAnnexbLongStartcode)
227 {
228     MS_S32 len;
229 
230     MS_ASSERT (nalu != NULL);
231     if (nalu == NULL)
232     {
233         ms_dprintk(DRV_L4, "[RBSPtoNALU] n is null\n");
234         return -1;
235     }
236 
237     MS_ASSERT (nal_reference_idc <=3 && nal_reference_idc >=0);
238     MS_ASSERT (nal_unit_type > 0 && nal_unit_type <= 10);
239     MS_ASSERT (rbsp_size < MAXRBSPSIZE);
240 
241     nalu->startcodeprefix_len = UseAnnexbLongStartcode ? 4 : 3;
242     nalu->forbidden_bit       = 0;
243     nalu->nal_reference_idc   = (NalRefIdc) nal_reference_idc;
244     nalu->nal_unit_type       = (NaluType) nal_unit_type;
245     nalu->buf[0]              =
246         nalu->forbidden_bit << 7      |
247         nalu->nal_reference_idc << 5  |
248         nalu->nal_unit_type;
249 
250     memcpy (&nalu->buf[1], rbsp, rbsp_size);
251     // printf ("First Byte %x\n", nalu->buf[0]);
252     // printf ("RBSPtoNALU: Before: NALU len %d\t RBSP %x %x %x %x\n", rbsp_size, (MS_U32) nalu->buf[1], (MS_U32) nalu->buf[2], (MS_U32) nalu->buf[3], (MS_U32) nalu->buf[4]);
253 
254     len = 1 + RBSPtoEBSP (&nalu->buf[1], 0, rbsp_size, min_num_bytes);
255 
256     // printf ("RBSPtoNALU: After : NALU len %d\t EBSP %x %x %x %x\n", rbsp_size, (MS_U32) nalu->buf[1], (MS_U32) nalu->buf[2], (MS_U32) nalu->buf[3], (MS_U32) nalu->buf[4]);
257     // printf ("len %d\n\n", len);
258     nalu->len = len * 8;
259 
260     return len;
261 }
262 
263 /*!
264 ************************************************************************
265 * \brief
266 *    writes UVLC code to the appropriate buffer
267 ************************************************************************
268 */
writeUVLC2buffer(SyntaxElement * se,Bitstream * currStream)269 void  writeUVLC2buffer(SyntaxElement *se, Bitstream *currStream)
270 {
271     MS_U32 mask = 1 << (se->len - 1);
272     MS_S32 i;
273     //byte *streamBuffer = &currStream->streamBuffer[currStream->byte_pos];
274     //MS_ASSERT ((se->len-1) < 32);
275 
276     // Add the new bits to the bitstream.
277     // Write out a byte if it is full
278     for (i = 0; i < se->len; i++)
279     {
280         currStream->byte_buf <<= 1;
281 
282         if (se->bitpattern & mask)
283             currStream->byte_buf |= 1;
284 
285         mask >>= 1;
286 
287         if ((--currStream->bits_to_go) == 0)
288         {
289             if(currStream->zerocount == ZEROBYTES_SHORTSTARTCODE && !(currStream->byte_buf & 0xFC))
290             {
291                 //currStream->streamBuffer[currStream->byte_pos++] = 0x03;
292                 //img->prevention_byte++;
293                 currStream->zerocount = 0;
294             }
295             currStream->streamBuffer[currStream->byte_pos++] = currStream->byte_buf;
296             if(currStream->byte_buf == 0x00)
297                 currStream->zerocount++;
298             else
299                 currStream->zerocount = 0;
300 
301             currStream->bits_to_go = 8;
302             currStream->byte_buf = 0;
303         }
304     }
305 }
306 
307 /*!
308 ************************************************************************
309 * \brief
310 *    Makes code word and passes it back
311 *    A code word has the following format: 0 0 0 ... 1 Xn ...X2 X1 X0.
312 *
313 * \par Input:
314 *    Info   : Xn..X2 X1 X0                                             \n
315 *    Length : Total number of bits in the codeword
316 ************************************************************************
317 */
318 // NOTE this function is called with sym->inf > (1<<(sym->len/2)).  The upper bits of inf are junk
symbol2uvlc(SyntaxElement * sym)319 MS_S32 symbol2uvlc(SyntaxElement *sym)
320 {
321     MS_S32 suffix_len = sym->len >> 1;
322     MS_ASSERT (suffix_len<32);
323     sym->bitpattern = (1<<suffix_len)|(sym->inf & ((1<<suffix_len) - 1));
324     return 0;
325 }
326 
327 /*!
328 *************************************************************************************
329 * \brief
330 *    ue_v, writes an ue(v) syntax element, returns the length in bits
331 *
332 * \param tracestring
333 *    the string for the trace file
334 * \param value
335 *    the value to be coded
336 *  \param bitstream
337 *    the target bitstream the value should be coded into
338 *
339 * \return
340 *    Number of bits used by the coded syntax element
341 *
342 * \ note
343 *    This function writes always the bit buffer for the progressive scan flag, and
344 *    should not be used (or should be modified appropriately) for the interlace crap
345 *    When used in the context of the Parameter Sets, this is obviously not a
346 *    problem.
347 *
348 *************************************************************************************
349 */
ue_v(MS_S8 * tracestring,MS_S32 value,Bitstream * bitstream)350 MS_S32 ue_v (MS_S8 *tracestring, MS_S32 value, Bitstream *bitstream)
351 {
352     SyntaxElement symbol, *sym=&symbol;
353     sym->value1 = value;
354     sym->value2 = 0;
355 
356     MS_ASSERT (bitstream->streamBuffer != NULL);
357 
358     ue_linfo(sym->value1,sym->value2,&(sym->len),&(sym->inf));
359     symbol2uvlc(sym);
360 
361     writeUVLC2buffer (sym, bitstream);
362 
363 #if TRACE
364     strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
365     trace2out (sym);
366 #endif
367 
368     return (sym->len);
369 }
370 
371 /*!
372  *************************************************************************************
373  * \brief
374  *    se_v, writes an se(v) syntax element, returns the length in bits
375  *
376  * \param tracestring
377  *    the string for the trace file
378  * \param value
379  *    the value to be coded
380  *  \param bitstream
381  *    the target bitstream the value should be coded into
382  *
383  * \return
384  *    Number of bits used by the coded syntax element
385  *
386  * \ note
387  *    This function writes always the bit buffer for the progressive scan flag, and
388  *    should not be used (or should be modified appropriately) for the interlace crap
389  *    When used in the context of the Parameter Sets, this is obviously not a
390  *    problem.
391  *
392  *************************************************************************************
393  */
se_v(MS_S8 * tracestring,MS_S32 value,Bitstream * bitstream)394 MS_S32 se_v (MS_S8 *tracestring, MS_S32 value, Bitstream *bitstream)
395 {
396   SyntaxElement symbol, *sym=&symbol;
397   sym->value1 = value;
398   sym->value2 = 0;
399 
400   MS_ASSERT (bitstream->streamBuffer != NULL);
401 
402   se_linfo(sym->value1,sym->value2,&(sym->len),&(sym->inf));
403   symbol2uvlc(sym);
404 
405   writeUVLC2buffer (sym, bitstream);
406 
407 #if TRACE
408   strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
409   trace2out (sym);
410 #endif
411 
412   return (sym->len);
413 }
414 
415 
416 /*!
417  *************************************************************************************
418  * \brief
419  *    u_1, writes a flag (u(1) syntax element, returns the length in bits,
420  *    always 1
421  *
422  * \param tracestring
423  *    the string for the trace file
424  * \param value
425  *    the value to be coded
426  *  \param bitstream
427  *    the target bitstream the value should be coded into
428  *
429  * \return
430  *    Number of bits used by the coded syntax element (always 1)
431  *
432  * \ note
433  *    This function writes always the bit buffer for the progressive scan flag, and
434  *    should not be used (or should be modified appropriately) for the interlace crap
435  *    When used in the context of the Parameter Sets, this is obviously not a
436  *    problem.
437  *
438  *************************************************************************************
439  */
u_1(MS_S8 * tracestring,MS_S32 value,Bitstream * bitstream)440 MS_S32 u_1 (MS_S8 *tracestring, MS_S32 value, Bitstream *bitstream)
441 {
442   SyntaxElement symbol, *sym=&symbol;
443 
444   sym->bitpattern = value;
445   sym->len = 1;
446   sym->value1 = value;
447 
448   MS_ASSERT (bitstream->streamBuffer != NULL);
449 
450   writeUVLC2buffer(sym, bitstream);
451 
452 #if TRACE
453   strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
454   trace2out (sym);
455 #endif
456 
457   return (sym->len);
458 }
459 
460 
461 /*!
462  *************************************************************************************
463  * \brief
464  *    u_v, writes a n bit fixed length syntax element, returns the length in bits,
465  *
466  * \param n
467  *    length in bits
468  * \param tracestring
469  *    the string for the trace file
470  * \param value
471  *    the value to be coded
472  *  \param bitstream
473  *    the target bitstream the value should be coded into
474  *
475  * \return
476  *    Number of bits used by the coded syntax element
477  *
478  * \ note
479  *    This function writes always the bit buffer for the progressive scan flag, and
480  *    should not be used (or should be modified appropriately) for the interlace crap
481  *    When used in the context of the Parameter Sets, this is obviously not a
482  *    problem.
483  *
484  *************************************************************************************
485  */
486 
u_v(MS_S32 n,MS_S8 * tracestring,MS_S32 value,Bitstream * bitstream)487 MS_S32 u_v (MS_S32 n, MS_S8 *tracestring, MS_S32 value, Bitstream *bitstream)
488 {
489   SyntaxElement symbol, *sym=&symbol;
490 
491   sym->bitpattern = value;
492   sym->len = n;
493   sym->value1 = value;
494 
495   MS_ASSERT (bitstream->streamBuffer != NULL);
496 
497   writeUVLC2buffer(sym, bitstream);
498 
499 #if TRACE
500   strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
501   trace2out (sym);
502 #endif
503 
504   return (sym->len);
505 }
506 
507 /*!
508 ************************************************************************
509 * \brief
510 *    mapping for ue(v) syntax elements
511 * \param ue
512 *    value to be mapped
513 * \param dummy
514 *    dummy parameter
515 * \param info
516 *    returns mapped value
517 * \param len
518 *    returns mapped value length
519 ************************************************************************
520 */
ue_linfo(MS_S32 ue,MS_S32 dummy,MS_S32 * len,MS_S32 * info)521 void ue_linfo(MS_S32 ue, MS_S32 dummy, MS_S32 *len,MS_S32 *info)
522 {
523     MS_S32 i,nn;
524 
525     nn=(ue+1)>>1;
526 
527     for (i=0; i < 33 && nn != 0; i++)
528     {
529         nn >>= 1;
530     }
531     *len  = (i << 1) + 1;
532     *info = ue + 1 - (1 << i);
533 }
534 
535 
536 /*!
537 ************************************************************************
538 * \brief
539 *    mapping for se(v) syntax elements
540 * \param se
541 *    value to be mapped
542 * \param dummy
543 *    dummy parameter
544 * \param len
545 *    returns mapped value length
546 * \param info
547 *    returns mapped value
548 ************************************************************************
549 */
se_linfo(MS_S32 se,MS_S32 dummy,MS_S32 * len,MS_S32 * info)550 void se_linfo(MS_S32 se, MS_S32 dummy, MS_S32 *len,MS_S32 *info)
551 {
552     MS_S32 sign = (se <= 0) ? 1 : 0;
553     MS_S32 n = iabs(se) << 1;   //  n+1 is the number in the code table.  Based on this we find length and info
554     MS_S32 nn = (n >> 1);
555     MS_S32 i;
556     for (i=0; i < 33 && nn != 0; i++)
557     {
558         nn >>= 1;
559     }
560     *len  = (i << 1) + 1;
561     *info = n - (1 << i) + sign;
562 }
563 
writeVlcByteAlign(Bitstream * currStream)564 void writeVlcByteAlign(Bitstream* currStream)
565 {
566     if (currStream->bits_to_go < 8)
567     { // trailing bits to process
568 /*
569         currStream->byte_buf = (currStream->byte_buf <<currStream->bits_to_go) | (0xff >> (8 - currStream->bits_to_go));
570         stats->bit_use_stuffingBits[img->type]+=currStream->bits_to_go;
571         currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
572         currStream->bits_to_go = 8;
573 */
574         SyntaxElement se;
575         se.len = currStream->bits_to_go;
576         se.bitpattern = (0xff >> (8 - currStream->bits_to_go));
577         writeUVLC2buffer(&se, currStream);
578         //stats->bit_use_stuffingBits[img->type]+=currStream->bits_to_go;
579     }
580 }
581