Originally committed as revision 3643 to svn://svn.ffmpeg.org/ffmpeg/trunk
Michael Niedermayer authored on 2004/10/28 19:12:57... | ... |
@@ -59,6 +59,7 @@ void avcodec_register_all(void) |
59 | 59 |
// register_avcodec(&h264_encoder); |
60 | 60 |
#ifdef CONFIG_RISKY |
61 | 61 |
register_avcodec(&mpeg2video_encoder); |
62 |
+ register_avcodec(&h261_encoder); |
|
62 | 63 |
register_avcodec(&h263_encoder); |
63 | 64 |
register_avcodec(&h263p_encoder); |
64 | 65 |
register_avcodec(&flv_encoder); |
... | ... |
@@ -1786,6 +1786,7 @@ extern AVCodec faac_encoder; |
1786 | 1786 |
extern AVCodec xvid_encoder; |
1787 | 1787 |
extern AVCodec mpeg1video_encoder; |
1788 | 1788 |
extern AVCodec mpeg2video_encoder; |
1789 |
+extern AVCodec h261_encoder; |
|
1789 | 1790 |
extern AVCodec h263_encoder; |
1790 | 1791 |
extern AVCodec h263p_encoder; |
1791 | 1792 |
extern AVCodec flv_encoder; |
... | ... |
@@ -47,6 +47,7 @@ typedef struct H261Context{ |
47 | 47 |
MpegEncContext s; |
48 | 48 |
|
49 | 49 |
int current_mba; |
50 |
+ int previous_mba; |
|
50 | 51 |
int mba_diff; |
51 | 52 |
int mtype; |
52 | 53 |
int current_mv_x; |
... | ... |
@@ -76,11 +77,330 @@ void ff_h261_loop_filter(MpegEncContext *s){ |
76 | 76 |
s->dsp.h261_loop_filter(dest_cr, uvlinesize); |
77 | 77 |
} |
78 | 78 |
|
79 |
+int ff_h261_get_picture_format(int width, int height){ |
|
80 |
+ // QCIF |
|
81 |
+ if (width == 176 && height == 144) |
|
82 |
+ return 0; |
|
83 |
+ // CIF |
|
84 |
+ else if (width == 352 && height == 288) |
|
85 |
+ return 1; |
|
86 |
+ // ERROR |
|
87 |
+ else |
|
88 |
+ return -1; |
|
89 |
+} |
|
90 |
+ |
|
91 |
+static void h261_encode_block(H261Context * h, DCTELEM * block, |
|
92 |
+ int n); |
|
79 | 93 |
static int h261_decode_block(H261Context *h, DCTELEM *block, |
80 | 94 |
int n, int coded); |
81 | 95 |
static int h261_decode_mb(H261Context *h); |
82 | 96 |
void ff_set_qscale(MpegEncContext * s, int qscale); |
83 | 97 |
|
98 |
+void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ |
|
99 |
+ H261Context * h = (H261Context *) s; |
|
100 |
+ int format, coded_frame_rate, coded_frame_rate_base, temp_ref; |
|
101 |
+ int best_clock_code=1; |
|
102 |
+ int best_divisor=60; |
|
103 |
+ coded_frame_rate= 1800000; |
|
104 |
+ coded_frame_rate_base= (1000+best_clock_code)*best_divisor; |
|
105 |
+ |
|
106 |
+ align_put_bits(&s->pb); |
|
107 |
+ |
|
108 |
+ /* Update the pointer to last GOB */ |
|
109 |
+ s->ptr_lastgob = pbBufPtr(&s->pb); |
|
110 |
+ |
|
111 |
+ put_bits(&s->pb, 20, 0x10); /* PSC */ |
|
112 |
+ |
|
113 |
+ temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->frame_rate_base / |
|
114 |
+ (coded_frame_rate_base * (int64_t)s->avctx->frame_rate); |
|
115 |
+ put_bits(&s->pb, 5, temp_ref & 0x1f); /* TemporalReference */ |
|
116 |
+ |
|
117 |
+ put_bits(&s->pb, 1, 0); /* split screen off */ |
|
118 |
+ put_bits(&s->pb, 1, 0); /* camera off */ |
|
119 |
+ put_bits(&s->pb, 1, 0); /* freeze picture release off */ |
|
120 |
+ |
|
121 |
+ format = ff_h261_get_picture_format(s->width, s->height); |
|
122 |
+ |
|
123 |
+ put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */ |
|
124 |
+ |
|
125 |
+ put_bits(&s->pb, 1, 0); /* still image mode */ |
|
126 |
+ put_bits(&s->pb, 1, 0); /* reserved */ |
|
127 |
+ |
|
128 |
+ put_bits(&s->pb, 1, 0); /* no PEI */ |
|
129 |
+ if(format == 0) |
|
130 |
+ h->gob_number = -1; |
|
131 |
+ else |
|
132 |
+ h->gob_number = 0; |
|
133 |
+ h->current_mba = 0; |
|
134 |
+} |
|
135 |
+ |
|
136 |
+/** |
|
137 |
+ * Encodes a group of blocks header. |
|
138 |
+ */ |
|
139 |
+static void h261_encode_gob_header(MpegEncContext * s, int mb_line){ |
|
140 |
+ H261Context * h = (H261Context *)s; |
|
141 |
+ if(ff_h261_get_picture_format(s->width, s->height) == 0){ |
|
142 |
+ h->gob_number+=2; // QCIF |
|
143 |
+ } |
|
144 |
+ else{ |
|
145 |
+ h->gob_number++; // CIF |
|
146 |
+ } |
|
147 |
+ put_bits(&s->pb, 16, 1); /* GBSC */ |
|
148 |
+ put_bits(&s->pb, 4, h->gob_number); /* GN */ |
|
149 |
+ put_bits(&s->pb, 5, s->qscale); /* GQUANT */ |
|
150 |
+ put_bits(&s->pb, 1, 0); /* no GEI */ |
|
151 |
+ h->current_mba = 0; |
|
152 |
+ h->previous_mba = 0; |
|
153 |
+ h->current_mv_x=0; |
|
154 |
+ h->current_mv_y=0; |
|
155 |
+} |
|
156 |
+ |
|
157 |
+void ff_h261_reorder_mb_index(MpegEncContext* s){ |
|
158 |
+ /* for CIF the GOB's are fragmented in the middle of a scanline |
|
159 |
+ that's why we need to adjust the x and y index of the macroblocks */ |
|
160 |
+ if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF |
|
161 |
+ if((s->mb_x == 0 && (s->mb_y % 3 == 0) ) || (s->mb_x == 11 && ((s->mb_y -1 )% 3 == 0) )) |
|
162 |
+ h261_encode_gob_header(s,0); |
|
163 |
+ if(s->mb_x < 11 ){ |
|
164 |
+ if((s->mb_y % 3) == 1 ){ |
|
165 |
+ s->mb_x += 0; |
|
166 |
+ s->mb_y += 1; |
|
167 |
+ } |
|
168 |
+ else if( (s->mb_y % 3) == 2 ){ |
|
169 |
+ s->mb_x += 11; |
|
170 |
+ s->mb_y -= 1; |
|
171 |
+ } |
|
172 |
+ } |
|
173 |
+ else{ |
|
174 |
+ if((s->mb_y % 3) == 1 ){ |
|
175 |
+ s->mb_x += 0; |
|
176 |
+ s->mb_y -= 1; |
|
177 |
+ } |
|
178 |
+ else if( (s->mb_y % 3) == 0 ){ |
|
179 |
+ s->mb_x -= 11; |
|
180 |
+ s->mb_y += 1; |
|
181 |
+ } |
|
182 |
+ } |
|
183 |
+ ff_init_block_index(s); |
|
184 |
+ ff_update_block_index(s); |
|
185 |
+ /* for QCIF we don't need to reorder MB's |
|
186 |
+ there the GOB's aren't fragmented in the middle of a scanline */ |
|
187 |
+ }else if(ff_h261_get_picture_format(s->width,s->height) == 0){ // QCIF |
|
188 |
+ if(s->mb_y % 3 == 0 && s->mb_x == 0) |
|
189 |
+ h261_encode_gob_header(s,0); |
|
190 |
+ } |
|
191 |
+} |
|
192 |
+ |
|
193 |
+static void h261_encode_motion(H261Context * h, int val){ |
|
194 |
+ MpegEncContext * const s = &h->s; |
|
195 |
+ int sign, code; |
|
196 |
+ if(val==0){ |
|
197 |
+ code = 0; |
|
198 |
+ put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); |
|
199 |
+ } |
|
200 |
+ else{ |
|
201 |
+ if(val > 16) |
|
202 |
+ val -=32; |
|
203 |
+ if(val < -16) |
|
204 |
+ val+=32; |
|
205 |
+ sign = val < 0; |
|
206 |
+ code = sign ? -val : val; |
|
207 |
+ put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); |
|
208 |
+ put_bits(&s->pb,1,sign); |
|
209 |
+ } |
|
210 |
+} |
|
211 |
+ |
|
212 |
+static inline int get_cbp(MpegEncContext * s, |
|
213 |
+ DCTELEM block[6][64]) |
|
214 |
+{ |
|
215 |
+ int i, cbp; |
|
216 |
+ cbp= 0; |
|
217 |
+ for (i = 0; i < 6; i++) { |
|
218 |
+ if (s->block_last_index[i] >= 0) |
|
219 |
+ cbp |= 1 << (5 - i); |
|
220 |
+ } |
|
221 |
+ return cbp; |
|
222 |
+} |
|
223 |
+void ff_h261_encode_mb(MpegEncContext * s, |
|
224 |
+ DCTELEM block[6][64], |
|
225 |
+ int motion_x, int motion_y) |
|
226 |
+{ |
|
227 |
+ H261Context * h = (H261Context *)s; |
|
228 |
+ int old_mtype, mvd, mv_diff_x, mv_diff_y, i, cbp; |
|
229 |
+ cbp = 63; // avoid warning |
|
230 |
+ mvd = 0; |
|
231 |
+ |
|
232 |
+ h->current_mba++; |
|
233 |
+ old_mtype = h->mtype; |
|
234 |
+ h->mtype = 0; |
|
235 |
+ |
|
236 |
+ if (!s->mb_intra){ |
|
237 |
+ /* compute cbp */ |
|
238 |
+ cbp= get_cbp(s, block); |
|
239 |
+ |
|
240 |
+ /* mvd indicates if this block is motion compensated */ |
|
241 |
+ if(((motion_x >> 1) - h->current_mv_x != 0) || ((motion_y >> 1 ) - h->current_mv_y) != 0){ |
|
242 |
+ mvd = 1; |
|
243 |
+ } |
|
244 |
+ else if((motion_x >> 1 == 0) && (motion_y >> 1 == 0)){ |
|
245 |
+ mvd = 0; |
|
246 |
+ } |
|
247 |
+ else |
|
248 |
+ mvd = 1; |
|
249 |
+ if((cbp | mvd | s->dquant ) == 0) { |
|
250 |
+ /* skip macroblock */ |
|
251 |
+ s->skip_count++; |
|
252 |
+ h->current_mv_x=0; |
|
253 |
+ h->current_mv_y=0; |
|
254 |
+ return; |
|
255 |
+ } |
|
256 |
+ } |
|
257 |
+ |
|
258 |
+ /* MB is not skipped, encode MBA */ |
|
259 |
+ put_bits(&s->pb, h261_mba_bits[(h->current_mba-h->previous_mba)-1], h261_mba_code[(h->current_mba-h->previous_mba)-1]); |
|
260 |
+ |
|
261 |
+ /* calculate MTYPE */ |
|
262 |
+ if(!s->mb_intra){ |
|
263 |
+ h->mtype+=2; |
|
264 |
+ if(mvd == 1){ |
|
265 |
+ h->mtype+=2; |
|
266 |
+ if(cbp!=0) |
|
267 |
+ h->mtype+=1; |
|
268 |
+ if(s->loop_filter) |
|
269 |
+ h->mtype+=3; |
|
270 |
+ } |
|
271 |
+ } |
|
272 |
+ |
|
273 |
+ if(s->dquant) |
|
274 |
+ h->mtype++; |
|
275 |
+ |
|
276 |
+ put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]); |
|
277 |
+ |
|
278 |
+ h->mtype = h261_mtype_map[h->mtype]; |
|
279 |
+ |
|
280 |
+ if(IS_QUANT(h->mtype)){ |
|
281 |
+ ff_set_qscale(s,s->qscale+s->dquant); |
|
282 |
+ put_bits(&s->pb, 5, s->qscale); |
|
283 |
+ } |
|
284 |
+ |
|
285 |
+ if(IS_16X16(h->mtype)){ |
|
286 |
+ mv_diff_x = (motion_x >> 1) - h->current_mv_x; |
|
287 |
+ mv_diff_y = (motion_y >> 1) - h->current_mv_y; |
|
288 |
+ h->current_mv_x = (motion_x >> 1); |
|
289 |
+ h->current_mv_y = (motion_y >> 1); |
|
290 |
+ h261_encode_motion(h,mv_diff_x); |
|
291 |
+ h261_encode_motion(h,mv_diff_y); |
|
292 |
+ } |
|
293 |
+ |
|
294 |
+ h->previous_mba = h->current_mba; |
|
295 |
+ |
|
296 |
+ if(HAS_CBP(h->mtype)){ |
|
297 |
+ put_bits(&s->pb,h261_cbp_tab[cbp-1][1],h261_cbp_tab[cbp-1][0]); |
|
298 |
+ } |
|
299 |
+ for(i=0; i<6; i++) { |
|
300 |
+ /* encode each block */ |
|
301 |
+ h261_encode_block(h, block[i], i); |
|
302 |
+ } |
|
303 |
+ |
|
304 |
+ if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){ |
|
305 |
+ h->current_mv_x=0; |
|
306 |
+ h->current_mv_y=0; |
|
307 |
+ } |
|
308 |
+} |
|
309 |
+ |
|
310 |
+void ff_h261_encode_init(MpegEncContext *s){ |
|
311 |
+ static int done = 0; |
|
312 |
+ |
|
313 |
+ if (!done) { |
|
314 |
+ done = 1; |
|
315 |
+ init_rl(&h261_rl_tcoeff); |
|
316 |
+ } |
|
317 |
+ |
|
318 |
+ s->min_qcoeff= -127; |
|
319 |
+ s->max_qcoeff= 127; |
|
320 |
+ s->y_dc_scale_table= |
|
321 |
+ s->c_dc_scale_table= ff_mpeg1_dc_scale_table; |
|
322 |
+} |
|
323 |
+ |
|
324 |
+ |
|
325 |
+/** |
|
326 |
+ * encodes a 8x8 block. |
|
327 |
+ * @param block the 8x8 block |
|
328 |
+ * @param n block index (0-3 are luma, 4-5 are chroma) |
|
329 |
+ */ |
|
330 |
+static void h261_encode_block(H261Context * h, DCTELEM * block, int n){ |
|
331 |
+ MpegEncContext * const s = &h->s; |
|
332 |
+ int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; |
|
333 |
+ RLTable *rl; |
|
334 |
+ |
|
335 |
+ rl = &h261_rl_tcoeff; |
|
336 |
+ if (s->mb_intra) { |
|
337 |
+ /* DC coef */ |
|
338 |
+ level = block[0]; |
|
339 |
+ /* 255 cannot be represented, so we clamp */ |
|
340 |
+ if (level > 254) { |
|
341 |
+ level = 254; |
|
342 |
+ block[0] = 254; |
|
343 |
+ } |
|
344 |
+ /* 0 cannot be represented also */ |
|
345 |
+ else if (level < 1) { |
|
346 |
+ level = 1; |
|
347 |
+ block[0] = 1; |
|
348 |
+ } |
|
349 |
+ if (level == 128) |
|
350 |
+ put_bits(&s->pb, 8, 0xff); |
|
351 |
+ else |
|
352 |
+ put_bits(&s->pb, 8, level); |
|
353 |
+ i = 1; |
|
354 |
+ } else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){ |
|
355 |
+ //special case |
|
356 |
+ put_bits(&s->pb,1,1); |
|
357 |
+ put_bits(&s->pb,1,block[0]>0 ? 0 : 1 ); |
|
358 |
+ i = 1; |
|
359 |
+ } else { |
|
360 |
+ i = 0; |
|
361 |
+ } |
|
362 |
+ |
|
363 |
+ /* AC coefs */ |
|
364 |
+ last_index = s->block_last_index[n]; |
|
365 |
+ last_non_zero = i - 1; |
|
366 |
+ for (; i <= last_index; i++) { |
|
367 |
+ j = s->intra_scantable.permutated[i]; |
|
368 |
+ level = block[j]; |
|
369 |
+ if (level) { |
|
370 |
+ run = i - last_non_zero - 1; |
|
371 |
+ last = (i == last_index); |
|
372 |
+ sign = 0; |
|
373 |
+ slevel = level; |
|
374 |
+ if (level < 0) { |
|
375 |
+ sign = 1; |
|
376 |
+ level = -level; |
|
377 |
+ } |
|
378 |
+ code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level); |
|
379 |
+ if(run==0 && level < 16) |
|
380 |
+ code+=1; |
|
381 |
+ put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); |
|
382 |
+ if (code == rl->n) { |
|
383 |
+ put_bits(&s->pb, 6, run); |
|
384 |
+ assert(slevel != 0); |
|
385 |
+ if(slevel < -127){ |
|
386 |
+ slevel = -127; |
|
387 |
+ } |
|
388 |
+ else if(slevel > 127){ |
|
389 |
+ slevel = 127; |
|
390 |
+ } |
|
391 |
+ put_bits(&s->pb, 8, slevel & 0xff); |
|
392 |
+ } else { |
|
393 |
+ put_bits(&s->pb, 1, sign); |
|
394 |
+ } |
|
395 |
+ last_non_zero = i; |
|
396 |
+ } |
|
397 |
+ } |
|
398 |
+ if(last_index > -1){ |
|
399 |
+ put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK |
|
400 |
+ } |
|
401 |
+} |
|
402 |
+ |
|
84 | 403 |
/***********************************************/ |
85 | 404 |
/* decoding */ |
86 | 405 |
|
... | ... |
@@ -767,6 +1087,16 @@ static int h261_decode_end(AVCodecContext *avctx) |
767 | 767 |
return 0; |
768 | 768 |
} |
769 | 769 |
|
770 |
+AVCodec h261_encoder = { |
|
771 |
+ "h261", |
|
772 |
+ CODEC_TYPE_VIDEO, |
|
773 |
+ CODEC_ID_H261, |
|
774 |
+ sizeof(H261Context), |
|
775 |
+ MPV_encode_init, |
|
776 |
+ MPV_encode_picture, |
|
777 |
+ MPV_encode_end, |
|
778 |
+}; |
|
779 |
+ |
|
770 | 780 |
AVCodec h261_decoder = { |
771 | 781 |
"h261", |
772 | 782 |
CODEC_TYPE_VIDEO, |
... | ... |
@@ -88,7 +88,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s, |
88 | 88 |
qmat = s->q_inter_matrix16[qscale][0]; |
89 | 89 |
} |
90 | 90 |
|
91 |
- if(s->out_format == FMT_H263 && s->mpeg_quant==0){ |
|
91 |
+ if((s->out_format == FMT_H263 || s->out_format == FMT_H261) && s->mpeg_quant==0){ |
|
92 | 92 |
|
93 | 93 |
asm volatile( |
94 | 94 |
"movd %%"REG_a", %%mm3 \n\t" // last_non_zero_p1 |
... | ... |
@@ -279,6 +279,10 @@ void ff_init_me(MpegEncContext *s){ |
279 | 279 |
c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel; |
280 | 280 |
} |
281 | 281 |
|
282 |
+ if(s->codec_id == CODEC_ID_H261){ |
|
283 |
+ c->sub_motion_search= no_sub_motion_search; |
|
284 |
+ } |
|
285 |
+ |
|
282 | 286 |
c->temp= c->scratchpad; |
283 | 287 |
} |
284 | 288 |
|
... | ... |
@@ -691,6 +695,12 @@ static inline void get_limits(MpegEncContext *s, int x, int y) |
691 | 691 |
c->ymin = - y - 16; |
692 | 692 |
c->xmax = - x + s->mb_width *16; |
693 | 693 |
c->ymax = - y + s->mb_height*16; |
694 |
+ } else if (s->out_format == FMT_H261){ |
|
695 |
+ // Search range of H261 is different from other codec standards |
|
696 |
+ c->xmin = (x > 15) ? - 15 : 0; |
|
697 |
+ c->ymin = (y > 15) ? - 15 : 0; |
|
698 |
+ c->xmax = (x < s->mb_width * 16 - 16) ? 15 : 0; |
|
699 |
+ c->ymax = (y < s->mb_height * 16 - 16) ? 15 : 0; |
|
694 | 700 |
} else { |
695 | 701 |
c->xmin = - x; |
696 | 702 |
c->ymin = - y; |
... | ... |
@@ -221,6 +221,16 @@ static int hpel_motion_search(MpegEncContext * s, |
221 | 221 |
} |
222 | 222 |
#endif |
223 | 223 |
|
224 |
+static int no_sub_motion_search(MpegEncContext * s, |
|
225 |
+ int *mx_ptr, int *my_ptr, int dmin, |
|
226 |
+ int src_index, int ref_index, |
|
227 |
+ int size, int h) |
|
228 |
+{ |
|
229 |
+ (*mx_ptr)<<=1; |
|
230 |
+ (*my_ptr)<<=1; |
|
231 |
+ return dmin; |
|
232 |
+} |
|
233 |
+ |
|
224 | 234 |
int inline ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, |
225 | 235 |
int ref_index, int size, int h, int add_rate) |
226 | 236 |
{ |
... | ... |
@@ -1080,6 +1080,11 @@ int MPV_encode_init(AVCodecContext *avctx) |
1080 | 1080 |
s->low_delay=1; |
1081 | 1081 |
break; |
1082 | 1082 |
#ifdef CONFIG_RISKY |
1083 |
+ case CODEC_ID_H261: |
|
1084 |
+ s->out_format = FMT_H261; |
|
1085 |
+ avctx->delay=0; |
|
1086 |
+ s->low_delay=1; |
|
1087 |
+ break; |
|
1083 | 1088 |
case CODEC_ID_H263: |
1084 | 1089 |
if (h263_get_picture_format(s->width, s->height) == 7) { |
1085 | 1090 |
av_log(avctx, AV_LOG_INFO, "Input picture size isn't suitable for h263 codec! try h263+\n"); |
... | ... |
@@ -1199,6 +1204,8 @@ int MPV_encode_init(AVCodecContext *avctx) |
1199 | 1199 |
|
1200 | 1200 |
#ifdef CONFIG_ENCODERS |
1201 | 1201 |
#ifdef CONFIG_RISKY |
1202 |
+ if (s->out_format == FMT_H261) |
|
1203 |
+ ff_h261_encode_init(s); |
|
1202 | 1204 |
if (s->out_format == FMT_H263) |
1203 | 1205 |
h263_encode_init(s); |
1204 | 1206 |
if(s->msmpeg4_version) |
... | ... |
@@ -1215,7 +1222,7 @@ int MPV_encode_init(AVCodecContext *avctx) |
1215 | 1215 |
if(s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){ |
1216 | 1216 |
s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i]; |
1217 | 1217 |
s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i]; |
1218 |
- }else if(s->out_format == FMT_H263){ |
|
1218 |
+ }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ |
|
1219 | 1219 |
s->intra_matrix[j] = |
1220 | 1220 |
s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; |
1221 | 1221 |
}else |
... | ... |
@@ -4127,6 +4134,8 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) |
4127 | 4127 |
msmpeg4_encode_mb(s, s->block, motion_x, motion_y); break; |
4128 | 4128 |
case CODEC_ID_WMV2: |
4129 | 4129 |
ff_wmv2_encode_mb(s, s->block, motion_x, motion_y); break; |
4130 |
+ case CODEC_ID_H261: |
|
4131 |
+ ff_h261_encode_mb(s, s->block, motion_x, motion_y); break; |
|
4130 | 4132 |
case CODEC_ID_H263: |
4131 | 4133 |
case CODEC_ID_H263P: |
4132 | 4134 |
case CODEC_ID_FLV1: |
... | ... |
@@ -4495,15 +4504,21 @@ static int encode_thread(AVCodecContext *c, void *arg){ |
4495 | 4495 |
ff_init_block_index(s); |
4496 | 4496 |
|
4497 | 4497 |
for(mb_x=0; mb_x < s->mb_width; mb_x++) { |
4498 |
- const int xy= mb_y*s->mb_stride + mb_x; |
|
4498 |
+ int xy= mb_y*s->mb_stride + mb_x; // removed const, H261 needs to adjust this |
|
4499 | 4499 |
int mb_type= s->mb_type[xy]; |
4500 | 4500 |
// int d; |
4501 | 4501 |
int dmin= INT_MAX; |
4502 | 4502 |
int dir; |
4503 | 4503 |
|
4504 | 4504 |
s->mb_x = mb_x; |
4505 |
+ s->mb_y = mb_y; // moved into loop, can get changed by H.261 |
|
4505 | 4506 |
ff_update_block_index(s); |
4506 | 4507 |
|
4508 |
+ if(s->codec_id == CODEC_ID_H261){ |
|
4509 |
+ ff_h261_reorder_mb_index(s); |
|
4510 |
+ xy= s->mb_y*s->mb_stride + s->mb_x; |
|
4511 |
+ } |
|
4512 |
+ |
|
4507 | 4513 |
/* write gob / video packet header */ |
4508 | 4514 |
#ifdef CONFIG_RISKY |
4509 | 4515 |
if(s->rtp_mode){ |
... | ... |
@@ -5215,6 +5230,9 @@ static void encode_picture(MpegEncContext *s, int picture_number) |
5215 | 5215 |
mjpeg_picture_header(s); |
5216 | 5216 |
break; |
5217 | 5217 |
#ifdef CONFIG_RISKY |
5218 |
+ case FMT_H261: |
|
5219 |
+ ff_h261_encode_picture_header(s, picture_number); |
|
5220 |
+ break; |
|
5218 | 5221 |
case FMT_H263: |
5219 | 5222 |
if (s->codec_id == CODEC_ID_WMV2) |
5220 | 5223 |
ff_wmv2_encode_picture_header(s, picture_number); |
... | ... |
@@ -865,6 +865,12 @@ extern const uint8_t ff_h263_loop_filter_strength[32]; |
865 | 865 |
|
866 | 866 |
/* h261.c */ |
867 | 867 |
void ff_h261_loop_filter(MpegEncContext *s); |
868 |
+void ff_h261_reorder_mb_index(MpegEncContext* s); |
|
869 |
+void ff_h261_encode_mb(MpegEncContext *s, |
|
870 |
+ DCTELEM block[6][64], |
|
871 |
+ int motion_x, int motion_y); |
|
872 |
+void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number); |
|
873 |
+void ff_h261_encode_init(MpegEncContext *s); |
|
868 | 874 |
|
869 | 875 |
|
870 | 876 |
/* h263.c, h263dec.c */ |
... | ... |
@@ -344,6 +344,21 @@ AVInputFormat h261_iformat = { |
344 | 344 |
.value = CODEC_ID_H261, |
345 | 345 |
}; |
346 | 346 |
|
347 |
+#ifdef CONFIG_ENCODERS |
|
348 |
+AVOutputFormat h261_oformat = { |
|
349 |
+ "h261", |
|
350 |
+ "raw h261", |
|
351 |
+ "video/x-h261", |
|
352 |
+ "h261", |
|
353 |
+ 0, |
|
354 |
+ 0, |
|
355 |
+ CODEC_ID_H261, |
|
356 |
+ raw_write_header, |
|
357 |
+ raw_write_packet, |
|
358 |
+ raw_write_trailer, |
|
359 |
+}; |
|
360 |
+#endif //CONFIG_ENCODERS |
|
361 |
+ |
|
347 | 362 |
AVInputFormat h263_iformat = { |
348 | 363 |
"h263", |
349 | 364 |
"raw h263", |
... | ... |
@@ -648,6 +663,7 @@ int raw_init(void) |
648 | 648 |
av_register_input_format(&dts_iformat); |
649 | 649 |
|
650 | 650 |
av_register_input_format(&h261_iformat); |
651 |
+ av_register_output_format(&h261_oformat); |
|
651 | 652 |
|
652 | 653 |
av_register_input_format(&h263_iformat); |
653 | 654 |
av_register_output_format(&h263_oformat); |