• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #include "avcenc_lib.h"
19 #include "oscl_mem.h"
20 
21 #define WORD_SIZE 32
22 
23 /* array for trailing bit pattern as function of number of bits */
24 /* the first one is unused. */
25 const static uint8 trailing_bits[9] = {0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
26 
27 /* ======================================================================== */
28 /*  Function : BitstreamInit()                                              */
29 /*  Date     : 11/4/2003                                                    */
30 /*  Purpose  : Populate bitstream structure with bitstream buffer and size  */
31 /*             it also initializes internal data                            */
32 /*  In/out   :                                                              */
33 /*  Return   : AVCENC_SUCCESS if successed, AVCENC_FAIL if failed.              */
34 /*  Modified :                                                              */
35 /* ======================================================================== */
36 /* |--------|--------|----~~~~~-----|---------|---------|---------|
37    ^                                          ^write_pos          ^buf_size
38    bitstreamBuffer                  <--------->
39                                     current_word
40 
41    |-----xxxxxxxxxxxxx|  = current_word 32 or 16 bits
42     <---->
43      bit_left
44  ======================================================================== */
45 
BitstreamEncInit(AVCEncBitstream * stream,uint8 * buffer,int buf_size,uint8 * overrunBuffer,int oBSize)46 AVCEnc_Status BitstreamEncInit(AVCEncBitstream *stream, uint8 *buffer, int buf_size,
47                                uint8 *overrunBuffer, int oBSize)
48 {
49     if (stream == NULL || buffer == NULL || buf_size <= 0)
50     {
51         return AVCENC_BITSTREAM_INIT_FAIL;
52     }
53 
54     stream->bitstreamBuffer = buffer;
55 
56     stream->buf_size = buf_size;
57 
58     stream->write_pos = 0;
59 
60     stream->count_zeros = 0;
61 
62     stream->current_word = 0;
63 
64     stream->bit_left = WORD_SIZE;
65 
66     stream->overrunBuffer = overrunBuffer;
67 
68     stream->oBSize = oBSize;
69 
70     return AVCENC_SUCCESS;
71 }
72 
73 /* ======================================================================== */
74 /*  Function : AVCBitstreamSaveWord()                                           */
75 /*  Date     : 3/29/2004                                                    */
76 /*  Purpose  : Save the current_word into the buffer, byte-swap, and        */
77 /*              add emulation prevention insertion.                         */
78 /*  In/out   :                                                              */
79 /*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
80 /*              full.                                                       */
81 /*  Modified :                                                              */
82 /* ======================================================================== */
AVCBitstreamSaveWord(AVCEncBitstream * stream)83 AVCEnc_Status AVCBitstreamSaveWord(AVCEncBitstream *stream)
84 {
85     int num_bits;
86     uint8 *write_pnt, byte;
87     uint current_word;
88 
89     /* check number of bytes in current_word, must always be byte-aligned!!!! */
90     num_bits = WORD_SIZE - stream->bit_left; /* must be multiple of 8 !!*/
91 
92     if (stream->buf_size - stream->write_pos <= (num_bits >> 3) + 2) /* 2 more bytes for possible EPBS */
93     {
94         if (AVCENC_SUCCESS != AVCBitstreamUseOverrunBuffer(stream, (num_bits >> 3) + 2))
95         {
96             return AVCENC_BITSTREAM_BUFFER_FULL;
97         }
98     }
99 
100     /* write word, byte-by-byte */
101     write_pnt = stream->bitstreamBuffer + stream->write_pos;
102     current_word = stream->current_word;
103     while (num_bits) /* no need to check stream->buf_size and stream->write_pos, taken care already */
104     {
105         num_bits -= 8;
106         byte = (current_word >> num_bits) & 0xFF;
107         if (byte != 0)
108         {
109             *write_pnt++ = byte;
110             stream->write_pos++;
111             stream->count_zeros = 0;
112         }
113         else
114         {
115             stream->count_zeros++;
116             *write_pnt++ = byte;
117             stream->write_pos++;
118             if (stream->count_zeros == 2)
119             {   /* for num_bits = 32, this can add 2 more bytes extra for EPBS */
120                 *write_pnt++ = 0x3;
121                 stream->write_pos++;
122                 stream->count_zeros = 0;
123             }
124         }
125     }
126 
127     /* reset current_word and bit_left */
128     stream->current_word = 0;
129     stream->bit_left = WORD_SIZE;
130 
131     return AVCENC_SUCCESS;
132 }
133 
134 /* ======================================================================== */
135 /*  Function : BitstreamWriteBits()                                         */
136 /*  Date     : 3/29/2004                                                    */
137 /*  Purpose  : Write up to machine word.                                    */
138 /*  In/out   : Unused bits in 'code' must be all zeros.                     */
139 /*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
140 /*              full.                                                       */
141 /*  Modified :                                                              */
142 /* ======================================================================== */
BitstreamWriteBits(AVCEncBitstream * stream,int nBits,uint code)143 AVCEnc_Status BitstreamWriteBits(AVCEncBitstream *stream, int nBits, uint code)
144 {
145     AVCEnc_Status status = AVCENC_SUCCESS;
146     int bit_left = stream->bit_left;
147     uint current_word = stream->current_word;
148 
149     //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWriteBits",nBits,-1);
150 
151     if (nBits > WORD_SIZE) /* has to be taken care of specially */
152     {
153         return AVCENC_FAIL; /* for now */
154         /* otherwise, break it down to 2 write of less than 16 bits at a time. */
155     }
156 
157     if (nBits <= bit_left) /* more bits left in current_word */
158     {
159         stream->current_word = (current_word << nBits) | code;
160         stream->bit_left -= nBits;
161         if (stream->bit_left == 0) /* prepare for the next word */
162         {
163             status = AVCBitstreamSaveWord(stream);
164             return status;
165         }
166     }
167     else
168     {
169         stream->current_word = (current_word << bit_left) | (code >> (nBits - bit_left));
170 
171         nBits -= bit_left;
172 
173         stream->bit_left = 0;
174 
175         status = AVCBitstreamSaveWord(stream); /* save current word */
176 
177         stream->bit_left = WORD_SIZE - nBits;
178 
179         stream->current_word = code; /* no extra masking for code, must be handled before saving */
180     }
181 
182     return status;
183 }
184 
185 
186 /* ======================================================================== */
187 /*  Function : BitstreamWrite1Bit()                                         */
188 /*  Date     : 3/30/2004                                                    */
189 /*  Purpose  : Write 1 bit                                                  */
190 /*  In/out   : Unused bits in 'code' must be all zeros.                     */
191 /*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
192 /*              full.                                                       */
193 /*  Modified :                                                              */
194 /* ======================================================================== */
BitstreamWrite1Bit(AVCEncBitstream * stream,uint code)195 AVCEnc_Status BitstreamWrite1Bit(AVCEncBitstream *stream, uint code)
196 {
197     AVCEnc_Status status;
198     uint current_word = stream->current_word;
199 
200     //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"BitstreamWrite1Bit",code,-1);
201 
202     //if(1 <= bit_left) /* more bits left in current_word */
203     /* we can assume that there always be positive bit_left in the current word */
204     stream->current_word = (current_word << 1) | code;
205     stream->bit_left--;
206     if (stream->bit_left == 0) /* prepare for the next word */
207     {
208         status = AVCBitstreamSaveWord(stream);
209         return status;
210     }
211 
212     return AVCENC_SUCCESS;
213 }
214 
215 
216 /* ======================================================================== */
217 /*  Function : BitstreamTrailingBits()                                      */
218 /*  Date     : 3/31/2004                                                    */
219 /*  Purpose  : Add trailing bits and report the final EBSP size.            */
220 /*  In/out   :                                                              */
221 /*  Return   : AVCENC_SUCCESS if successed, AVCENC_WRITE_FAIL if buffer is  */
222 /*              full.                                                       */
223 /*  Modified :                                                              */
224 /* ======================================================================== */
BitstreamTrailingBits(AVCEncBitstream * bitstream,uint * nal_size)225 AVCEnc_Status BitstreamTrailingBits(AVCEncBitstream *bitstream, uint *nal_size)
226 {
227     (void)(nal_size);
228 
229     AVCEnc_Status status;
230     int bit_left = bitstream->bit_left;
231 
232     bit_left &= 0x7; /* modulo by 8 */
233     if (bit_left == 0) bit_left = 8;
234     /* bitstream->bit_left == 0 cannot happen here since it would have been Saved already */
235 
236     status = BitstreamWriteBits(bitstream, bit_left, trailing_bits[bit_left]);
237 
238     if (status != AVCENC_SUCCESS)
239     {
240         return status;
241     }
242 
243     /* if it's not saved, save it. */
244     //if(bitstream->bit_left<(WORD_SIZE<<3)) /* in fact, no need to check */
245     {
246         status = AVCBitstreamSaveWord(bitstream);
247     }
248 
249     return status;
250 }
251 
252 /* check whether it's byte-aligned */
byte_aligned(AVCEncBitstream * stream)253 bool byte_aligned(AVCEncBitstream *stream)
254 {
255     if (stream->bit_left % 8)
256         return false;
257     else
258         return true;
259 }
260 
261 
262 /* determine whether overrun buffer can be used or not */
AVCBitstreamUseOverrunBuffer(AVCEncBitstream * stream,int numExtraBytes)263 AVCEnc_Status AVCBitstreamUseOverrunBuffer(AVCEncBitstream* stream, int numExtraBytes)
264 {
265     AVCEncObject *encvid = (AVCEncObject*)stream->encvid;
266 
267     if (stream->overrunBuffer != NULL) // overrunBuffer is set
268     {
269         if (stream->bitstreamBuffer != stream->overrunBuffer) // not already used
270         {
271             if (stream->write_pos + numExtraBytes >= stream->oBSize)
272             {
273                 stream->oBSize = stream->write_pos + numExtraBytes + 100;
274                 stream->oBSize &= (~0x3); // make it multiple of 4
275 
276                 // allocate new overrun Buffer
277                 if (encvid->overrunBuffer)
278                 {
279                     encvid->avcHandle->CBAVC_Free((uint32*)encvid->avcHandle->userData,
280                                                   (int)encvid->overrunBuffer);
281                 }
282 
283                 encvid->oBSize = stream->oBSize;
284                 encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
285                                         stream->oBSize, DEFAULT_ATTR);
286 
287                 stream->overrunBuffer = encvid->overrunBuffer;
288                 if (stream->overrunBuffer == NULL)
289                 {
290                     return AVCENC_FAIL;
291                 }
292             }
293 
294             // copy everything to overrun buffer and start using it.
295             oscl_memcpy(stream->overrunBuffer, stream->bitstreamBuffer, stream->write_pos);
296             stream->bitstreamBuffer = stream->overrunBuffer;
297             stream->buf_size = stream->oBSize;
298         }
299         else // overrun buffer is already used
300         {
301             stream->oBSize = stream->write_pos + numExtraBytes + 100;
302             stream->oBSize &= (~0x3); // make it multiple of 4
303 
304             // allocate new overrun buffer
305             encvid->oBSize = stream->oBSize;
306             encvid->overrunBuffer = (uint8*) encvid->avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
307                                     stream->oBSize, DEFAULT_ATTR);
308 
309             if (encvid->overrunBuffer == NULL)
310             {
311                 return AVCENC_FAIL;
312             }
313 
314 
315             // copy from the old buffer to new buffer
316             oscl_memcpy(encvid->overrunBuffer, stream->overrunBuffer, stream->write_pos);
317             // free old buffer
318             encvid->avcHandle->CBAVC_Free((uint32*)encvid->avcHandle->userData,
319                                           (int)stream->overrunBuffer);
320 
321             // assign pointer to new buffer
322             stream->overrunBuffer = encvid->overrunBuffer;
323             stream->bitstreamBuffer = stream->overrunBuffer;
324             stream->buf_size = stream->oBSize;
325         }
326 
327         return AVCENC_SUCCESS;
328     }
329     else // overrunBuffer is not enable.
330     {
331         return AVCENC_FAIL;
332     }
333 
334 }
335 
336 
337 
338