• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2013 Advanced Micro Devices, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /*
29  * Authors:
30  *      Christian König <christian.koenig@amd.com>
31  *
32  */
33 
34 /*
35  * Functions for reading the raw byte sequence payload of H.264
36  */
37 
38 #ifndef vl_rbsp_h
39 #define vl_rbsp_h
40 
41 #include "vl/vl_vlc.h"
42 
43 struct vl_rbsp {
44    struct vl_vlc nal;
45    unsigned escaped;
46 };
47 
48 /**
49  * Initialize the RBSP object
50  */
vl_rbsp_init(struct vl_rbsp * rbsp,struct vl_vlc * nal,unsigned num_bits)51 static inline void vl_rbsp_init(struct vl_rbsp *rbsp, struct vl_vlc *nal, unsigned num_bits)
52 {
53    unsigned valid, bits_left = vl_vlc_bits_left(nal);
54    int i;
55 
56    /* copy the position */
57    rbsp->nal = *nal;
58 
59    /* search for the end of the NAL unit */
60    while (vl_vlc_search_byte(nal, num_bits, 0x00)) {
61       if (vl_vlc_peekbits(nal, 24) == 0x000001 ||
62           vl_vlc_peekbits(nal, 32) == 0x00000001) {
63          vl_vlc_limit(&rbsp->nal, bits_left - vl_vlc_bits_left(nal));
64          break;
65       }
66       vl_vlc_eatbits(nal, 8);
67    }
68 
69    valid = vl_vlc_valid_bits(&rbsp->nal);
70    /* search for the emulation prevention three byte */
71    for (i = 24; i <= valid; i += 8) {
72       if ((vl_vlc_peekbits(&rbsp->nal, i) & 0xffffff) == 0x3) {
73          vl_vlc_removebits(&rbsp->nal, i - 8, 8);
74          i += 8;
75       }
76    }
77 
78    valid = vl_vlc_valid_bits(&rbsp->nal);
79 
80    rbsp->escaped = (valid >= 16) ? 16 : ((valid >= 8) ? 8 : 0);
81 }
82 
83 /**
84  * Make at least 16 more bits available
85  */
vl_rbsp_fillbits(struct vl_rbsp * rbsp)86 static inline void vl_rbsp_fillbits(struct vl_rbsp *rbsp)
87 {
88    unsigned valid = vl_vlc_valid_bits(&rbsp->nal);
89    unsigned i, bits;
90 
91    /* abort if we still have enough bits */
92    if (valid >= 32)
93       return;
94 
95    vl_vlc_fillbits(&rbsp->nal);
96 
97    /* abort if we have less than 24 bits left in this nal */
98    if (vl_vlc_bits_left(&rbsp->nal) < 24)
99       return;
100 
101    /* check that we have enough bits left from the last fillbits */
102    assert(valid >= rbsp->escaped);
103 
104    /* handle the already escaped bits */
105    valid -= rbsp->escaped;
106 
107    /* search for the emulation prevention three byte */
108    rbsp->escaped = 16;
109    bits = vl_vlc_valid_bits(&rbsp->nal);
110    for (i = valid + 24; i <= bits; i += 8) {
111       if ((vl_vlc_peekbits(&rbsp->nal, i) & 0xffffff) == 0x3) {
112          vl_vlc_removebits(&rbsp->nal, i - 8, 8);
113          rbsp->escaped = bits - i;
114          bits -= 8;
115          i += 8;
116       }
117    }
118 }
119 
120 /**
121  * Return an unsigned integer from the first n bits
122  */
vl_rbsp_u(struct vl_rbsp * rbsp,unsigned n)123 static inline unsigned vl_rbsp_u(struct vl_rbsp *rbsp, unsigned n)
124 {
125    if (n == 0)
126       return 0;
127 
128    vl_rbsp_fillbits(rbsp);
129    return vl_vlc_get_uimsbf(&rbsp->nal, n);
130 }
131 
132 /**
133  * Return an unsigned exponential Golomb encoded integer
134  */
vl_rbsp_ue(struct vl_rbsp * rbsp)135 static inline unsigned vl_rbsp_ue(struct vl_rbsp *rbsp)
136 {
137    unsigned bits = 0;
138 
139    vl_rbsp_fillbits(rbsp);
140    while (!vl_vlc_get_uimsbf(&rbsp->nal, 1))
141       ++bits;
142 
143    return (1 << bits) - 1 + vl_rbsp_u(rbsp, bits);
144 }
145 
146 /**
147  * Return an signed exponential Golomb encoded integer
148  */
vl_rbsp_se(struct vl_rbsp * rbsp)149 static inline signed vl_rbsp_se(struct vl_rbsp *rbsp)
150 {
151    signed codeNum = vl_rbsp_ue(rbsp);
152    if (codeNum & 1)
153       return (codeNum + 1) >> 1;
154    else
155       return -(codeNum >> 1);
156 }
157 
158 /**
159  * Are more data available in the RBSP ?
160  */
vl_rbsp_more_data(struct vl_rbsp * rbsp)161 static inline bool vl_rbsp_more_data(struct vl_rbsp *rbsp)
162 {
163    unsigned bits, value;
164 
165    if (vl_vlc_bits_left(&rbsp->nal) > 8)
166       return TRUE;
167 
168    bits = vl_vlc_valid_bits(&rbsp->nal);
169    value = vl_vlc_peekbits(&rbsp->nal, bits);
170    if (value == 0 || value == (1 << (bits - 1)))
171       return FALSE;
172 
173    return TRUE;
174 }
175 
176 #endif /* vl_rbsp_h */
177