summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c
blob: 7bdda19a62eedffe448dd7724fb1dc8fff1d67aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
 * Copyright (C) 2007-2008 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/**
 * 
 * File Name:  omxVCM4P2_EncodeVLCZigzag_IntraDCVLC.c
 * OpenMAX DL: v1.0.2
 * Revision:   9641
 * Date:       Thursday, February 7, 2008
 * 
 * 
 * 
 *
 * Description: 
 * Contains modules for zigzag scanning and VLC encoding
 * for intra block.
 *
 */ 
 
#include "omxtypes.h"
#include "armOMX.h"
#include "omxVC.h"

#include "armVC.h"
#include "armCOMM_Bitstream.h"
#include "armCOMM.h"
#include "armVCM4P2_Huff_Tables_VLC.h"
#include "armVCM4P2_ZigZag_Tables.h"



/**
 * Function:  omxVCM4P2_EncodeVLCZigzag_IntraDCVLC   (6.2.4.5.2)
 *
 * Description:
 * Performs zigzag scan and VLC encoding of AC and DC coefficients for one 
 * intra block.  Two versions of the function (DCVLC and ACVLC) are provided 
 * in order to support the two different methods of processing DC 
 * coefficients, as described in [ISO14496-2], subclause 7.4.1.4, "Intra DC 
 * Coefficient Decoding for the Case of Switched VLC Encoding".  
 *
 * Input Arguments:
 *   
 *   ppBitStream - double pointer to the current byte in the bitstream 
 *   pBitOffset - pointer to the bit position in the byte pointed by 
 *            *ppBitStream. Valid within 0 to 7. 
 *   pQDctBlkCoef - pointer to the quantized DCT coefficient 
 *   predDir - AC prediction direction, which is used to decide the zigzag 
 *            scan pattern; takes one of the following values: 
 *            -  OMX_VC_NONE - AC prediction not used.  
 *                             Performs classical zigzag scan. 
 *            -  OMX_VC_HORIZONTAL - Horizontal prediction.  
 *                             Performs alternate-vertical zigzag scan. 
 *            -  OMX_VC_VERTICAL - Vertical prediction.  
 *                             Performs alternate-horizontal zigzag scan. 
 *   pattern - block pattern which is used to decide whether this block is 
 *            encoded 
 *   shortVideoHeader - binary flag indicating presence of 
 *            short_video_header; escape modes 0-3 are used if 
 *            shortVideoHeader==0, and escape mode 4 is used when 
 *            shortVideoHeader==1. 
 *   videoComp - video component type (luminance, chrominance) of the current 
 *            block 
 *
 * Output Arguments:
 *   
 *   ppBitStream - *ppBitStream is updated after the block is encoded, so 
 *            that it points to the current byte in the bit stream buffer. 
 *   pBitOffset - *pBitOffset is updated so that it points to the current bit 
 *            position in the byte pointed by *ppBitStream. 
 *
 * Return Value:
 *    
 *    OMX_Sts_NoErr - no error 
 *    OMX_Sts_BadArgErr - Bad arguments:
 *    -    At least one of the following pointers is NULL: ppBitStream, 
 *              *ppBitStream, pBitOffset, pQDctBlkCoef. 
 *    -   *pBitOffset < 0, or *pBitOffset >7. 
 *    -    PredDir is not one of: OMX_VC_NONE, OMX_VC_HORIZONTAL, or 
 *         OMX_VC_VERTICAL. 
 *    -    VideoComp is not one component of enum OMXVCM4P2VideoComponent. 
 *
 */

OMXResult omxVCM4P2_EncodeVLCZigzag_IntraDCVLC(
     OMX_U8 **ppBitStream,
     OMX_INT *pBitOffset,
     const OMX_S16 *pQDctBlkCoef,
     OMX_U8 predDir,
     OMX_U8 pattern,
     OMX_INT shortVideoHeader,
     OMXVCM4P2VideoComponent videoComp
)
{
    OMX_S16 dcValue, powOfSize;
    OMX_U8  DCValueSize, start = 1;
    OMX_U16 absDCValue;

    /* Argument error checks */
    armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pQDctBlkCoef == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr);
	armRetArgErrIf((videoComp != OMX_VC_LUMINANCE) && (videoComp != OMX_VC_CHROMINANCE), OMX_Sts_BadArgErr);
	armRetArgErrIf((predDir != OMX_VC_NONE) && (predDir != OMX_VC_HORIZONTAL) && (predDir != OMX_VC_VERTICAL) , OMX_Sts_BadArgErr);
    
    if (pattern)
    {
        dcValue = pQDctBlkCoef[0];
        absDCValue = armAbs(dcValue);

        /* Find the size */
        DCValueSize = armLogSize (absDCValue);
        absDCValue = armAbs(dcValue);

        /* Insert the code into the bitstream */
        if (videoComp == OMX_VC_LUMINANCE)
        {

            armPackVLC32 (ppBitStream, pBitOffset,
                          armVCM4P2_aIntraDCLumaIndex[DCValueSize]);
        }
        else if (videoComp == OMX_VC_CHROMINANCE)
        {

            armPackVLC32 (ppBitStream, pBitOffset,
                          armVCM4P2_aIntraDCChromaIndex[DCValueSize]);
        }

        /* Additional code generation in case of negative
           dc value the additional */
        if (DCValueSize > 0)
        {
            if (dcValue < 0)
            {
                /* calulate 2 pow */
                powOfSize = (1 << DCValueSize);

                absDCValue =  absDCValue ^ (powOfSize - 1);
            }
            armPackBits(ppBitStream, pBitOffset, (OMX_U32)absDCValue, \
                        DCValueSize);

            if (DCValueSize > 8)
            {
                armPackBits(ppBitStream, pBitOffset, 1, 1);
            }
        }
    }

    return armVCM4P2_EncodeVLCZigzag_Intra(
                ppBitStream,
                pBitOffset,
                pQDctBlkCoef,
                predDir,
                pattern,
                shortVideoHeader,
                start);
}

/* End of file */