• 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 "util/vl_vlc.h"
42 
43 struct vl_rbsp {
44    struct vl_vlc nal;
45    unsigned escaped;
46    unsigned removed;
47 };
48 
49 /**
50  * Initialize the RBSP object
51  */
vl_rbsp_init(struct vl_rbsp * rbsp,struct vl_vlc * nal,unsigned num_bits)52 static inline void vl_rbsp_init(struct vl_rbsp *rbsp, struct vl_vlc *nal, unsigned num_bits)
53 {
54    unsigned valid, bits_left = vl_vlc_bits_left(nal);
55    int i;
56 
57    /* copy the position */
58    rbsp->nal = *nal;
59 
60    /* search for the end of the NAL unit */
61    while (vl_vlc_search_byte(nal, num_bits, 0x00)) {
62       if (vl_vlc_peekbits(nal, 24) == 0x000001 ||
63           vl_vlc_peekbits(nal, 32) == 0x00000001) {
64          vl_vlc_limit(&rbsp->nal, bits_left - vl_vlc_bits_left(nal));
65          break;
66       }
67       vl_vlc_eatbits(nal, 8);
68    }
69 
70    valid = vl_vlc_valid_bits(&rbsp->nal);
71    /* search for the emulation prevention three byte */
72    for (i = 24; i <= valid; i += 8) {
73       if ((vl_vlc_peekbits(&rbsp->nal, i) & 0xffffff) == 0x3) {
74          vl_vlc_removebits(&rbsp->nal, i - 8, 8);
75          i += 8;
76       }
77    }
78 
79    valid = vl_vlc_valid_bits(&rbsp->nal);
80 
81    rbsp->escaped = (valid >= 16) ? 16 : ((valid >= 8) ? 8 : 0);
82    rbsp->removed = 0;
83 }
84 
85 /**
86  * Make at least 16 more bits available
87  */
vl_rbsp_fillbits(struct vl_rbsp * rbsp)88 static inline void vl_rbsp_fillbits(struct vl_rbsp *rbsp)
89 {
90    unsigned valid = vl_vlc_valid_bits(&rbsp->nal);
91    unsigned i, bits;
92 
93    /* abort if we still have enough bits */
94    if (valid >= 32)
95       return;
96 
97    vl_vlc_fillbits(&rbsp->nal);
98 
99    /* abort if we have less than 24 bits left in this nal */
100    if (vl_vlc_bits_left(&rbsp->nal) < 24)
101       return;
102 
103    /* check that we have enough bits left from the last fillbits */
104    assert(valid >= rbsp->escaped);
105 
106    /* handle the already escaped bits */
107    valid -= rbsp->escaped;
108 
109    /* search for the emulation prevention three byte */
110    rbsp->escaped = 16;
111    bits = vl_vlc_valid_bits(&rbsp->nal);
112    for (i = valid + 24; i <= bits; i += 8) {
113       if ((vl_vlc_peekbits(&rbsp->nal, i) & 0xffffff) == 0x3) {
114          vl_vlc_removebits(&rbsp->nal, i - 8, 8);
115          rbsp->escaped = bits - i;
116          bits -= 8;
117          rbsp->removed += 8;
118          i += 8;
119       }
120    }
121 }
122 
123 /**
124  * Return an unsigned integer from the first n bits
125  */
vl_rbsp_u(struct vl_rbsp * rbsp,unsigned n)126 static inline unsigned vl_rbsp_u(struct vl_rbsp *rbsp, unsigned n)
127 {
128    if (n == 0)
129       return 0;
130 
131    vl_rbsp_fillbits(rbsp);
132    return vl_vlc_get_uimsbf(&rbsp->nal, n);
133 }
134 
135 /**
136  * Return an unsigned exponential Golomb encoded integer
137  */
vl_rbsp_ue(struct vl_rbsp * rbsp)138 static inline unsigned vl_rbsp_ue(struct vl_rbsp *rbsp)
139 {
140    unsigned bits = 0;
141 
142    vl_rbsp_fillbits(rbsp);
143    while (!vl_vlc_get_uimsbf(&rbsp->nal, 1))
144       ++bits;
145 
146    return (1 << bits) - 1 + vl_rbsp_u(rbsp, bits);
147 }
148 
149 /**
150  * Return an signed exponential Golomb encoded integer
151  */
vl_rbsp_se(struct vl_rbsp * rbsp)152 static inline signed vl_rbsp_se(struct vl_rbsp *rbsp)
153 {
154    signed codeNum = vl_rbsp_ue(rbsp);
155    if (codeNum & 1)
156       return (codeNum + 1) >> 1;
157    else
158       return -(codeNum >> 1);
159 }
160 
161 /**
162  * Are more data available in the RBSP ?
163  */
vl_rbsp_more_data(struct vl_rbsp * rbsp)164 static inline bool vl_rbsp_more_data(struct vl_rbsp *rbsp)
165 {
166    unsigned bits, value;
167 
168    if (vl_vlc_bits_left(&rbsp->nal) > 8)
169       return true;
170 
171    bits = vl_vlc_valid_bits(&rbsp->nal);
172    value = vl_vlc_peekbits(&rbsp->nal, bits);
173    if (value == 0 || value == (1 << (bits - 1)))
174       return false;
175 
176    return true;
177 }
178 
179 #endif /* vl_rbsp_h */
180