Mercurial > libavcodec.hg
comparison h261enc.c @ 5057:5b63f62602fa libavcodec
Split the h261.c file into separate files for the encoder, decoder and common stuff.
author | takis |
---|---|
date | Mon, 21 May 2007 12:51:29 +0000 |
parents | h261.c@f99e40a7155b |
children | 65b1bfb3a74c |
comparison
equal
deleted
inserted
replaced
5056:bea5fb6c0999 | 5057:5b63f62602fa |
---|---|
1 /* | |
2 * H261 encoder | |
3 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> | |
4 * Copyright (c) 2004 Maarten Daniels | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 /** | |
24 * @file h261enc.c | |
25 * H.261 encoder. | |
26 */ | |
27 | |
28 #include "dsputil.h" | |
29 #include "avcodec.h" | |
30 #include "mpegvideo.h" | |
31 #include "h261data.h" | |
32 #include "h261.h" | |
33 | |
34 extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; | |
35 | |
36 static void h261_encode_block(H261Context * h, DCTELEM * block, | |
37 int n); | |
38 | |
39 int ff_h261_get_picture_format(int width, int height){ | |
40 // QCIF | |
41 if (width == 176 && height == 144) | |
42 return 0; | |
43 // CIF | |
44 else if (width == 352 && height == 288) | |
45 return 1; | |
46 // ERROR | |
47 else | |
48 return -1; | |
49 } | |
50 | |
51 void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ | |
52 H261Context * h = (H261Context *) s; | |
53 int format, temp_ref; | |
54 | |
55 align_put_bits(&s->pb); | |
56 | |
57 /* Update the pointer to last GOB */ | |
58 s->ptr_lastgob = pbBufPtr(&s->pb); | |
59 | |
60 put_bits(&s->pb, 20, 0x10); /* PSC */ | |
61 | |
62 temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num / | |
63 (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp | |
64 put_bits(&s->pb, 5, temp_ref & 0x1f); /* TemporalReference */ | |
65 | |
66 put_bits(&s->pb, 1, 0); /* split screen off */ | |
67 put_bits(&s->pb, 1, 0); /* camera off */ | |
68 put_bits(&s->pb, 1, 0); /* freeze picture release off */ | |
69 | |
70 format = ff_h261_get_picture_format(s->width, s->height); | |
71 | |
72 put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */ | |
73 | |
74 put_bits(&s->pb, 1, 0); /* still image mode */ | |
75 put_bits(&s->pb, 1, 0); /* reserved */ | |
76 | |
77 put_bits(&s->pb, 1, 0); /* no PEI */ | |
78 if(format == 0) | |
79 h->gob_number = -1; | |
80 else | |
81 h->gob_number = 0; | |
82 h->current_mba = 0; | |
83 } | |
84 | |
85 /** | |
86 * Encodes a group of blocks header. | |
87 */ | |
88 static void h261_encode_gob_header(MpegEncContext * s, int mb_line){ | |
89 H261Context * h = (H261Context *)s; | |
90 if(ff_h261_get_picture_format(s->width, s->height) == 0){ | |
91 h->gob_number+=2; // QCIF | |
92 } | |
93 else{ | |
94 h->gob_number++; // CIF | |
95 } | |
96 put_bits(&s->pb, 16, 1); /* GBSC */ | |
97 put_bits(&s->pb, 4, h->gob_number); /* GN */ | |
98 put_bits(&s->pb, 5, s->qscale); /* GQUANT */ | |
99 put_bits(&s->pb, 1, 0); /* no GEI */ | |
100 h->current_mba = 0; | |
101 h->previous_mba = 0; | |
102 h->current_mv_x=0; | |
103 h->current_mv_y=0; | |
104 } | |
105 | |
106 void ff_h261_reorder_mb_index(MpegEncContext* s){ | |
107 int index= s->mb_x + s->mb_y*s->mb_width; | |
108 | |
109 if(index % 33 == 0) | |
110 h261_encode_gob_header(s,0); | |
111 | |
112 /* for CIF the GOB's are fragmented in the middle of a scanline | |
113 that's why we need to adjust the x and y index of the macroblocks */ | |
114 if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF | |
115 s->mb_x = index % 11 ; index /= 11; | |
116 s->mb_y = index % 3 ; index /= 3; | |
117 s->mb_x+= 11*(index % 2); index /= 2; | |
118 s->mb_y+= 3*index; | |
119 | |
120 ff_init_block_index(s); | |
121 ff_update_block_index(s); | |
122 } | |
123 } | |
124 | |
125 static void h261_encode_motion(H261Context * h, int val){ | |
126 MpegEncContext * const s = &h->s; | |
127 int sign, code; | |
128 if(val==0){ | |
129 code = 0; | |
130 put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); | |
131 } | |
132 else{ | |
133 if(val > 15) | |
134 val -=32; | |
135 if(val < -16) | |
136 val+=32; | |
137 sign = val < 0; | |
138 code = sign ? -val : val; | |
139 put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); | |
140 put_bits(&s->pb,1,sign); | |
141 } | |
142 } | |
143 | |
144 static inline int get_cbp(MpegEncContext * s, | |
145 DCTELEM block[6][64]) | |
146 { | |
147 int i, cbp; | |
148 cbp= 0; | |
149 for (i = 0; i < 6; i++) { | |
150 if (s->block_last_index[i] >= 0) | |
151 cbp |= 1 << (5 - i); | |
152 } | |
153 return cbp; | |
154 } | |
155 void ff_h261_encode_mb(MpegEncContext * s, | |
156 DCTELEM block[6][64], | |
157 int motion_x, int motion_y) | |
158 { | |
159 H261Context * h = (H261Context *)s; | |
160 int mvd, mv_diff_x, mv_diff_y, i, cbp; | |
161 cbp = 63; // avoid warning | |
162 mvd = 0; | |
163 | |
164 h->current_mba++; | |
165 h->mtype = 0; | |
166 | |
167 if (!s->mb_intra){ | |
168 /* compute cbp */ | |
169 cbp= get_cbp(s, block); | |
170 | |
171 /* mvd indicates if this block is motion compensated */ | |
172 mvd = motion_x | motion_y; | |
173 | |
174 if((cbp | mvd | s->dquant ) == 0) { | |
175 /* skip macroblock */ | |
176 s->skip_count++; | |
177 h->current_mv_x=0; | |
178 h->current_mv_y=0; | |
179 return; | |
180 } | |
181 } | |
182 | |
183 /* MB is not skipped, encode MBA */ | |
184 put_bits(&s->pb, h261_mba_bits[(h->current_mba-h->previous_mba)-1], h261_mba_code[(h->current_mba-h->previous_mba)-1]); | |
185 | |
186 /* calculate MTYPE */ | |
187 if(!s->mb_intra){ | |
188 h->mtype++; | |
189 | |
190 if(mvd || s->loop_filter) | |
191 h->mtype+=3; | |
192 if(s->loop_filter) | |
193 h->mtype+=3; | |
194 if(cbp || s->dquant) | |
195 h->mtype++; | |
196 assert(h->mtype > 1); | |
197 } | |
198 | |
199 if(s->dquant) | |
200 h->mtype++; | |
201 | |
202 put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]); | |
203 | |
204 h->mtype = h261_mtype_map[h->mtype]; | |
205 | |
206 if(IS_QUANT(h->mtype)){ | |
207 ff_set_qscale(s,s->qscale+s->dquant); | |
208 put_bits(&s->pb, 5, s->qscale); | |
209 } | |
210 | |
211 if(IS_16X16(h->mtype)){ | |
212 mv_diff_x = (motion_x >> 1) - h->current_mv_x; | |
213 mv_diff_y = (motion_y >> 1) - h->current_mv_y; | |
214 h->current_mv_x = (motion_x >> 1); | |
215 h->current_mv_y = (motion_y >> 1); | |
216 h261_encode_motion(h,mv_diff_x); | |
217 h261_encode_motion(h,mv_diff_y); | |
218 } | |
219 | |
220 h->previous_mba = h->current_mba; | |
221 | |
222 if(HAS_CBP(h->mtype)){ | |
223 assert(cbp>0); | |
224 put_bits(&s->pb,h261_cbp_tab[cbp-1][1],h261_cbp_tab[cbp-1][0]); | |
225 } | |
226 for(i=0; i<6; i++) { | |
227 /* encode each block */ | |
228 h261_encode_block(h, block[i], i); | |
229 } | |
230 | |
231 if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){ | |
232 h->current_mv_x=0; | |
233 h->current_mv_y=0; | |
234 } | |
235 } | |
236 | |
237 void ff_h261_encode_init(MpegEncContext *s){ | |
238 static int done = 0; | |
239 | |
240 if (!done) { | |
241 done = 1; | |
242 init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); | |
243 } | |
244 | |
245 s->min_qcoeff= -127; | |
246 s->max_qcoeff= 127; | |
247 s->y_dc_scale_table= | |
248 s->c_dc_scale_table= ff_mpeg1_dc_scale_table; | |
249 } | |
250 | |
251 | |
252 /** | |
253 * encodes a 8x8 block. | |
254 * @param block the 8x8 block | |
255 * @param n block index (0-3 are luma, 4-5 are chroma) | |
256 */ | |
257 static void h261_encode_block(H261Context * h, DCTELEM * block, int n){ | |
258 MpegEncContext * const s = &h->s; | |
259 int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; | |
260 RLTable *rl; | |
261 | |
262 rl = &h261_rl_tcoeff; | |
263 if (s->mb_intra) { | |
264 /* DC coef */ | |
265 level = block[0]; | |
266 /* 255 cannot be represented, so we clamp */ | |
267 if (level > 254) { | |
268 level = 254; | |
269 block[0] = 254; | |
270 } | |
271 /* 0 cannot be represented also */ | |
272 else if (level < 1) { | |
273 level = 1; | |
274 block[0] = 1; | |
275 } | |
276 if (level == 128) | |
277 put_bits(&s->pb, 8, 0xff); | |
278 else | |
279 put_bits(&s->pb, 8, level); | |
280 i = 1; | |
281 } else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){ | |
282 //special case | |
283 put_bits(&s->pb,2,block[0]>0 ? 2 : 3 ); | |
284 i = 1; | |
285 } else { | |
286 i = 0; | |
287 } | |
288 | |
289 /* AC coefs */ | |
290 last_index = s->block_last_index[n]; | |
291 last_non_zero = i - 1; | |
292 for (; i <= last_index; i++) { | |
293 j = s->intra_scantable.permutated[i]; | |
294 level = block[j]; | |
295 if (level) { | |
296 run = i - last_non_zero - 1; | |
297 last = (i == last_index); | |
298 sign = 0; | |
299 slevel = level; | |
300 if (level < 0) { | |
301 sign = 1; | |
302 level = -level; | |
303 } | |
304 code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level); | |
305 if(run==0 && level < 16) | |
306 code+=1; | |
307 put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); | |
308 if (code == rl->n) { | |
309 put_bits(&s->pb, 6, run); | |
310 assert(slevel != 0); | |
311 assert(level <= 127); | |
312 put_bits(&s->pb, 8, slevel & 0xff); | |
313 } else { | |
314 put_bits(&s->pb, 1, sign); | |
315 } | |
316 last_non_zero = i; | |
317 } | |
318 } | |
319 if(last_index > -1){ | |
320 put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK | |
321 } | |
322 } | |
323 | |
324 AVCodec h261_encoder = { | |
325 "h261", | |
326 CODEC_TYPE_VIDEO, | |
327 CODEC_ID_H261, | |
328 sizeof(H261Context), | |
329 MPV_encode_init, | |
330 MPV_encode_picture, | |
331 MPV_encode_end, | |
332 .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, | |
333 }; | |
334 |