Mercurial > libavcodec.hg
annotate mpegvideo.c @ 229:f418b5c5ff67 libavcodec
PATCH by Rik Snel <rsnel@cube.dyndns.org>
this patch enhances the jpeg header writer. It can be asked to omit
quantisation and huffman tables and it can write different horizontal and
vertical sampling factors. (the last thing is useless for libavcodec
itself (because libavcodec only handles YUV420P at ecoder level), but the
values are initialized so that operation of libavcodec is not impaired)
| author | arpi_esp |
|---|---|
| date | Sat, 09 Feb 2002 01:23:41 +0000 |
| parents | ec1bc02a0a47 |
| children | ba9cd6fb6f0e |
| rev | line source |
|---|---|
| 0 | 1 /* |
| 2 * The simplest mpeg encoder (well, it was the simplest!) | |
| 3 * Copyright (c) 2000,2001 Gerard Lantau. | |
| 4 * | |
| 5 * This program is free software; you can redistribute it and/or modify | |
| 6 * it under the terms of the GNU General Public License as published by | |
| 7 * the Free Software Foundation; either version 2 of the License, or | |
| 8 * (at your option) any later version. | |
| 9 * | |
| 10 * This program is distributed in the hope that it will be useful, | |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 13 * GNU General Public License for more details. | |
| 14 * | |
| 15 * You should have received a copy of the GNU General Public License | |
| 16 * along with this program; if not, write to the Free Software | |
| 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 18 */ | |
| 19 #include <stdlib.h> | |
| 20 #include <stdio.h> | |
| 21 #include <math.h> | |
| 22 #include <string.h> | |
| 23 #include "avcodec.h" | |
| 24 #include "dsputil.h" | |
| 25 #include "mpegvideo.h" | |
| 26 | |
|
17
b69fe46fd708
Adding fastmemcpy stuff to speedup mplayer project
nickols_k
parents:
13
diff
changeset
|
27 #ifdef USE_FASTMEMCPY |
|
b69fe46fd708
Adding fastmemcpy stuff to speedup mplayer project
nickols_k
parents:
13
diff
changeset
|
28 #include "fastmemcpy.h" |
|
b69fe46fd708
Adding fastmemcpy stuff to speedup mplayer project
nickols_k
parents:
13
diff
changeset
|
29 #endif |
|
b69fe46fd708
Adding fastmemcpy stuff to speedup mplayer project
nickols_k
parents:
13
diff
changeset
|
30 |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
31 static void encode_picture(MpegEncContext *s, int picture_number); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
32 static void rate_control_init(MpegEncContext *s); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
33 static int rate_estimate_qscale(MpegEncContext *s); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
34 static void dct_unquantize_mpeg1_c(MpegEncContext *s, |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
35 DCTELEM *block, int n, int qscale); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
36 static void dct_unquantize_h263_c(MpegEncContext *s, |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
37 DCTELEM *block, int n, int qscale); |
| 206 | 38 static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w); |
| 220 | 39 static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale); |
| 206 | 40 |
| 220 | 41 int (*dct_quantize)(MpegEncContext *s, DCTELEM *block, int n, int qscale)= dct_quantize_c; |
| 206 | 42 void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edges_c; |
| 43 | |
| 0 | 44 #define EDGE_WIDTH 16 |
| 45 | |
| 46 /* enable all paranoid tests for rounding, overflows, etc... */ | |
| 47 //#define PARANOID | |
| 48 | |
| 49 //#define DEBUG | |
| 50 | |
| 51 /* for jpeg fast DCT */ | |
| 52 #define CONST_BITS 14 | |
| 53 | |
| 54 static const unsigned short aanscales[64] = { | |
| 55 /* precomputed values scaled up by 14 bits */ | |
| 56 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, | |
| 57 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, | |
| 58 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, | |
| 59 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, | |
| 60 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, | |
| 61 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, | |
| 62 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, | |
| 63 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 | |
| 64 }; | |
| 65 | |
| 66 static UINT8 h263_chroma_roundtab[16] = { | |
| 67 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, | |
| 68 }; | |
| 69 | |
| 70 /* default motion estimation */ | |
| 71 int motion_estimation_method = ME_LOG; | |
| 72 | |
| 200 | 73 extern UINT8 zigzag_end[64]; |
| 74 | |
| 220 | 75 static void convert_matrix(int *qmat, UINT16 *qmat16, const UINT16 *quant_matrix, int qscale) |
| 0 | 76 { |
| 77 int i; | |
| 78 | |
| 79 if (av_fdct == jpeg_fdct_ifast) { | |
| 80 for(i=0;i<64;i++) { | |
| 81 /* 16 <= qscale * quant_matrix[i] <= 7905 */ | |
| 220 | 82 /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ |
| 83 /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */ | |
| 84 /* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */ | |
| 0 | 85 |
| 220 | 86 qmat[block_permute_op(i)] = (int)((UINT64_C(1) << (QMAT_SHIFT + 11)) / |
| 87 (aanscales[i] * qscale * quant_matrix[block_permute_op(i)])); | |
| 0 | 88 } |
| 89 } else { | |
| 90 for(i=0;i<64;i++) { | |
| 91 /* We can safely suppose that 16 <= quant_matrix[i] <= 255 | |
| 220 | 92 So 16 <= qscale * quant_matrix[i] <= 7905 |
| 93 so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905 | |
| 94 so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67 | |
| 0 | 95 */ |
| 220 | 96 qmat[i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]); |
| 97 qmat16[i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[block_permute_op(i)]); | |
| 0 | 98 } |
| 99 } | |
| 100 } | |
| 101 | |
| 102 /* init common structure for both encoder and decoder */ | |
| 103 int MPV_common_init(MpegEncContext *s) | |
| 104 { | |
| 105 int c_size, i; | |
| 106 UINT8 *pict; | |
| 107 | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
108 if (s->out_format == FMT_H263) |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
109 s->dct_unquantize = dct_unquantize_h263_c; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
110 else |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
111 s->dct_unquantize = dct_unquantize_mpeg1_c; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
112 |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
113 #ifdef HAVE_MMX |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
114 MPV_common_init_mmx(s); |
| 8 | 115 #endif |
| 0 | 116 s->mb_width = (s->width + 15) / 16; |
| 117 s->mb_height = (s->height + 15) / 16; | |
| 118 s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH; | |
| 119 | |
| 120 for(i=0;i<3;i++) { | |
| 121 int w, h, shift, pict_start; | |
| 122 | |
| 123 w = s->linesize; | |
| 124 h = s->mb_height * 16 + 2 * EDGE_WIDTH; | |
| 125 shift = (i == 0) ? 0 : 1; | |
| 126 c_size = (w >> shift) * (h >> shift); | |
| 127 pict_start = (w >> shift) * (EDGE_WIDTH >> shift) + (EDGE_WIDTH >> shift); | |
| 128 | |
| 129 pict = av_mallocz(c_size); | |
| 130 if (pict == NULL) | |
| 131 goto fail; | |
| 132 s->last_picture_base[i] = pict; | |
| 133 s->last_picture[i] = pict + pict_start; | |
| 134 | |
| 135 pict = av_mallocz(c_size); | |
| 136 if (pict == NULL) | |
| 137 goto fail; | |
| 138 s->next_picture_base[i] = pict; | |
| 139 s->next_picture[i] = pict + pict_start; | |
| 140 | |
| 141 if (s->has_b_frames) { | |
| 142 pict = av_mallocz(c_size); | |
| 143 if (pict == NULL) | |
| 144 goto fail; | |
| 145 s->aux_picture_base[i] = pict; | |
| 146 s->aux_picture[i] = pict + pict_start; | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 if (s->out_format == FMT_H263) { | |
| 151 int size; | |
| 152 /* MV prediction */ | |
| 153 size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2); | |
| 154 s->motion_val = malloc(size * 2 * sizeof(INT16)); | |
| 155 if (s->motion_val == NULL) | |
| 156 goto fail; | |
| 157 memset(s->motion_val, 0, size * 2 * sizeof(INT16)); | |
| 158 } | |
| 159 | |
| 160 if (s->h263_pred) { | |
| 161 int y_size, c_size, i, size; | |
| 162 | |
| 163 /* dc values */ | |
| 164 | |
| 165 y_size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2); | |
| 166 c_size = (s->mb_width + 2) * (s->mb_height + 2); | |
| 167 size = y_size + 2 * c_size; | |
| 168 s->dc_val[0] = malloc(size * sizeof(INT16)); | |
| 169 if (s->dc_val[0] == NULL) | |
| 170 goto fail; | |
| 171 s->dc_val[1] = s->dc_val[0] + y_size; | |
| 172 s->dc_val[2] = s->dc_val[1] + c_size; | |
| 173 for(i=0;i<size;i++) | |
| 174 s->dc_val[0][i] = 1024; | |
| 175 | |
| 176 /* ac values */ | |
| 177 s->ac_val[0] = av_mallocz(size * sizeof(INT16) * 16); | |
| 178 if (s->ac_val[0] == NULL) | |
| 179 goto fail; | |
| 180 s->ac_val[1] = s->ac_val[0] + y_size; | |
| 181 s->ac_val[2] = s->ac_val[1] + c_size; | |
| 182 | |
| 183 /* cbp values */ | |
| 184 s->coded_block = av_mallocz(y_size); | |
| 185 if (!s->coded_block) | |
| 186 goto fail; | |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
187 |
|
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
188 /* which mb is a intra block */ |
|
196
9ffa69cd4ed6
This fixes segfaults because of uninitialized s->mbintra_table variable - patch by Vladimir Dergachev <volodya@mindspring.com>
arpi_esp
parents:
194
diff
changeset
|
189 s->mbintra_table = av_mallocz(s->mb_width * s->mb_height); |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
190 if (!s->mbintra_table) |
|
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
191 goto fail; |
|
196
9ffa69cd4ed6
This fixes segfaults because of uninitialized s->mbintra_table variable - patch by Vladimir Dergachev <volodya@mindspring.com>
arpi_esp
parents:
194
diff
changeset
|
192 memset(s->mbintra_table, 1, s->mb_width * s->mb_height); |
|
197
21abf1b20016
different fix, s->mbintra_table used only if h263_pred set. - patch by Michael Niedermayer <michaelni@gmx.at>
arpi_esp
parents:
196
diff
changeset
|
193 } |
| 0 | 194 /* default structure is frame */ |
| 195 s->picture_structure = PICT_FRAME; | |
| 196 | |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
197 /* init macroblock skip table */ |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
198 if (!s->encoding) { |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
199 s->mbskip_table = av_mallocz(s->mb_width * s->mb_height); |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
200 if (!s->mbskip_table) |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
201 goto fail; |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
202 } |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
203 |
| 0 | 204 s->context_initialized = 1; |
| 205 return 0; | |
| 206 fail: | |
| 207 if (s->motion_val) | |
| 208 free(s->motion_val); | |
| 209 if (s->dc_val[0]) | |
| 210 free(s->dc_val[0]); | |
| 211 if (s->ac_val[0]) | |
| 212 free(s->ac_val[0]); | |
| 213 if (s->coded_block) | |
| 214 free(s->coded_block); | |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
215 if (s->mbintra_table) |
|
197
21abf1b20016
different fix, s->mbintra_table used only if h263_pred set. - patch by Michael Niedermayer <michaelni@gmx.at>
arpi_esp
parents:
196
diff
changeset
|
216 free(s->mbintra_table); |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
217 if (s->mbskip_table) |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
218 free(s->mbskip_table); |
| 0 | 219 for(i=0;i<3;i++) { |
| 220 if (s->last_picture_base[i]) | |
| 221 free(s->last_picture_base[i]); | |
| 222 if (s->next_picture_base[i]) | |
| 223 free(s->next_picture_base[i]); | |
| 224 if (s->aux_picture_base[i]) | |
| 225 free(s->aux_picture_base[i]); | |
| 226 } | |
| 227 return -1; | |
| 228 } | |
| 229 | |
| 230 /* init common structure for both encoder and decoder */ | |
| 231 void MPV_common_end(MpegEncContext *s) | |
| 232 { | |
| 233 int i; | |
| 234 | |
| 235 if (s->motion_val) | |
| 236 free(s->motion_val); | |
| 237 if (s->h263_pred) { | |
| 238 free(s->dc_val[0]); | |
| 239 free(s->ac_val[0]); | |
| 240 free(s->coded_block); | |
|
197
21abf1b20016
different fix, s->mbintra_table used only if h263_pred set. - patch by Michael Niedermayer <michaelni@gmx.at>
arpi_esp
parents:
196
diff
changeset
|
241 free(s->mbintra_table); |
| 0 | 242 } |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
243 if (s->mbskip_table) |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
244 free(s->mbskip_table); |
| 0 | 245 for(i=0;i<3;i++) { |
| 246 free(s->last_picture_base[i]); | |
| 247 free(s->next_picture_base[i]); | |
| 248 if (s->has_b_frames) | |
| 249 free(s->aux_picture_base[i]); | |
| 250 } | |
| 251 s->context_initialized = 0; | |
| 252 } | |
| 253 | |
| 254 /* init video encoder */ | |
| 255 int MPV_encode_init(AVCodecContext *avctx) | |
| 256 { | |
| 257 MpegEncContext *s = avctx->priv_data; | |
| 60 | 258 int i; |
| 0 | 259 |
| 260 s->bit_rate = avctx->bit_rate; | |
| 261 s->frame_rate = avctx->frame_rate; | |
| 262 s->width = avctx->width; | |
| 263 s->height = avctx->height; | |
| 264 s->gop_size = avctx->gop_size; | |
| 162 | 265 s->rtp_mode = avctx->rtp_mode; |
| 266 s->rtp_payload_size = avctx->rtp_payload_size; | |
|
194
27d1773552c9
mpeg4 encoder fix by Michael Niedermayer <michaelni@gmx.at>
arpi_esp
parents:
191
diff
changeset
|
267 s->avctx = avctx; |
| 162 | 268 |
| 0 | 269 if (s->gop_size <= 1) { |
| 270 s->intra_only = 1; | |
| 271 s->gop_size = 12; | |
| 272 } else { | |
| 273 s->intra_only = 0; | |
| 274 } | |
| 275 s->full_search = motion_estimation_method; | |
| 276 | |
| 277 s->fixed_qscale = (avctx->flags & CODEC_FLAG_QSCALE); | |
| 278 | |
| 279 switch(avctx->codec->id) { | |
| 280 case CODEC_ID_MPEG1VIDEO: | |
| 281 s->out_format = FMT_MPEG1; | |
| 282 break; | |
| 283 case CODEC_ID_MJPEG: | |
| 284 s->out_format = FMT_MJPEG; | |
| 285 s->intra_only = 1; /* force intra only for jpeg */ | |
| 229 | 286 s->mjpeg_write_tables = 1; /* write all tables */ |
| 287 s->mjpeg_vsample[0] = 2; /* set up default sampling factors */ | |
| 288 s->mjpeg_vsample[1] = 1; /* the only currently supported values */ | |
| 289 s->mjpeg_vsample[2] = 1; | |
| 290 s->mjpeg_hsample[0] = 2; | |
| 291 s->mjpeg_hsample[1] = 1; | |
| 292 s->mjpeg_hsample[2] = 1; | |
| 0 | 293 if (mjpeg_init(s) < 0) |
| 294 return -1; | |
| 295 break; | |
| 296 case CODEC_ID_H263: | |
| 178 | 297 if (h263_get_picture_format(s->width, s->height) == 7){ |
| 298 printf("Input picture size isn't suitable for h263 codec! try h263+\n"); | |
| 0 | 299 return -1; |
| 178 | 300 } |
| 0 | 301 s->out_format = FMT_H263; |
| 302 break; | |
| 303 case CODEC_ID_H263P: | |
| 304 s->out_format = FMT_H263; | |
| 162 | 305 s->rtp_mode = 1; |
| 306 s->rtp_payload_size = 1200; | |
| 0 | 307 s->h263_plus = 1; |
| 78 | 308 s->unrestricted_mv = 1; |
|
79
82e579c37bc3
Moved some H.263+ variables to MpegEncContext to be thread-safe.
pulento
parents:
78
diff
changeset
|
309 |
|
82e579c37bc3
Moved some H.263+ variables to MpegEncContext to be thread-safe.
pulento
parents:
78
diff
changeset
|
310 /* These are just to be sure */ |
|
82e579c37bc3
Moved some H.263+ variables to MpegEncContext to be thread-safe.
pulento
parents:
78
diff
changeset
|
311 s->umvplus = 0; |
|
82e579c37bc3
Moved some H.263+ variables to MpegEncContext to be thread-safe.
pulento
parents:
78
diff
changeset
|
312 s->umvplus_dec = 0; |
| 0 | 313 break; |
| 314 case CODEC_ID_RV10: | |
| 315 s->out_format = FMT_H263; | |
| 316 s->h263_rv10 = 1; | |
| 317 break; | |
| 71 | 318 case CODEC_ID_MPEG4: |
| 0 | 319 s->out_format = FMT_H263; |
| 320 s->h263_pred = 1; | |
| 321 s->unrestricted_mv = 1; | |
| 322 break; | |
| 323 case CODEC_ID_MSMPEG4: | |
| 324 s->out_format = FMT_H263; | |
| 325 s->h263_msmpeg4 = 1; | |
| 326 s->h263_pred = 1; | |
| 327 s->unrestricted_mv = 1; | |
| 328 break; | |
| 329 default: | |
| 330 return -1; | |
| 331 } | |
| 332 | |
| 333 if (s->out_format == FMT_H263) | |
| 334 h263_encode_init_vlc(s); | |
| 335 | |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
336 s->encoding = 1; |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
337 |
| 0 | 338 /* init */ |
| 339 if (MPV_common_init(s) < 0) | |
| 340 return -1; | |
| 341 | |
| 60 | 342 /* init default q matrix */ |
| 343 for(i=0;i<64;i++) { | |
| 344 s->intra_matrix[i] = default_intra_matrix[i]; | |
| 345 s->non_intra_matrix[i] = default_non_intra_matrix[i]; | |
| 346 } | |
| 347 | |
| 0 | 348 /* rate control init */ |
| 349 rate_control_init(s); | |
| 350 | |
| 351 s->picture_number = 0; | |
| 352 s->fake_picture_number = 0; | |
| 353 /* motion detector init */ | |
| 354 s->f_code = 1; | |
| 355 | |
| 356 return 0; | |
| 357 } | |
| 358 | |
| 359 int MPV_encode_end(AVCodecContext *avctx) | |
| 360 { | |
| 361 MpegEncContext *s = avctx->priv_data; | |
| 362 | |
| 363 #ifdef STATS | |
| 364 print_stats(); | |
| 365 #endif | |
| 366 MPV_common_end(s); | |
| 367 if (s->out_format == FMT_MJPEG) | |
| 368 mjpeg_close(s); | |
| 369 return 0; | |
| 370 } | |
| 371 | |
| 372 /* draw the edges of width 'w' of an image of size width, height */ | |
| 206 | 373 static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w) |
| 0 | 374 { |
| 375 UINT8 *ptr, *last_line; | |
| 376 int i; | |
| 377 | |
| 378 last_line = buf + (height - 1) * wrap; | |
| 379 for(i=0;i<w;i++) { | |
| 380 /* top and bottom */ | |
| 381 memcpy(buf - (i + 1) * wrap, buf, width); | |
| 382 memcpy(last_line + (i + 1) * wrap, last_line, width); | |
| 383 } | |
| 384 /* left and right */ | |
| 385 ptr = buf; | |
| 386 for(i=0;i<height;i++) { | |
| 387 memset(ptr - w, ptr[0], w); | |
| 388 memset(ptr + width, ptr[width-1], w); | |
| 389 ptr += wrap; | |
| 390 } | |
| 391 /* corners */ | |
| 392 for(i=0;i<w;i++) { | |
| 393 memset(buf - (i + 1) * wrap - w, buf[0], w); /* top left */ | |
| 394 memset(buf - (i + 1) * wrap + width, buf[width-1], w); /* top right */ | |
| 395 memset(last_line + (i + 1) * wrap - w, last_line[0], w); /* top left */ | |
| 396 memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */ | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 /* generic function for encode/decode called before a frame is coded/decoded */ | |
| 401 void MPV_frame_start(MpegEncContext *s) | |
| 402 { | |
| 403 int i; | |
| 404 UINT8 *tmp; | |
| 405 | |
|
46
931417475f5b
fixed mpeg1 first block bug (pb with black picture optimisation for B frames)
glantau
parents:
40
diff
changeset
|
406 s->mb_skiped = 0; |
| 0 | 407 if (s->pict_type == B_TYPE) { |
| 408 for(i=0;i<3;i++) { | |
| 409 s->current_picture[i] = s->aux_picture[i]; | |
| 410 } | |
| 411 } else { | |
| 412 for(i=0;i<3;i++) { | |
| 413 /* swap next and last */ | |
| 414 tmp = s->last_picture[i]; | |
| 415 s->last_picture[i] = s->next_picture[i]; | |
| 416 s->next_picture[i] = tmp; | |
| 417 s->current_picture[i] = tmp; | |
| 418 } | |
| 419 } | |
| 420 } | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
421 |
| 0 | 422 /* generic function for encode/decode called after a frame has been coded/decoded */ |
| 423 void MPV_frame_end(MpegEncContext *s) | |
| 424 { | |
| 425 /* draw edge for correct motion prediction if outside */ | |
| 220 | 426 if (s->pict_type != B_TYPE && !s->intra_only) { |
|
198
82ba367b1827
rv10 sig11 fix by Michael Niedermayer <michaelni@gmx.at>
arpi_esp
parents:
197
diff
changeset
|
427 if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4){ |
|
176
9ce215ee9216
unrestricted MC fixed - thanks to Michael Niedermayer for idea
arpi_esp
parents:
162
diff
changeset
|
428 draw_edges(s->current_picture[0], s->linesize, s->mb_width*16, s->mb_height*16, EDGE_WIDTH); |
|
9ce215ee9216
unrestricted MC fixed - thanks to Michael Niedermayer for idea
arpi_esp
parents:
162
diff
changeset
|
429 draw_edges(s->current_picture[1], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2); |
|
9ce215ee9216
unrestricted MC fixed - thanks to Michael Niedermayer for idea
arpi_esp
parents:
162
diff
changeset
|
430 draw_edges(s->current_picture[2], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2); |
|
189
42552c1cf360
fix different UMV handling for mpeg4 vs. h263 - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
187
diff
changeset
|
431 }else{ |
|
42552c1cf360
fix different UMV handling for mpeg4 vs. h263 - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
187
diff
changeset
|
432 /* OpenDivx, but i dunno how to distinguish it from mpeg4 */ |
| 0 | 433 draw_edges(s->current_picture[0], s->linesize, s->width, s->height, EDGE_WIDTH); |
| 434 draw_edges(s->current_picture[1], s->linesize/2, s->width/2, s->height/2, EDGE_WIDTH/2); | |
| 435 draw_edges(s->current_picture[2], s->linesize/2, s->width/2, s->height/2, EDGE_WIDTH/2); | |
|
189
42552c1cf360
fix different UMV handling for mpeg4 vs. h263 - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
187
diff
changeset
|
436 } |
| 0 | 437 } |
| 207 | 438 emms_c(); |
| 0 | 439 } |
| 440 | |
| 441 int MPV_encode_picture(AVCodecContext *avctx, | |
| 442 unsigned char *buf, int buf_size, void *data) | |
| 443 { | |
| 444 MpegEncContext *s = avctx->priv_data; | |
| 445 AVPicture *pict = data; | |
| 446 int i, j; | |
| 447 | |
| 448 if (s->fixed_qscale) | |
| 449 s->qscale = avctx->quality; | |
| 450 | |
| 451 init_put_bits(&s->pb, buf, buf_size, NULL, NULL); | |
| 452 | |
| 453 if (!s->intra_only) { | |
| 454 /* first picture of GOP is intra */ | |
| 455 if ((s->picture_number % s->gop_size) == 0) | |
| 456 s->pict_type = I_TYPE; | |
| 457 else | |
| 458 s->pict_type = P_TYPE; | |
| 459 } else { | |
| 460 s->pict_type = I_TYPE; | |
| 461 } | |
| 462 avctx->key_frame = (s->pict_type == I_TYPE); | |
| 463 | |
| 464 MPV_frame_start(s); | |
| 220 | 465 |
| 0 | 466 for(i=0;i<3;i++) { |
| 467 UINT8 *src = pict->data[i]; | |
| 468 UINT8 *dest = s->current_picture[i]; | |
| 469 int src_wrap = pict->linesize[i]; | |
| 470 int dest_wrap = s->linesize; | |
| 471 int w = s->width; | |
| 472 int h = s->height; | |
| 473 | |
| 474 if (i >= 1) { | |
| 475 dest_wrap >>= 1; | |
| 476 w >>= 1; | |
| 477 h >>= 1; | |
| 478 } | |
| 479 | |
|
227
ec1bc02a0a47
avoid copying input when encoding non intra stuff too
michaelni
parents:
220
diff
changeset
|
480 if(dest_wrap==src_wrap){ |
|
ec1bc02a0a47
avoid copying input when encoding non intra stuff too
michaelni
parents:
220
diff
changeset
|
481 s->new_picture[i] = pict->data[i]; |
| 220 | 482 }else { |
| 483 for(j=0;j<h;j++) { | |
| 484 memcpy(dest, src, w); | |
| 485 dest += dest_wrap; | |
| 486 src += src_wrap; | |
| 487 } | |
|
227
ec1bc02a0a47
avoid copying input when encoding non intra stuff too
michaelni
parents:
220
diff
changeset
|
488 s->new_picture[i] = s->current_picture[i]; |
| 220 | 489 } |
| 0 | 490 } |
| 491 | |
| 492 encode_picture(s, s->picture_number); | |
| 493 | |
| 494 MPV_frame_end(s); | |
| 495 s->picture_number++; | |
| 496 | |
| 497 if (s->out_format == FMT_MJPEG) | |
| 498 mjpeg_picture_trailer(s); | |
| 499 | |
| 500 flush_put_bits(&s->pb); | |
| 501 s->total_bits += (s->pb.buf_ptr - s->pb.buf) * 8; | |
| 502 avctx->quality = s->qscale; | |
| 503 return s->pb.buf_ptr - s->pb.buf; | |
| 504 } | |
| 505 | |
| 506 static inline int clip(int a, int amin, int amax) | |
| 507 { | |
| 508 if (a < amin) | |
| 509 return amin; | |
| 510 else if (a > amax) | |
| 511 return amax; | |
| 512 else | |
| 513 return a; | |
| 514 } | |
| 515 | |
| 516 /* apply one mpeg motion vector to the three components */ | |
| 517 static inline void mpeg_motion(MpegEncContext *s, | |
| 518 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, | |
| 519 int dest_offset, | |
| 520 UINT8 **ref_picture, int src_offset, | |
| 521 int field_based, op_pixels_func *pix_op, | |
| 522 int motion_x, int motion_y, int h) | |
| 523 { | |
| 524 UINT8 *ptr; | |
| 525 int dxy, offset, mx, my, src_x, src_y, height, linesize; | |
| 526 | |
| 527 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
| 528 src_x = s->mb_x * 16 + (motion_x >> 1); | |
| 529 src_y = s->mb_y * (16 >> field_based) + (motion_y >> 1); | |
| 530 | |
| 531 /* WARNING: do no forget half pels */ | |
| 532 height = s->height >> field_based; | |
| 533 src_x = clip(src_x, -16, s->width); | |
| 534 if (src_x == s->width) | |
| 535 dxy &= ~1; | |
| 536 src_y = clip(src_y, -16, height); | |
| 537 if (src_y == height) | |
| 538 dxy &= ~2; | |
| 539 linesize = s->linesize << field_based; | |
| 540 ptr = ref_picture[0] + (src_y * linesize) + (src_x) + src_offset; | |
| 541 dest_y += dest_offset; | |
| 542 pix_op[dxy](dest_y, ptr, linesize, h); | |
| 543 pix_op[dxy](dest_y + 8, ptr + 8, linesize, h); | |
| 544 | |
| 545 if (s->out_format == FMT_H263) { | |
| 546 dxy = 0; | |
| 547 if ((motion_x & 3) != 0) | |
| 548 dxy |= 1; | |
| 549 if ((motion_y & 3) != 0) | |
| 550 dxy |= 2; | |
| 551 mx = motion_x >> 2; | |
| 552 my = motion_y >> 2; | |
| 553 } else { | |
| 554 mx = motion_x / 2; | |
| 555 my = motion_y / 2; | |
| 556 dxy = ((my & 1) << 1) | (mx & 1); | |
| 557 mx >>= 1; | |
| 558 my >>= 1; | |
| 559 } | |
| 560 | |
| 561 src_x = s->mb_x * 8 + mx; | |
| 562 src_y = s->mb_y * (8 >> field_based) + my; | |
| 563 src_x = clip(src_x, -8, s->width >> 1); | |
| 564 if (src_x == (s->width >> 1)) | |
| 565 dxy &= ~1; | |
| 566 src_y = clip(src_y, -8, height >> 1); | |
| 567 if (src_y == (height >> 1)) | |
| 568 dxy &= ~2; | |
| 569 | |
| 570 offset = (src_y * (linesize >> 1)) + src_x + (src_offset >> 1); | |
| 571 ptr = ref_picture[1] + offset; | |
| 572 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); | |
| 573 ptr = ref_picture[2] + offset; | |
| 574 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); | |
| 575 } | |
| 576 | |
| 577 static inline void MPV_motion(MpegEncContext *s, | |
| 578 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, | |
| 579 int dir, UINT8 **ref_picture, | |
| 580 op_pixels_func *pix_op) | |
| 581 { | |
| 582 int dxy, offset, mx, my, src_x, src_y, motion_x, motion_y; | |
| 583 int mb_x, mb_y, i; | |
| 584 UINT8 *ptr, *dest; | |
| 585 | |
| 586 mb_x = s->mb_x; | |
| 587 mb_y = s->mb_y; | |
| 588 | |
| 589 switch(s->mv_type) { | |
| 590 case MV_TYPE_16X16: | |
| 591 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, | |
| 592 ref_picture, 0, | |
| 593 0, pix_op, | |
| 594 s->mv[dir][0][0], s->mv[dir][0][1], 16); | |
| 595 break; | |
| 596 case MV_TYPE_8X8: | |
| 597 for(i=0;i<4;i++) { | |
| 598 motion_x = s->mv[dir][i][0]; | |
| 599 motion_y = s->mv[dir][i][1]; | |
| 600 | |
| 601 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
| 602 src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8; | |
| 603 src_y = mb_y * 16 + (motion_y >> 1) + ((i >> 1) & 1) * 8; | |
| 604 | |
| 605 /* WARNING: do no forget half pels */ | |
| 606 src_x = clip(src_x, -16, s->width); | |
| 607 if (src_x == s->width) | |
| 608 dxy &= ~1; | |
| 609 src_y = clip(src_y, -16, s->height); | |
| 610 if (src_y == s->height) | |
| 611 dxy &= ~2; | |
| 612 | |
| 613 ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); | |
| 614 dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; | |
| 615 pix_op[dxy](dest, ptr, s->linesize, 8); | |
| 616 } | |
| 617 /* In case of 8X8, we construct a single chroma motion vector | |
| 618 with a special rounding */ | |
| 619 mx = 0; | |
| 620 my = 0; | |
| 621 for(i=0;i<4;i++) { | |
| 622 mx += s->mv[dir][i][0]; | |
| 623 my += s->mv[dir][i][1]; | |
| 624 } | |
| 625 if (mx >= 0) | |
| 626 mx = (h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1)); | |
| 627 else { | |
| 628 mx = -mx; | |
| 629 mx = -(h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1)); | |
| 630 } | |
| 631 if (my >= 0) | |
| 632 my = (h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1)); | |
| 633 else { | |
| 634 my = -my; | |
| 635 my = -(h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1)); | |
| 636 } | |
| 637 dxy = ((my & 1) << 1) | (mx & 1); | |
| 638 mx >>= 1; | |
| 639 my >>= 1; | |
| 640 | |
| 641 src_x = mb_x * 8 + mx; | |
| 642 src_y = mb_y * 8 + my; | |
| 643 src_x = clip(src_x, -8, s->width/2); | |
| 644 if (src_x == s->width/2) | |
| 645 dxy &= ~1; | |
| 646 src_y = clip(src_y, -8, s->height/2); | |
| 647 if (src_y == s->height/2) | |
| 648 dxy &= ~2; | |
| 649 | |
| 650 offset = (src_y * (s->linesize >> 1)) + src_x; | |
| 651 ptr = ref_picture[1] + offset; | |
| 652 pix_op[dxy](dest_cb, ptr, s->linesize >> 1, 8); | |
| 653 ptr = ref_picture[2] + offset; | |
| 654 pix_op[dxy](dest_cr, ptr, s->linesize >> 1, 8); | |
| 655 break; | |
| 656 case MV_TYPE_FIELD: | |
| 657 if (s->picture_structure == PICT_FRAME) { | |
| 658 /* top field */ | |
| 659 mpeg_motion(s, dest_y, dest_cb, dest_cr, 0, | |
| 660 ref_picture, s->field_select[dir][0] ? s->linesize : 0, | |
| 661 1, pix_op, | |
| 662 s->mv[dir][0][0], s->mv[dir][0][1], 8); | |
| 663 /* bottom field */ | |
| 664 mpeg_motion(s, dest_y, dest_cb, dest_cr, s->linesize, | |
| 665 ref_picture, s->field_select[dir][1] ? s->linesize : 0, | |
| 666 1, pix_op, | |
| 667 s->mv[dir][1][0], s->mv[dir][1][1], 8); | |
| 668 } else { | |
| 669 | |
| 670 | |
| 671 } | |
| 672 break; | |
| 673 } | |
| 674 } | |
| 675 | |
| 676 | |
| 677 /* put block[] to dest[] */ | |
| 678 static inline void put_dct(MpegEncContext *s, | |
| 679 DCTELEM *block, int i, UINT8 *dest, int line_size) | |
| 680 { | |
| 681 if (!s->mpeg2) | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
682 s->dct_unquantize(s, block, i, s->qscale); |
|
19
82d4c9be9873
MMX/MMXEXT iDCT support, using external functions currently defined in libmpeg2
arpi_esp
parents:
18
diff
changeset
|
683 ff_idct (block); |
| 0 | 684 put_pixels_clamped(block, dest, line_size); |
| 685 } | |
| 686 | |
| 687 /* add block[] to dest[] */ | |
| 688 static inline void add_dct(MpegEncContext *s, | |
| 689 DCTELEM *block, int i, UINT8 *dest, int line_size) | |
| 690 { | |
| 691 if (s->block_last_index[i] >= 0) { | |
| 692 if (!s->mpeg2) | |
| 206 | 693 if(s->encoding || (!s->h263_msmpeg4)) |
| 200 | 694 s->dct_unquantize(s, block, i, s->qscale); |
|
19
82d4c9be9873
MMX/MMXEXT iDCT support, using external functions currently defined in libmpeg2
arpi_esp
parents:
18
diff
changeset
|
695 ff_idct (block); |
| 0 | 696 add_pixels_clamped(block, dest, line_size); |
| 697 } | |
| 698 } | |
| 699 | |
| 700 /* generic function called after a macroblock has been parsed by the | |
| 701 decoder or after it has been encoded by the encoder. | |
| 702 | |
| 703 Important variables used: | |
| 704 s->mb_intra : true if intra macroblock | |
| 705 s->mv_dir : motion vector direction | |
| 706 s->mv_type : motion vector type | |
| 707 s->mv : motion vector | |
| 708 s->interlaced_dct : true if interlaced dct used (mpeg2) | |
| 709 */ | |
| 710 void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |
| 711 { | |
| 712 int mb_x, mb_y, motion_x, motion_y; | |
| 713 int dct_linesize, dct_offset; | |
| 714 op_pixels_func *op_pix; | |
| 715 | |
| 716 mb_x = s->mb_x; | |
| 717 mb_y = s->mb_y; | |
| 718 | |
|
108
1e4a4af694d1
exporting qscale data for postprocessing (for MPlayer)
arpi_esp
parents:
79
diff
changeset
|
719 #ifdef FF_POSTPROCESS |
|
1e4a4af694d1
exporting qscale data for postprocessing (for MPlayer)
arpi_esp
parents:
79
diff
changeset
|
720 quant_store[mb_y][mb_x]=s->qscale; |
|
1e4a4af694d1
exporting qscale data for postprocessing (for MPlayer)
arpi_esp
parents:
79
diff
changeset
|
721 //printf("[%02d][%02d] %d\n",mb_x,mb_y,s->qscale); |
|
1e4a4af694d1
exporting qscale data for postprocessing (for MPlayer)
arpi_esp
parents:
79
diff
changeset
|
722 #endif |
|
1e4a4af694d1
exporting qscale data for postprocessing (for MPlayer)
arpi_esp
parents:
79
diff
changeset
|
723 |
| 0 | 724 /* update DC predictors for P macroblocks */ |
| 725 if (!s->mb_intra) { | |
| 726 if (s->h263_pred) { | |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
727 if(s->mbintra_table[mb_x + mb_y*s->mb_width]) |
|
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
728 { |
| 0 | 729 int wrap, x, y, v; |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
730 s->mbintra_table[mb_x + mb_y*s->mb_width]=0; |
|
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
731 |
| 0 | 732 wrap = 2 * s->mb_width + 2; |
| 733 v = 1024; | |
| 734 x = 2 * mb_x + 1; | |
| 735 y = 2 * mb_y + 1; | |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
736 |
| 0 | 737 s->dc_val[0][(x) + (y) * wrap] = v; |
| 738 s->dc_val[0][(x + 1) + (y) * wrap] = v; | |
| 739 s->dc_val[0][(x) + (y + 1) * wrap] = v; | |
| 740 s->dc_val[0][(x + 1) + (y + 1) * wrap] = v; | |
| 741 /* ac pred */ | |
| 742 memset(s->ac_val[0][(x) + (y) * wrap], 0, 16 * sizeof(INT16)); | |
| 743 memset(s->ac_val[0][(x + 1) + (y) * wrap], 0, 16 * sizeof(INT16)); | |
| 744 memset(s->ac_val[0][(x) + (y + 1) * wrap], 0, 16 * sizeof(INT16)); | |
| 745 memset(s->ac_val[0][(x + 1) + (y + 1) * wrap], 0, 16 * sizeof(INT16)); | |
| 746 if (s->h263_msmpeg4) { | |
| 747 s->coded_block[(x) + (y) * wrap] = 0; | |
| 748 s->coded_block[(x + 1) + (y) * wrap] = 0; | |
| 749 s->coded_block[(x) + (y + 1) * wrap] = 0; | |
| 750 s->coded_block[(x + 1) + (y + 1) * wrap] = 0; | |
| 751 } | |
| 752 /* chroma */ | |
| 753 wrap = s->mb_width + 2; | |
| 754 x = mb_x + 1; | |
| 755 y = mb_y + 1; | |
| 756 s->dc_val[1][(x) + (y) * wrap] = v; | |
| 757 s->dc_val[2][(x) + (y) * wrap] = v; | |
| 758 /* ac pred */ | |
| 759 memset(s->ac_val[1][(x) + (y) * wrap], 0, 16 * sizeof(INT16)); | |
| 760 memset(s->ac_val[2][(x) + (y) * wrap], 0, 16 * sizeof(INT16)); | |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
761 } |
| 0 | 762 } else { |
| 763 s->last_dc[0] = 128 << s->intra_dc_precision; | |
| 764 s->last_dc[1] = 128 << s->intra_dc_precision; | |
| 765 s->last_dc[2] = 128 << s->intra_dc_precision; | |
| 766 } | |
| 767 } | |
|
197
21abf1b20016
different fix, s->mbintra_table used only if h263_pred set. - patch by Michael Niedermayer <michaelni@gmx.at>
arpi_esp
parents:
196
diff
changeset
|
768 else if (s->h263_pred) |
|
191
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
769 s->mbintra_table[mb_x + mb_y*s->mb_width]=1; |
|
883f184537e6
AC table reset (memset) optimization - patch by Michael Niedermayer <michaelni@gmx.at>
uid46427
parents:
189
diff
changeset
|
770 |
| 0 | 771 /* update motion predictor */ |
| 772 if (s->out_format == FMT_H263) { | |
| 773 int x, y, wrap; | |
| 774 | |
| 775 x = 2 * mb_x + 1; | |
| 776 y = 2 * mb_y + 1; | |
| 777 wrap = 2 * s->mb_width + 2; | |
| 778 if (s->mb_intra) { | |
| 779 motion_x = 0; | |
| 780 motion_y = 0; | |
| 781 goto motion_init; | |
| 782 } else if (s->mv_type == MV_TYPE_16X16) { | |
| 783 motion_x = s->mv[0][0][0]; | |
| 784 motion_y = s->mv[0][0][1]; | |
| 785 motion_init: | |
| 786 /* no update if 8X8 because it has been done during parsing */ | |
| 787 s->motion_val[(x) + (y) * wrap][0] = motion_x; | |
| 788 s->motion_val[(x) + (y) * wrap][1] = motion_y; | |
| 789 s->motion_val[(x + 1) + (y) * wrap][0] = motion_x; | |
| 790 s->motion_val[(x + 1) + (y) * wrap][1] = motion_y; | |
| 791 s->motion_val[(x) + (y + 1) * wrap][0] = motion_x; | |
| 792 s->motion_val[(x) + (y + 1) * wrap][1] = motion_y; | |
| 793 s->motion_val[(x + 1) + (y + 1) * wrap][0] = motion_x; | |
| 794 s->motion_val[(x + 1) + (y + 1) * wrap][1] = motion_y; | |
| 795 } | |
| 796 } | |
| 797 | |
| 798 if (!s->intra_only) { | |
| 799 UINT8 *dest_y, *dest_cb, *dest_cr; | |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
800 UINT8 *mbskip_ptr; |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
801 |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
802 /* avoid copy if macroblock skipped in last frame too */ |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
803 if (!s->encoding && s->pict_type != B_TYPE) { |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
804 mbskip_ptr = &s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]; |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
805 if (s->mb_skiped) { |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
806 s->mb_skiped = 0; |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
807 /* if previous was skipped too, then nothing to do ! */ |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
808 if (*mbskip_ptr != 0) |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
809 goto the_end; |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
810 *mbskip_ptr = 1; /* indicate that this time we skiped it */ |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
811 } else { |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
812 *mbskip_ptr = 0; /* not skipped */ |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
813 } |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
814 } |
| 0 | 815 |
| 816 dest_y = s->current_picture[0] + (mb_y * 16 * s->linesize) + mb_x * 16; | |
| 817 dest_cb = s->current_picture[1] + (mb_y * 8 * (s->linesize >> 1)) + mb_x * 8; | |
| 818 dest_cr = s->current_picture[2] + (mb_y * 8 * (s->linesize >> 1)) + mb_x * 8; | |
| 819 | |
| 820 if (s->interlaced_dct) { | |
| 821 dct_linesize = s->linesize * 2; | |
| 822 dct_offset = s->linesize; | |
| 823 } else { | |
| 824 dct_linesize = s->linesize; | |
| 825 dct_offset = s->linesize * 8; | |
| 826 } | |
| 827 | |
| 828 if (!s->mb_intra) { | |
| 829 /* motion handling */ | |
| 830 if (!s->no_rounding) | |
| 831 op_pix = put_pixels_tab; | |
| 832 else | |
| 833 op_pix = put_no_rnd_pixels_tab; | |
| 834 | |
| 835 if (s->mv_dir & MV_DIR_FORWARD) { | |
| 836 MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix); | |
| 837 if (!s->no_rounding) | |
| 838 op_pix = avg_pixels_tab; | |
| 839 else | |
| 840 op_pix = avg_no_rnd_pixels_tab; | |
| 841 } | |
| 842 if (s->mv_dir & MV_DIR_BACKWARD) { | |
| 843 MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix); | |
| 844 } | |
| 845 | |
| 846 /* add dct residue */ | |
| 847 add_dct(s, block[0], 0, dest_y, dct_linesize); | |
| 848 add_dct(s, block[1], 1, dest_y + 8, dct_linesize); | |
| 849 add_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize); | |
| 850 add_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize); | |
| 851 | |
| 57 | 852 add_dct(s, block[4], 4, dest_cb, s->linesize >> 1); |
| 853 add_dct(s, block[5], 5, dest_cr, s->linesize >> 1); | |
| 0 | 854 } else { |
| 855 /* dct only in intra block */ | |
| 856 put_dct(s, block[0], 0, dest_y, dct_linesize); | |
| 857 put_dct(s, block[1], 1, dest_y + 8, dct_linesize); | |
| 858 put_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize); | |
| 859 put_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize); | |
| 860 | |
| 57 | 861 put_dct(s, block[4], 4, dest_cb, s->linesize >> 1); |
| 862 put_dct(s, block[5], 5, dest_cr, s->linesize >> 1); | |
| 0 | 863 } |
| 864 } | |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
865 the_end: |
|
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
866 emms_c(); |
| 0 | 867 } |
| 868 | |
| 869 static void encode_picture(MpegEncContext *s, int picture_number) | |
| 870 { | |
| 162 | 871 int mb_x, mb_y, wrap, last_gob; |
| 0 | 872 UINT8 *ptr; |
| 873 int i, motion_x, motion_y; | |
| 874 | |
| 875 s->picture_number = picture_number; | |
| 876 if (!s->fixed_qscale) | |
| 877 s->qscale = rate_estimate_qscale(s); | |
| 878 | |
| 879 /* precompute matrix */ | |
| 880 if (s->out_format == FMT_MJPEG) { | |
| 881 /* for mjpeg, we do include qscale in the matrix */ | |
| 882 s->intra_matrix[0] = default_intra_matrix[0]; | |
| 883 for(i=1;i<64;i++) | |
| 884 s->intra_matrix[i] = (default_intra_matrix[i] * s->qscale) >> 3; | |
| 220 | 885 convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->intra_matrix, 8); |
| 0 | 886 } else { |
| 220 | 887 convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->intra_matrix, s->qscale); |
| 888 convert_matrix(s->q_non_intra_matrix, s->q_non_intra_matrix16, s->non_intra_matrix, s->qscale); | |
| 0 | 889 } |
| 890 | |
| 891 switch(s->out_format) { | |
| 892 case FMT_MJPEG: | |
| 893 mjpeg_picture_header(s); | |
| 894 break; | |
| 895 case FMT_H263: | |
| 896 if (s->h263_msmpeg4) | |
| 897 msmpeg4_encode_picture_header(s, picture_number); | |
| 898 else if (s->h263_pred) | |
| 899 mpeg4_encode_picture_header(s, picture_number); | |
| 900 else if (s->h263_rv10) | |
| 901 rv10_encode_picture_header(s, picture_number); | |
| 902 else | |
| 903 h263_encode_picture_header(s, picture_number); | |
| 904 break; | |
| 905 case FMT_MPEG1: | |
| 906 mpeg1_encode_picture_header(s, picture_number); | |
| 907 break; | |
| 908 } | |
| 909 | |
| 910 /* init last dc values */ | |
| 911 /* note: quant matrix value (8) is implied here */ | |
| 912 s->last_dc[0] = 128; | |
| 913 s->last_dc[1] = 128; | |
| 914 s->last_dc[2] = 128; | |
| 915 s->mb_incr = 1; | |
| 916 s->last_mv[0][0][0] = 0; | |
| 917 s->last_mv[0][0][1] = 0; | |
| 918 s->mv_type = MV_TYPE_16X16; | |
| 919 s->mv_dir = MV_DIR_FORWARD; | |
| 920 | |
| 162 | 921 /* Get the GOB height based on picture height */ |
| 922 if (s->out_format == FMT_H263 && s->h263_plus) { | |
| 923 if (s->height <= 400) | |
| 924 s->gob_index = 1; | |
| 925 else if (s->height <= 800) | |
| 926 s->gob_index = 2; | |
| 927 else | |
| 928 s->gob_index = 4; | |
| 929 } | |
| 930 | |
| 0 | 931 for(mb_y=0; mb_y < s->mb_height; mb_y++) { |
| 162 | 932 /* Put GOB header based on RTP MTU */ |
| 933 if (!mb_y) { | |
| 934 s->ptr_lastgob = s->pb.buf_ptr; | |
| 935 s->ptr_last_mb_line = s->pb.buf_ptr; | |
| 936 } else if (s->out_format == FMT_H263 && s->h263_plus) { | |
| 937 last_gob = h263_encode_gob_header(s, mb_y); | |
| 938 if (last_gob) { | |
| 939 //fprintf(stderr,"\nLast GOB size: %d", last_gob); | |
| 940 s->first_gob_line = 1; | |
| 941 } else | |
| 942 s->first_gob_line = 0; | |
| 943 } | |
| 0 | 944 for(mb_x=0; mb_x < s->mb_width; mb_x++) { |
| 945 | |
| 946 s->mb_x = mb_x; | |
| 947 s->mb_y = mb_y; | |
| 948 | |
| 949 /* compute motion vector and macro block type (intra or non intra) */ | |
| 950 motion_x = 0; | |
| 951 motion_y = 0; | |
| 952 if (s->pict_type == P_TYPE) { | |
| 953 s->mb_intra = estimate_motion(s, mb_x, mb_y, | |
| 954 &motion_x, | |
| 955 &motion_y); | |
| 956 } else { | |
| 957 s->mb_intra = 1; | |
| 958 } | |
| 959 | |
| 960 /* get the pixels */ | |
| 961 wrap = s->linesize; | |
| 962 ptr = s->new_picture[0] + (mb_y * 16 * wrap) + mb_x * 16; | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
963 get_pixels(s->block[0], ptr, wrap); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
964 get_pixels(s->block[1], ptr + 8, wrap); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
965 get_pixels(s->block[2], ptr + 8 * wrap, wrap); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
966 get_pixels(s->block[3], ptr + 8 * wrap + 8, wrap); |
| 0 | 967 wrap = s->linesize >> 1; |
| 968 ptr = s->new_picture[1] + (mb_y * 8 * wrap) + mb_x * 8; | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
969 get_pixels(s->block[4], ptr, wrap); |
| 0 | 970 |
| 971 wrap = s->linesize >> 1; | |
| 972 ptr = s->new_picture[2] + (mb_y * 8 * wrap) + mb_x * 8; | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
973 get_pixels(s->block[5], ptr, wrap); |
| 0 | 974 |
| 975 /* subtract previous frame if non intra */ | |
| 976 if (!s->mb_intra) { | |
| 977 int dxy, offset, mx, my; | |
| 978 | |
| 979 dxy = ((motion_y & 1) << 1) | (motion_x & 1); | |
| 980 ptr = s->last_picture[0] + | |
| 981 ((mb_y * 16 + (motion_y >> 1)) * s->linesize) + | |
| 982 (mb_x * 16 + (motion_x >> 1)); | |
| 983 | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
984 sub_pixels_2(s->block[0], ptr, s->linesize, dxy); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
985 sub_pixels_2(s->block[1], ptr + 8, s->linesize, dxy); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
986 sub_pixels_2(s->block[2], ptr + s->linesize * 8, s->linesize, dxy); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
987 sub_pixels_2(s->block[3], ptr + 8 + s->linesize * 8, s->linesize ,dxy); |
| 0 | 988 |
| 989 if (s->out_format == FMT_H263) { | |
| 990 /* special rounding for h263 */ | |
| 991 dxy = 0; | |
| 992 if ((motion_x & 3) != 0) | |
| 993 dxy |= 1; | |
| 994 if ((motion_y & 3) != 0) | |
| 995 dxy |= 2; | |
| 996 mx = motion_x >> 2; | |
| 997 my = motion_y >> 2; | |
| 998 } else { | |
| 999 mx = motion_x / 2; | |
| 1000 my = motion_y / 2; | |
| 1001 dxy = ((my & 1) << 1) | (mx & 1); | |
| 1002 mx >>= 1; | |
| 1003 my >>= 1; | |
| 1004 } | |
| 1005 offset = ((mb_y * 8 + my) * (s->linesize >> 1)) + (mb_x * 8 + mx); | |
| 1006 ptr = s->last_picture[1] + offset; | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1007 sub_pixels_2(s->block[4], ptr, s->linesize >> 1, dxy); |
| 0 | 1008 ptr = s->last_picture[2] + offset; |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1009 sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy); |
| 0 | 1010 } |
|
7
1d3ac9654178
added skip macroblock optimization (big perf win on black regions for example)
glantau
parents:
0
diff
changeset
|
1011 emms_c(); |
| 0 | 1012 |
| 1013 /* DCT & quantize */ | |
| 1014 if (s->h263_msmpeg4) { | |
| 1015 msmpeg4_dc_scale(s); | |
| 1016 } else if (s->h263_pred) { | |
| 1017 h263_dc_scale(s); | |
| 1018 } else { | |
| 1019 /* default quantization values */ | |
| 1020 s->y_dc_scale = 8; | |
| 1021 s->c_dc_scale = 8; | |
| 1022 } | |
| 1023 for(i=0;i<6;i++) { | |
| 220 | 1024 s->block_last_index[i] = dct_quantize(s, s->block[i], i, s->qscale); |
| 0 | 1025 } |
| 1026 | |
| 1027 /* huffman encode */ | |
| 1028 switch(s->out_format) { | |
| 1029 case FMT_MPEG1: | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1030 mpeg1_encode_mb(s, s->block, motion_x, motion_y); |
| 0 | 1031 break; |
| 1032 case FMT_H263: | |
| 1033 if (s->h263_msmpeg4) | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1034 msmpeg4_encode_mb(s, s->block, motion_x, motion_y); |
| 0 | 1035 else |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1036 h263_encode_mb(s, s->block, motion_x, motion_y); |
| 0 | 1037 break; |
| 1038 case FMT_MJPEG: | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1039 mjpeg_encode_mb(s, s->block); |
| 0 | 1040 break; |
| 1041 } | |
| 1042 | |
| 1043 /* decompress blocks so that we keep the state of the decoder */ | |
| 1044 s->mv[0][0][0] = motion_x; | |
| 1045 s->mv[0][0][1] = motion_y; | |
| 1046 | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1047 MPV_decode_mb(s, s->block); |
| 0 | 1048 } |
| 162 | 1049 /* Obtain average MB line size for RTP */ |
| 1050 if (!mb_y) | |
| 1051 s->mb_line_avgsize = s->pb.buf_ptr - s->ptr_last_mb_line; | |
| 1052 else | |
| 1053 s->mb_line_avgsize = (s->mb_line_avgsize + s->pb.buf_ptr - s->ptr_last_mb_line) >> 1; | |
| 1054 //fprintf(stderr, "\nMB line: %d\tSize: %u\tAvg. Size: %u", s->mb_y, | |
| 1055 // (s->pb.buf_ptr - s->ptr_last_mb_line), s->mb_line_avgsize); | |
| 1056 s->ptr_last_mb_line = s->pb.buf_ptr; | |
| 0 | 1057 } |
| 208 | 1058 |
| 1059 if (s->h263_msmpeg4) | |
| 1060 msmpeg4_encode_ext_header(s); | |
| 1061 | |
| 162 | 1062 //if (s->gob_number) |
| 1063 // fprintf(stderr,"\nNumber of GOB: %d", s->gob_number); | |
| 0 | 1064 } |
| 1065 | |
| 220 | 1066 static int dct_quantize_c(MpegEncContext *s, |
| 0 | 1067 DCTELEM *block, int n, |
| 1068 int qscale) | |
| 1069 { | |
| 1070 int i, j, level, last_non_zero, q; | |
| 1071 const int *qmat; | |
| 216 | 1072 int minLevel, maxLevel; |
| 1073 | |
| 1074 if(s->avctx!=NULL && s->avctx->codec->id==CODEC_ID_MPEG4){ | |
| 1075 /* mpeg4 */ | |
| 1076 minLevel= -2048; | |
| 1077 maxLevel= 2047; | |
| 1078 }else if(s->out_format==FMT_MPEG1){ | |
| 1079 /* mpeg1 */ | |
| 1080 minLevel= -255; | |
| 1081 maxLevel= 255; | |
| 1082 }else{ | |
| 1083 /* h263 / msmpeg4 */ | |
| 1084 minLevel= -128; | |
| 1085 maxLevel= 127; | |
| 1086 } | |
| 0 | 1087 |
| 1088 av_fdct (block); | |
| 1089 | |
| 64 | 1090 /* we need this permutation so that we correct the IDCT |
| 1091 permutation. will be moved into DCT code */ | |
| 1092 block_permute(block); | |
| 1093 | |
| 0 | 1094 if (s->mb_intra) { |
| 1095 if (n < 4) | |
| 1096 q = s->y_dc_scale; | |
| 1097 else | |
| 1098 q = s->c_dc_scale; | |
| 1099 q = q << 3; | |
| 1100 | |
| 1101 /* note: block[0] is assumed to be positive */ | |
| 1102 block[0] = (block[0] + (q >> 1)) / q; | |
| 1103 i = 1; | |
| 1104 last_non_zero = 0; | |
| 1105 if (s->out_format == FMT_H263) { | |
| 1106 qmat = s->q_non_intra_matrix; | |
| 1107 } else { | |
| 1108 qmat = s->q_intra_matrix; | |
| 1109 } | |
| 1110 } else { | |
| 1111 i = 0; | |
| 1112 last_non_zero = -1; | |
| 1113 qmat = s->q_non_intra_matrix; | |
| 1114 } | |
| 1115 | |
| 1116 for(;i<64;i++) { | |
| 1117 j = zigzag_direct[i]; | |
| 1118 level = block[j]; | |
| 1119 level = level * qmat[j]; | |
| 1120 #ifdef PARANOID | |
| 1121 { | |
| 1122 static int count = 0; | |
| 1123 int level1, level2, qmat1; | |
| 1124 double val; | |
| 1125 if (qmat == s->q_non_intra_matrix) { | |
| 1126 qmat1 = default_non_intra_matrix[j] * s->qscale; | |
| 1127 } else { | |
| 1128 qmat1 = default_intra_matrix[j] * s->qscale; | |
| 1129 } | |
| 1130 if (av_fdct != jpeg_fdct_ifast) | |
| 1131 val = ((double)block[j] * 8.0) / (double)qmat1; | |
| 1132 else | |
| 1133 val = ((double)block[j] * 8.0 * 2048.0) / | |
| 1134 ((double)qmat1 * aanscales[j]); | |
| 1135 level1 = (int)val; | |
| 1136 level2 = level / (1 << (QMAT_SHIFT - 3)); | |
| 1137 if (level1 != level2) { | |
| 1138 fprintf(stderr, "%d: quant error qlevel=%d wanted=%d level=%d qmat1=%d qmat=%d wantedf=%0.6f\n", | |
| 1139 count, level2, level1, block[j], qmat1, qmat[j], | |
| 1140 val); | |
| 1141 count++; | |
| 1142 } | |
| 1143 | |
| 1144 } | |
| 1145 #endif | |
| 1146 /* XXX: slight error for the low range. Test should be equivalent to | |
| 1147 (level <= -(1 << (QMAT_SHIFT - 3)) || level >= (1 << | |
| 1148 (QMAT_SHIFT - 3))) | |
| 1149 */ | |
| 1150 if (((level << (31 - (QMAT_SHIFT - 3))) >> (31 - (QMAT_SHIFT - 3))) != | |
| 1151 level) { | |
| 1152 level = level / (1 << (QMAT_SHIFT - 3)); | |
| 1153 /* XXX: currently, this code is not optimal. the range should be: | |
| 1154 mpeg1: -255..255 | |
| 1155 mpeg2: -2048..2047 | |
| 1156 h263: -128..127 | |
| 1157 mpeg4: -2048..2047 | |
| 1158 */ | |
| 216 | 1159 if (level > maxLevel) |
| 1160 level = maxLevel; | |
| 1161 else if (level < minLevel) | |
| 1162 level = minLevel; | |
| 0 | 1163 |
| 1164 block[j] = level; | |
| 1165 last_non_zero = i; | |
| 1166 } else { | |
| 1167 block[j] = 0; | |
| 1168 } | |
| 1169 } | |
| 1170 return last_non_zero; | |
| 1171 } | |
| 1172 | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1173 static void dct_unquantize_mpeg1_c(MpegEncContext *s, |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1174 DCTELEM *block, int n, int qscale) |
| 0 | 1175 { |
| 200 | 1176 int i, level, nCoeffs; |
| 0 | 1177 const UINT16 *quant_matrix; |
| 1178 | |
| 200 | 1179 if(s->alternate_scan) nCoeffs= 64; |
| 1180 else nCoeffs= s->block_last_index[n]+1; | |
| 1181 | |
| 0 | 1182 if (s->mb_intra) { |
| 1183 if (n < 4) | |
| 1184 block[0] = block[0] * s->y_dc_scale; | |
| 1185 else | |
| 1186 block[0] = block[0] * s->c_dc_scale; | |
| 1187 /* XXX: only mpeg1 */ | |
| 1188 quant_matrix = s->intra_matrix; | |
| 200 | 1189 for(i=1;i<nCoeffs;i++) { |
| 1190 int j= zigzag_direct[i]; | |
| 1191 level = block[j]; | |
| 0 | 1192 if (level) { |
| 1193 if (level < 0) { | |
| 1194 level = -level; | |
| 200 | 1195 level = (int)(level * qscale * quant_matrix[j]) >> 3; |
| 0 | 1196 level = (level - 1) | 1; |
| 1197 level = -level; | |
| 1198 } else { | |
| 200 | 1199 level = (int)(level * qscale * quant_matrix[j]) >> 3; |
| 0 | 1200 level = (level - 1) | 1; |
| 1201 } | |
| 1202 #ifdef PARANOID | |
| 1203 if (level < -2048 || level > 2047) | |
| 1204 fprintf(stderr, "unquant error %d %d\n", i, level); | |
| 1205 #endif | |
| 200 | 1206 block[j] = level; |
| 0 | 1207 } |
| 1208 } | |
| 1209 } else { | |
| 1210 i = 0; | |
| 1211 quant_matrix = s->non_intra_matrix; | |
| 217 | 1212 for(;i<nCoeffs;i++) { |
| 200 | 1213 int j= zigzag_direct[i]; |
| 1214 level = block[j]; | |
| 0 | 1215 if (level) { |
| 1216 if (level < 0) { | |
| 1217 level = -level; | |
| 1218 level = (((level << 1) + 1) * qscale * | |
| 200 | 1219 ((int) (quant_matrix[j]))) >> 4; |
| 0 | 1220 level = (level - 1) | 1; |
| 1221 level = -level; | |
| 1222 } else { | |
| 1223 level = (((level << 1) + 1) * qscale * | |
| 200 | 1224 ((int) (quant_matrix[j]))) >> 4; |
| 0 | 1225 level = (level - 1) | 1; |
| 1226 } | |
| 1227 #ifdef PARANOID | |
| 1228 if (level < -2048 || level > 2047) | |
| 1229 fprintf(stderr, "unquant error %d %d\n", i, level); | |
| 1230 #endif | |
| 200 | 1231 block[j] = level; |
| 0 | 1232 } |
| 1233 } | |
| 1234 } | |
| 1235 } | |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1236 |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1237 static void dct_unquantize_h263_c(MpegEncContext *s, |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1238 DCTELEM *block, int n, int qscale) |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1239 { |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1240 int i, level, qmul, qadd; |
| 200 | 1241 int nCoeffs; |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1242 |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1243 if (s->mb_intra) { |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1244 if (n < 4) |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1245 block[0] = block[0] * s->y_dc_scale; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1246 else |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1247 block[0] = block[0] * s->c_dc_scale; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1248 i = 1; |
| 200 | 1249 nCoeffs= 64; //does not allways use zigzag table |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1250 } else { |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1251 i = 0; |
| 200 | 1252 nCoeffs= zigzag_end[ s->block_last_index[n] ]; |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1253 } |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1254 |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1255 qmul = s->qscale << 1; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1256 qadd = (s->qscale - 1) | 1; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1257 |
| 200 | 1258 for(;i<nCoeffs;i++) { |
|
13
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1259 level = block[i]; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1260 if (level) { |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1261 if (level < 0) { |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1262 level = level * qmul - qadd; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1263 } else { |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1264 level = level * qmul + qadd; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1265 } |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1266 #ifdef PARANOID |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1267 if (level < -2048 || level > 2047) |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1268 fprintf(stderr, "unquant error %d %d\n", i, level); |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1269 #endif |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1270 block[i] = level; |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1271 } |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1272 } |
|
174ef88f619a
use block[] in structure to have it aligned on 8 bytes for mmx optimizations - dct_unquantize is always a function pointer - added specialized dct_unquantize_h263
glantau
parents:
8
diff
changeset
|
1273 } |
| 0 | 1274 |
| 1275 /* rate control */ | |
| 1276 | |
| 1277 /* an I frame is I_FRAME_SIZE_RATIO bigger than a P frame */ | |
| 1278 #define I_FRAME_SIZE_RATIO 3.0 | |
| 1279 #define QSCALE_K 20 | |
| 1280 | |
| 1281 static void rate_control_init(MpegEncContext *s) | |
| 1282 { | |
| 1283 s->wanted_bits = 0; | |
| 1284 | |
| 1285 if (s->intra_only) { | |
| 1286 s->I_frame_bits = ((INT64)s->bit_rate * FRAME_RATE_BASE) / s->frame_rate; | |
| 1287 s->P_frame_bits = s->I_frame_bits; | |
| 1288 } else { | |
| 1289 s->P_frame_bits = (int) ((float)(s->gop_size * s->bit_rate) / | |
| 1290 (float)((float)s->frame_rate / FRAME_RATE_BASE * (I_FRAME_SIZE_RATIO + s->gop_size - 1))); | |
| 1291 s->I_frame_bits = (int)(s->P_frame_bits * I_FRAME_SIZE_RATIO); | |
| 1292 } | |
| 1293 | |
| 1294 #if defined(DEBUG) | |
| 1295 printf("I_frame_size=%d P_frame_size=%d\n", | |
| 1296 s->I_frame_bits, s->P_frame_bits); | |
| 1297 #endif | |
| 1298 } | |
| 1299 | |
| 1300 | |
| 1301 /* | |
| 1302 * This heuristic is rather poor, but at least we do not have to | |
| 1303 * change the qscale at every macroblock. | |
| 1304 */ | |
| 1305 static int rate_estimate_qscale(MpegEncContext *s) | |
| 1306 { | |
|
187
3f3b14d3a23d
qscale estimate fix, diff extended to 64bit wide. patch by Stephen Davies <steve@daviesfam.org>
arpi_esp
parents:
178
diff
changeset
|
1307 INT64 diff, total_bits = s->total_bits; |
| 0 | 1308 float q; |
|
187
3f3b14d3a23d
qscale estimate fix, diff extended to 64bit wide. patch by Stephen Davies <steve@daviesfam.org>
arpi_esp
parents:
178
diff
changeset
|
1309 int qscale, qmin; |
| 0 | 1310 |
| 1311 if (s->pict_type == I_TYPE) { | |
| 1312 s->wanted_bits += s->I_frame_bits; | |
| 1313 } else { | |
| 1314 s->wanted_bits += s->P_frame_bits; | |
| 1315 } | |
| 1316 diff = s->wanted_bits - total_bits; | |
| 1317 q = 31.0 - (float)diff / (QSCALE_K * s->mb_height * s->mb_width); | |
| 1318 /* adjust for I frame */ | |
| 1319 if (s->pict_type == I_TYPE && !s->intra_only) { | |
| 1320 q /= I_FRAME_SIZE_RATIO; | |
| 1321 } | |
| 1322 | |
| 1323 /* using a too small Q scale leeds to problems in mpeg1 and h263 | |
| 1324 because AC coefficients are clamped to 255 or 127 */ | |
| 1325 qmin = 3; | |
| 1326 if (q < qmin) | |
| 1327 q = qmin; | |
| 1328 else if (q > 31) | |
| 1329 q = 31; | |
| 1330 qscale = (int)(q + 0.5); | |
| 1331 #if defined(DEBUG) | |
| 64 | 1332 printf("%d: total=%0.0f br=%0.1f diff=%d qest=%0.1f\n", |
| 0 | 1333 s->picture_number, |
| 64 | 1334 (double)total_bits, |
| 0 | 1335 (float)s->frame_rate / FRAME_RATE_BASE * |
| 1336 total_bits / s->picture_number, | |
| 1337 diff, q); | |
| 1338 #endif | |
| 1339 return qscale; | |
| 1340 } | |
| 1341 | |
| 1342 AVCodec mpeg1video_encoder = { | |
| 1343 "mpeg1video", | |
| 1344 CODEC_TYPE_VIDEO, | |
| 1345 CODEC_ID_MPEG1VIDEO, | |
| 1346 sizeof(MpegEncContext), | |
| 1347 MPV_encode_init, | |
| 1348 MPV_encode_picture, | |
| 1349 MPV_encode_end, | |
| 1350 }; | |
| 1351 | |
| 1352 AVCodec h263_encoder = { | |
| 1353 "h263", | |
| 1354 CODEC_TYPE_VIDEO, | |
| 1355 CODEC_ID_H263, | |
| 1356 sizeof(MpegEncContext), | |
| 1357 MPV_encode_init, | |
| 1358 MPV_encode_picture, | |
| 1359 MPV_encode_end, | |
| 1360 }; | |
| 1361 | |
| 1362 AVCodec h263p_encoder = { | |
| 1363 "h263p", | |
| 1364 CODEC_TYPE_VIDEO, | |
| 1365 CODEC_ID_H263P, | |
| 1366 sizeof(MpegEncContext), | |
| 1367 MPV_encode_init, | |
| 1368 MPV_encode_picture, | |
| 1369 MPV_encode_end, | |
| 1370 }; | |
| 1371 | |
| 1372 AVCodec rv10_encoder = { | |
| 1373 "rv10", | |
| 1374 CODEC_TYPE_VIDEO, | |
| 1375 CODEC_ID_RV10, | |
| 1376 sizeof(MpegEncContext), | |
| 1377 MPV_encode_init, | |
| 1378 MPV_encode_picture, | |
| 1379 MPV_encode_end, | |
| 1380 }; | |
| 1381 | |
| 1382 AVCodec mjpeg_encoder = { | |
| 1383 "mjpeg", | |
| 1384 CODEC_TYPE_VIDEO, | |
| 1385 CODEC_ID_MJPEG, | |
| 1386 sizeof(MpegEncContext), | |
| 1387 MPV_encode_init, | |
| 1388 MPV_encode_picture, | |
| 1389 MPV_encode_end, | |
| 1390 }; | |
| 1391 | |
| 71 | 1392 AVCodec mpeg4_encoder = { |
| 1393 "mpeg4", | |
| 0 | 1394 CODEC_TYPE_VIDEO, |
| 71 | 1395 CODEC_ID_MPEG4, |
| 0 | 1396 sizeof(MpegEncContext), |
| 1397 MPV_encode_init, | |
| 1398 MPV_encode_picture, | |
| 1399 MPV_encode_end, | |
| 1400 }; | |
| 1401 | |
| 1402 AVCodec msmpeg4_encoder = { | |
| 1403 "msmpeg4", | |
| 1404 CODEC_TYPE_VIDEO, | |
| 1405 CODEC_ID_MSMPEG4, | |
| 1406 sizeof(MpegEncContext), | |
| 1407 MPV_encode_init, | |
| 1408 MPV_encode_picture, | |
| 1409 MPV_encode_end, | |
| 1410 }; |
