]> git.sesse.net Git - vlc/blob - modules/stream_out/transrate/transrate.h
422f167eb43fc6068910c39307765c640d6a16ef
[vlc] / modules / stream_out / transrate / transrate.h
1 /*****************************************************************************
2  * transrate.h: MPEG2 video transrating module
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
5  * Copyright (C) 2003 Antoine Missout
6  * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
7  * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
8  * $Id$
9  *
10  * Authors: Christophe Massiot <massiot@via.ecp.fr>
11  *          Laurent Aimar <fenrir@via.ecp.fr>
12  *          Antoine Missout
13  *          Michel Lespinasse <walken@zoy.org>
14  *          Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
29  *****************************************************************************/
30
31 /*****************************************************************************
32  * sout_stream_id_t:
33  *****************************************************************************/
34
35 typedef struct
36 {
37     uint8_t run;
38     short level;
39 } RunLevel;
40
41 typedef struct
42 {
43     uint8_t *p_c;
44     uint8_t *p_r;
45     uint8_t *p_w;
46     uint8_t *p_ow;
47     uint8_t *p_rw;
48
49     int i_bit_in;
50     int i_bit_out;
51     uint32_t i_bit_in_cache;
52     uint32_t i_bit_out_cache;
53
54     uint32_t i_byte_in;
55     uint32_t i_byte_out;
56 } bs_transrate_t;
57
58 typedef struct
59 {
60     bs_transrate_t bs;
61
62     /* MPEG2 state */
63
64     // seq header
65     unsigned int horizontal_size_value;
66     unsigned int vertical_size_value;
67     uint8_t intra_quantizer_matrix [64];
68     uint8_t non_intra_quantizer_matrix [64];
69     int mpeg4_matrix;
70
71     // pic header
72     unsigned int picture_coding_type;
73
74     // pic code ext
75     unsigned int f_code[2][2];
76     /* unsigned int intra_dc_precision; */
77     unsigned int picture_structure;
78     unsigned int frame_pred_frame_dct;
79     unsigned int concealment_motion_vectors;
80     unsigned int q_scale_type;
81     unsigned int intra_vlc_format;
82     const uint8_t * scan;
83
84     // slice or mb
85     // quantizer_scale_code
86     unsigned int quantizer_scale;
87     unsigned int new_quantizer_scale;
88     unsigned int last_coded_scale;
89     int   h_offset, v_offset;
90     vlc_bool_t b_error;
91
92     // mb
93     double qrate;
94     int i_admissible_error, i_minimum_error;
95
96     /* input buffers */
97     ssize_t i_total_input, i_remaining_input;
98     /* output buffers */
99     ssize_t i_current_output, i_wanted_output;
100 } transrate_t;
101
102
103 struct sout_stream_id_t
104 {
105     void            *id;
106     vlc_bool_t      b_transrate;
107
108     block_t         *p_current_buffer;
109     block_t         *p_next_gop;
110     mtime_t         i_next_gop_duration;
111     size_t          i_next_gop_size;
112
113     transrate_t     tr;
114 };
115
116
117 #ifdef HAVE_BUILTIN_EXPECT
118 #define likely(x) __builtin_expect ((x) != 0, 1)
119 #define unlikely(x) __builtin_expect ((x) != 0, 0)
120 #else
121 #define likely(x) (x)
122 #define unlikely(x) (x)
123 #endif
124
125 #define BITS_IN_BUF (8)
126
127 #define LOG(msg) fprintf (stderr, msg)
128 #define LOGF(format, args...) fprintf (stderr, format, args)
129
130 static inline void bs_write( bs_transrate_t *s, unsigned int val, int n )
131 {
132     assert(n < 32);
133     assert(!(val & (0xffffffffU << n)));
134
135     while (unlikely(n >= s->i_bit_out))
136     {
137         s->p_w[0] = (s->i_bit_out_cache << s->i_bit_out ) | (val >> (n - s->i_bit_out));
138         s->p_w++;
139         n -= s->i_bit_out;
140         s->i_bit_out_cache = 0;
141         val &= ~(0xffffffffU << n);
142         s->i_bit_out = BITS_IN_BUF;
143     }
144
145     if (likely(n))
146     {
147         s->i_bit_out_cache = (s->i_bit_out_cache << n) | val;
148         s->i_bit_out -= n;
149     }
150
151     assert(s->i_bit_out > 0);
152     assert(s->i_bit_out <= BITS_IN_BUF);
153 }
154
155 static inline void bs_refill( bs_transrate_t *s )
156 {
157     assert((s->p_r - s->p_c) >= 1);
158     s->i_bit_in_cache |= s->p_c[0] << (24 - s->i_bit_in);
159     s->i_bit_in += 8;
160     s->p_c++;
161 }
162
163 static inline void bs_flush( bs_transrate_t *s, unsigned int n )
164 {
165     assert(s->i_bit_in >= n);
166
167     s->i_bit_in_cache <<= n;
168     s->i_bit_in -= n;
169
170     assert( (!n) || ((n>0) && !(s->i_bit_in_cache & 0x1)) );
171
172     while (unlikely(s->i_bit_in < 24)) bs_refill( s );
173 }
174
175 static inline unsigned int bs_read( bs_transrate_t *s, unsigned int n )
176 {
177     unsigned int Val = ((unsigned int)s->i_bit_in_cache) >> (32 - n);
178     bs_flush( s, n );
179     return Val;
180 }
181
182 static inline unsigned int bs_copy( bs_transrate_t *s, unsigned int n )
183 {
184     unsigned int Val = bs_read( s, n);
185     bs_write(s, Val, n);
186     return Val;
187 }
188
189 static inline void bs_flush_read( bs_transrate_t *s )
190 {
191     int i = s->i_bit_in & 0x7;
192     if( i )
193     {
194         assert(((unsigned int)s->i_bit_in_cache) >> (32 - i) == 0);
195         s->i_bit_in_cache <<= i;
196         s->i_bit_in -= i;
197     }
198     s->p_c += -1 * (s->i_bit_in >> 3);
199     s->i_bit_in = 0;
200 }
201 static inline void bs_flush_write( bs_transrate_t *s )
202 {
203     if( s->i_bit_out != 8 ) bs_write(s, 0, s->i_bit_out);
204 }
205
206 int scale_quant( transrate_t *tr, double qrate );
207 int transrate_mb( transrate_t *tr, RunLevel blk[6][65], RunLevel new_blk[6][65], int i_cbp, int intra );
208 void get_intra_block_B14( transrate_t *tr, RunLevel *blk );
209 void get_intra_block_B15( transrate_t *tr, RunLevel *blk );
210 int get_non_intra_block( transrate_t *tr, RunLevel *blk );
211 void putnonintrablk( bs_transrate_t *bs, RunLevel *blk);
212 void putintrablk( bs_transrate_t *bs, RunLevel *blk, int vlcformat);
213
214 int process_frame( sout_stream_t *p_stream, sout_stream_id_t *id,
215                    block_t *in, block_t **out, int i_handicap );