Revision 2f349de2 libavcodec/mpegvideo.c
libavcodec/mpegvideo.c | ||
---|---|---|
35 | 35 |
DCTELEM *block, int n, int qscale); |
36 | 36 |
static void dct_unquantize_h263_c(MpegEncContext *s, |
37 | 37 |
DCTELEM *block, int n, int qscale); |
38 |
static int dct_quantize(MpegEncContext *s, DCTELEM *block, int n, int qscale); |
|
39 |
static int dct_quantize_mmx(MpegEncContext *s, |
|
40 |
DCTELEM *block, int n, |
|
41 |
int qscale); |
|
42 | 38 |
static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w); |
39 |
static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale); |
|
43 | 40 |
|
41 |
int (*dct_quantize)(MpegEncContext *s, DCTELEM *block, int n, int qscale)= dct_quantize_c; |
|
44 | 42 |
void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edges_c; |
45 | 43 |
|
46 | 44 |
#define EDGE_WIDTH 16 |
... | ... | |
74 | 72 |
|
75 | 73 |
extern UINT8 zigzag_end[64]; |
76 | 74 |
|
77 |
/* XXX: should use variable shift ? */ |
|
78 |
#define QMAT_SHIFT_MMX 19 |
|
79 |
#define QMAT_SHIFT 25 |
|
80 |
|
|
81 |
static void convert_matrix(int *qmat, const UINT16 *quant_matrix, int qscale) |
|
75 |
static void convert_matrix(int *qmat, UINT16 *qmat16, const UINT16 *quant_matrix, int qscale) |
|
82 | 76 |
{ |
83 | 77 |
int i; |
84 | 78 |
|
85 | 79 |
if (av_fdct == jpeg_fdct_ifast) { |
86 | 80 |
for(i=0;i<64;i++) { |
87 | 81 |
/* 16 <= qscale * quant_matrix[i] <= 7905 */ |
88 |
/* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ |
|
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 */ |
|
89 | 85 |
|
90 |
qmat[i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 11)) /
|
|
91 |
(aanscales[i] * qscale * quant_matrix[i]));
|
|
86 |
qmat[block_permute_op(i)] = (int)((UINT64_C(1) << (QMAT_SHIFT + 11)) /
|
|
87 |
(aanscales[i] * qscale * quant_matrix[block_permute_op(i)]));
|
|
92 | 88 |
} |
93 | 89 |
} else { |
94 | 90 |
for(i=0;i<64;i++) { |
95 | 91 |
/* We can safely suppose that 16 <= quant_matrix[i] <= 255 |
96 |
So 16 <= qscale * quant_matrix[i] <= 7905 |
|
97 |
so (1 << QMAT_SHIFT) / 16 >= qmat[i] >= (1 << QMAT_SHIFT) / 7905 |
|
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 |
|
98 | 95 |
*/ |
99 |
qmat[i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]); |
|
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)]); |
|
100 | 98 |
} |
101 | 99 |
} |
102 | 100 |
} |
... | ... | |
418 | 416 |
void MPV_frame_end(MpegEncContext *s) |
419 | 417 |
{ |
420 | 418 |
/* draw edge for correct motion prediction if outside */ |
421 |
if (s->pict_type != B_TYPE) { |
|
419 |
if (s->pict_type != B_TYPE && !s->intra_only) {
|
|
422 | 420 |
if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4){ |
423 | 421 |
draw_edges(s->current_picture[0], s->linesize, s->mb_width*16, s->mb_height*16, EDGE_WIDTH); |
424 | 422 |
draw_edges(s->current_picture[1], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2); |
... | ... | |
457 | 455 |
avctx->key_frame = (s->pict_type == I_TYPE); |
458 | 456 |
|
459 | 457 |
MPV_frame_start(s); |
460 |
|
|
458 |
|
|
461 | 459 |
for(i=0;i<3;i++) { |
462 | 460 |
UINT8 *src = pict->data[i]; |
463 | 461 |
UINT8 *dest = s->current_picture[i]; |
... | ... | |
472 | 470 |
h >>= 1; |
473 | 471 |
} |
474 | 472 |
|
475 |
for(j=0;j<h;j++) { |
|
476 |
memcpy(dest, src, w); |
|
477 |
dest += dest_wrap; |
|
478 |
src += src_wrap; |
|
479 |
} |
|
473 |
if(s->intra_only && dest_wrap==src_wrap){ |
|
474 |
s->current_picture[i] = pict->data[i]; |
|
475 |
}else { |
|
476 |
for(j=0;j<h;j++) { |
|
477 |
memcpy(dest, src, w); |
|
478 |
dest += dest_wrap; |
|
479 |
src += src_wrap; |
|
480 |
} |
|
481 |
} |
|
480 | 482 |
s->new_picture[i] = s->current_picture[i]; |
481 | 483 |
} |
482 | 484 |
|
... | ... | |
873 | 875 |
s->intra_matrix[0] = default_intra_matrix[0]; |
874 | 876 |
for(i=1;i<64;i++) |
875 | 877 |
s->intra_matrix[i] = (default_intra_matrix[i] * s->qscale) >> 3; |
876 |
convert_matrix(s->q_intra_matrix, s->intra_matrix, 8); |
|
878 |
convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->intra_matrix, 8);
|
|
877 | 879 |
} else { |
878 |
convert_matrix(s->q_intra_matrix, s->intra_matrix, s->qscale); |
|
879 |
convert_matrix(s->q_non_intra_matrix, s->non_intra_matrix, s->qscale); |
|
880 |
convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->intra_matrix, s->qscale);
|
|
881 |
convert_matrix(s->q_non_intra_matrix, s->q_non_intra_matrix16, s->non_intra_matrix, s->qscale);
|
|
880 | 882 |
} |
881 | 883 |
|
882 | 884 |
switch(s->out_format) { |
... | ... | |
1011 | 1013 |
s->y_dc_scale = 8; |
1012 | 1014 |
s->c_dc_scale = 8; |
1013 | 1015 |
} |
1014 |
|
|
1015 | 1016 |
for(i=0;i<6;i++) { |
1016 |
int last_index; |
|
1017 |
if (av_fdct == jpeg_fdct_ifast) |
|
1018 |
last_index = dct_quantize(s, s->block[i], i, s->qscale); |
|
1019 |
else |
|
1020 |
last_index = dct_quantize_mmx(s, s->block[i], i, s->qscale); |
|
1021 |
s->block_last_index[i] = last_index; |
|
1017 |
s->block_last_index[i] = dct_quantize(s, s->block[i], i, s->qscale); |
|
1022 | 1018 |
} |
1023 | 1019 |
|
1024 | 1020 |
/* huffman encode */ |
... | ... | |
1060 | 1056 |
// fprintf(stderr,"\nNumber of GOB: %d", s->gob_number); |
1061 | 1057 |
} |
1062 | 1058 |
|
1063 |
static int dct_quantize(MpegEncContext *s, |
|
1059 |
static int dct_quantize_c(MpegEncContext *s,
|
|
1064 | 1060 |
DCTELEM *block, int n, |
1065 | 1061 |
int qscale) |
1066 | 1062 |
{ |
... | ... | |
1157 | 1153 |
level = maxLevel; |
1158 | 1154 |
else if (level < minLevel) |
1159 | 1155 |
level = minLevel; |
1160 |
block[j] = level; |
|
1161 |
last_non_zero = i; |
|
1162 |
} else { |
|
1163 |
block[j] = 0; |
|
1164 |
} |
|
1165 |
} |
|
1166 |
return last_non_zero; |
|
1167 |
} |
|
1168 |
|
|
1169 |
static int dct_quantize_mmx(MpegEncContext *s, |
|
1170 |
DCTELEM *block, int n, |
|
1171 |
int qscale) |
|
1172 |
{ |
|
1173 |
int i, j, level, last_non_zero, q; |
|
1174 |
const int *qmat; |
|
1175 |
int minLevel, maxLevel; |
|
1176 |
|
|
1177 |
if(s->avctx!=NULL && s->avctx->codec->id==CODEC_ID_MPEG4){ |
|
1178 |
/* mpeg4 */ |
|
1179 |
minLevel= -2048; |
|
1180 |
maxLevel= 2047; |
|
1181 |
}else if(s->out_format==FMT_MPEG1){ |
|
1182 |
/* mpeg1 */ |
|
1183 |
minLevel= -255; |
|
1184 |
maxLevel= 255; |
|
1185 |
}else{ |
|
1186 |
/* h263 / msmpeg4 */ |
|
1187 |
minLevel= -128; |
|
1188 |
maxLevel= 127; |
|
1189 |
} |
|
1190 | 1156 |
|
1191 |
av_fdct (block); |
|
1192 |
|
|
1193 |
/* we need this permutation so that we correct the IDCT |
|
1194 |
permutation. will be moved into DCT code */ |
|
1195 |
block_permute(block); |
|
1196 |
|
|
1197 |
if (s->mb_intra) { |
|
1198 |
if (n < 4) |
|
1199 |
q = s->y_dc_scale; |
|
1200 |
else |
|
1201 |
q = s->c_dc_scale; |
|
1202 |
|
|
1203 |
/* note: block[0] is assumed to be positive */ |
|
1204 |
block[0] = (block[0] + (q >> 1)) / q; |
|
1205 |
i = 1; |
|
1206 |
last_non_zero = 0; |
|
1207 |
if (s->out_format == FMT_H263) { |
|
1208 |
qmat = s->q_non_intra_matrix; |
|
1209 |
} else { |
|
1210 |
qmat = s->q_intra_matrix; |
|
1211 |
} |
|
1212 |
} else { |
|
1213 |
i = 0; |
|
1214 |
last_non_zero = -1; |
|
1215 |
qmat = s->q_non_intra_matrix; |
|
1216 |
} |
|
1217 |
|
|
1218 |
for(;i<64;i++) { |
|
1219 |
j = zigzag_direct[i]; |
|
1220 |
level = block[j]; |
|
1221 |
level = level * qmat[j]; |
|
1222 |
/* XXX: slight error for the low range. Test should be equivalent to |
|
1223 |
(level <= -(1 << (QMAT_SHIFT_MMX - 3)) || level >= (1 << |
|
1224 |
(QMAT_SHIFT_MMX - 3))) |
|
1225 |
*/ |
|
1226 |
if (((level << (31 - (QMAT_SHIFT_MMX - 3))) >> (31 - (QMAT_SHIFT_MMX - 3))) != |
|
1227 |
level) { |
|
1228 |
level = level / (1 << (QMAT_SHIFT_MMX - 3)); |
|
1229 |
/* XXX: currently, this code is not optimal. the range should be: |
|
1230 |
mpeg1: -255..255 |
|
1231 |
mpeg2: -2048..2047 |
|
1232 |
h263: -128..127 |
|
1233 |
mpeg4: -2048..2047 |
|
1234 |
*/ |
|
1235 |
if (level > maxLevel) |
|
1236 |
level = maxLevel; |
|
1237 |
else if (level < minLevel) |
|
1238 |
level = minLevel; |
|
1239 | 1157 |
block[j] = level; |
1240 | 1158 |
last_non_zero = i; |
1241 | 1159 |
} else { |
Also available in: Unified diff