/src/x264/common/bitstream.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * bitstream.c: bitstream writing |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2003-2025 x264 project |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Fiona Glaser <fiona@x264.com> |
8 | | * |
9 | | * This program is free software; you can redistribute it and/or modify |
10 | | * it under the terms of the GNU General Public License as published by |
11 | | * the Free Software Foundation; either version 2 of the License, or |
12 | | * (at your option) any later version. |
13 | | * |
14 | | * This program is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | * GNU General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU General Public License |
20 | | * along with this program; if not, write to the Free Software |
21 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
22 | | * |
23 | | * This program is also available under a commercial proprietary license. |
24 | | * For more information, contact us at licensing@x264.com. |
25 | | *****************************************************************************/ |
26 | | |
27 | | #include "common.h" |
28 | | |
29 | | static uint8_t *nal_escape_c( uint8_t *dst, uint8_t *src, uint8_t *end ) |
30 | 0 | { |
31 | 0 | if( src < end ) *dst++ = *src++; |
32 | 0 | if( src < end ) *dst++ = *src++; |
33 | 0 | while( src < end ) |
34 | 0 | { |
35 | 0 | if( src[0] <= 0x03 && !dst[-2] && !dst[-1] ) |
36 | 0 | *dst++ = 0x03; |
37 | 0 | *dst++ = *src++; |
38 | 0 | } |
39 | 0 | return dst; |
40 | 0 | } |
41 | | |
42 | | #if HAVE_MMX |
43 | | #include "x86/bitstream.h" |
44 | | #endif |
45 | | #if HAVE_ARMV6 |
46 | | #include "arm/bitstream.h" |
47 | | #endif |
48 | | #if HAVE_AARCH64 |
49 | | #include "aarch64/bitstream.h" |
50 | | #endif |
51 | | |
52 | | /**************************************************************************** |
53 | | * x264_nal_encode: |
54 | | ****************************************************************************/ |
55 | | void x264_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal ) |
56 | 0 | { |
57 | 0 | uint8_t *src = nal->p_payload; |
58 | 0 | uint8_t *end = nal->p_payload + nal->i_payload; |
59 | 0 | uint8_t *orig_dst = dst; |
60 | |
|
61 | 0 | if( h->param.b_annexb ) |
62 | 0 | { |
63 | 0 | if( nal->b_long_startcode ) |
64 | 0 | *dst++ = 0x00; |
65 | 0 | *dst++ = 0x00; |
66 | 0 | *dst++ = 0x00; |
67 | 0 | *dst++ = 0x01; |
68 | 0 | } |
69 | 0 | else /* save room for size later */ |
70 | 0 | dst += 4; |
71 | | |
72 | | /* nal header */ |
73 | 0 | *dst++ = ( 0x00 << 7 ) | ( nal->i_ref_idc << 5 ) | nal->i_type; |
74 | |
|
75 | 0 | dst = h->bsf.nal_escape( dst, src, end ); |
76 | 0 | int size = dst - orig_dst; |
77 | | |
78 | | /* Apply AVC-Intra padding */ |
79 | 0 | if( h->param.i_avcintra_class ) |
80 | 0 | { |
81 | 0 | int padding = nal->i_payload + nal->i_padding + NALU_OVERHEAD - size; |
82 | 0 | if( padding > 0 ) |
83 | 0 | { |
84 | 0 | memset( dst, 0, padding ); |
85 | 0 | size += padding; |
86 | 0 | } |
87 | 0 | nal->i_padding = X264_MAX( padding, 0 ); |
88 | 0 | } |
89 | | |
90 | | /* Write the size header for mp4/etc */ |
91 | 0 | if( !h->param.b_annexb ) |
92 | 0 | { |
93 | | /* Size doesn't include the size of the header we're writing now. */ |
94 | 0 | int chunk_size = size - 4; |
95 | 0 | orig_dst[0] = (uint8_t)(chunk_size >> 24); |
96 | 0 | orig_dst[1] = (uint8_t)(chunk_size >> 16); |
97 | 0 | orig_dst[2] = (uint8_t)(chunk_size >> 8); |
98 | 0 | orig_dst[3] = (uint8_t)(chunk_size >> 0); |
99 | 0 | } |
100 | |
|
101 | 0 | nal->i_payload = size; |
102 | 0 | nal->p_payload = orig_dst; |
103 | 0 | x264_emms(); |
104 | 0 | } Unexecuted instantiation: x264_8_nal_encode Unexecuted instantiation: x264_10_nal_encode |
105 | | |
106 | | void x264_bitstream_init( uint32_t cpu, x264_bitstream_function_t *pf ) |
107 | 0 | { |
108 | 0 | memset( pf, 0, sizeof(*pf) ); |
109 | |
|
110 | 0 | pf->nal_escape = nal_escape_c; |
111 | | #if HAVE_MMX |
112 | | #if ARCH_X86_64 |
113 | | pf->cabac_block_residual_internal = x264_cabac_block_residual_internal_sse2; |
114 | | pf->cabac_block_residual_rd_internal = x264_cabac_block_residual_rd_internal_sse2; |
115 | | pf->cabac_block_residual_8x8_rd_internal = x264_cabac_block_residual_8x8_rd_internal_sse2; |
116 | | #endif |
117 | | |
118 | | if( cpu&X264_CPU_MMX2 ) |
119 | | pf->nal_escape = x264_nal_escape_mmx2; |
120 | | if( cpu&X264_CPU_SSE2 ) |
121 | | { |
122 | | if( cpu&X264_CPU_SSE2_IS_FAST ) |
123 | | pf->nal_escape = x264_nal_escape_sse2; |
124 | | } |
125 | | #if ARCH_X86_64 |
126 | | if( cpu&X264_CPU_LZCNT ) |
127 | | { |
128 | | pf->cabac_block_residual_internal = x264_cabac_block_residual_internal_lzcnt; |
129 | | pf->cabac_block_residual_rd_internal = x264_cabac_block_residual_rd_internal_lzcnt; |
130 | | pf->cabac_block_residual_8x8_rd_internal = x264_cabac_block_residual_8x8_rd_internal_lzcnt; |
131 | | } |
132 | | |
133 | | if( cpu&X264_CPU_SSSE3 ) |
134 | | { |
135 | | pf->cabac_block_residual_rd_internal = x264_cabac_block_residual_rd_internal_ssse3; |
136 | | pf->cabac_block_residual_8x8_rd_internal = x264_cabac_block_residual_8x8_rd_internal_ssse3; |
137 | | if( cpu&X264_CPU_LZCNT ) |
138 | | { |
139 | | pf->cabac_block_residual_rd_internal = x264_cabac_block_residual_rd_internal_ssse3_lzcnt; |
140 | | pf->cabac_block_residual_8x8_rd_internal = x264_cabac_block_residual_8x8_rd_internal_ssse3_lzcnt; |
141 | | } |
142 | | } |
143 | | |
144 | | if( cpu&X264_CPU_AVX2 ) |
145 | | { |
146 | | pf->nal_escape = x264_nal_escape_avx2; |
147 | | pf->cabac_block_residual_internal = x264_cabac_block_residual_internal_avx2; |
148 | | } |
149 | | |
150 | | if( cpu&X264_CPU_AVX512 ) |
151 | | { |
152 | | pf->cabac_block_residual_internal = x264_cabac_block_residual_internal_avx512; |
153 | | pf->cabac_block_residual_rd_internal = x264_cabac_block_residual_rd_internal_avx512; |
154 | | pf->cabac_block_residual_8x8_rd_internal = x264_cabac_block_residual_8x8_rd_internal_avx512; |
155 | | } |
156 | | #endif |
157 | | #endif |
158 | | #if HAVE_ARMV6 |
159 | | if( cpu&X264_CPU_NEON ) |
160 | | pf->nal_escape = x264_nal_escape_neon; |
161 | | #endif |
162 | | #if HAVE_AARCH64 |
163 | | if( cpu&X264_CPU_NEON ) |
164 | | pf->nal_escape = x264_nal_escape_neon; |
165 | | #endif |
166 | 0 | } Unexecuted instantiation: x264_8_bitstream_init Unexecuted instantiation: x264_10_bitstream_init |