summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYartrebo <yartrebo@earthlink.net>2005-04-25 10:03:01 +0000
committerMichael Niedermayer <michaelni@gmx.at>2005-04-25 10:03:01 +0000
commit66b32bf2729a186647af84892c68c1b7dbb70ef8 (patch)
tree2c20f330620daf53a26d753a6e6c73365a2ed9a8
parent42251a2a4fb2ff5d4b90d4e5ff04672cccc851ba (diff)
tighter snow slicing patch by (Yartrebo || yartrebo earthlink net)
Originally committed as revision 4159 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/snow.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index 0ea6b0c3ab..a79cb1ad6e 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -2950,7 +2950,7 @@ static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int b
}
}
-static void dequantize_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride){
+static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride, int start_y, int end_y){
const int w= b->width;
const int h= b->height;
const int qlog= clip(s->qlog + b->qlog, 0, QROOT*16);
@@ -2961,7 +2961,7 @@ static void dequantize_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, D
if(s->qlog == LOSSLESS_QLOG) return;
- for(y=0; y<h; y++){
+ for(y=start_y; y<end_y; y++){
// DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
DWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
for(x=0; x<w; x++){
@@ -3028,7 +3028,7 @@ static void decorrelate(SnowContext *s, SubBand *b, DWTELEM *src, int stride, in
}
}
-static void correlate_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride, int inverse, int use_median){
+static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
const int w= b->width;
const int h= b->height;
int x,y;
@@ -3038,7 +3038,10 @@ static void correlate_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DW
DWTELEM * line;
DWTELEM * prev;
- for(y=0; y<h; y++){
+ if (start_y != 0)
+ line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
+
+ for(y=start_y; y<end_y; y++){
prev = line;
// line = slice_buffer_get_line_from_address(sb, src + (y * stride));
line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
@@ -3653,11 +3656,7 @@ static int decode_init(AVCodecContext *avctx)
common_init(avctx);
block_size = MB_SIZE >> s->block_max_depth;
- /* FIXME block_size * 2 is determined empirically. block_size * 1.5 is definitely needed, but I (Robert) cannot figure out why more than that is needed. Perhaps there is a bug, or perhaps I overlooked some demands that are placed on the buffer. */
- /* FIXME The formula is WRONG. For height > 480, the buffer will overflow. */
- /* FIXME For now, I will use a full frame of lines. Fortunately, this should not materially effect cache performance because lines are allocated using a stack, so if in fact only 50 out of 496 lines are needed at a time, the other 446 will sit allocated but never accessed. */
-// slice_buffer_init(s->plane[0].sb, s->plane[0].height, (block_size * 2) + (s->spatial_decomposition_count * s->spatial_decomposition_count), s->plane[0].width, s->spatial_dwt_buffer);
- slice_buffer_init(&s->sb, s->plane[0].height, s->plane[0].height, s->plane[0].width, s->spatial_dwt_buffer);
+ slice_buffer_init(&s->sb, s->plane[0].height, (block_size) + (s->spatial_decomposition_count * (s->spatial_decomposition_count + 2)) + 1, s->plane[0].width, s->spatial_dwt_buffer);
return 0;
}
@@ -3689,7 +3688,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
int h= p->height;
int x, y;
int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
- SubBand * correlate_band;
if(s->avctx->debug&2048){
memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
@@ -3712,12 +3710,6 @@ if(s->avctx->debug&2048){
}
STOP_TIMER("unpack coeffs");
}
-
- /* Handle level 0, orientation 0 specially. It is particularly resistant to slicing but fortunately quite small, so process it in one pass. */
- correlate_band = &p->band[0][0];
- decode_subband_slice_buffered(s, correlate_band, &s->sb, 0, correlate_band->height, decode_state[0][0]);
- correlate_buffered(s, &s->sb, correlate_band, correlate_band->buf, correlate_band->stride, 1, 0);
- dequantize_buffered(s, &s->sb, correlate_band, correlate_band->buf, correlate_band->stride);
{START_TIMER
const int mb_h= s->b_height << s->block_max_depth;
@@ -3732,23 +3724,43 @@ if(s->avctx->debug&2048){
ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
for(mb_y=0; mb_y<=mb_h; mb_y++){
- const int slice_starty = block_w*mb_y;
- const int slice_h = block_w*(mb_y+1);
+ int slice_starty = block_w*mb_y;
+ int slice_h = block_w*(mb_y+1);
+ if (!(s->keyframe || s->avctx->debug&512)){
+ slice_starty = FFMAX(0, slice_starty - (block_w >> 1));
+ slice_h -= (block_w >> 1);
+ }
{
START_TIMER
for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 1; orientation<4; orientation++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
SubBand *b= &p->band[level][orientation];
int start_y;
int end_y;
int our_mb_start = mb_y;
int our_mb_end = (mb_y + 1);
- start_y = FFMIN(b->height, (mb_y ? ((block_w * our_mb_start - 4) >> (s->spatial_decomposition_count - level)) + 5 : 0));
- end_y = FFMIN(b->height, (((block_w * our_mb_end - 4) >> (s->spatial_decomposition_count - level)) + 5));
-
- if (start_y != end_y)
- decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
+ start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + 2: 0);
+ end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + 2);
+ if (!(s->keyframe || s->avctx->debug&512)){
+ start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level)));
+ end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level)));
+ }
+ start_y = FFMIN(b->height, start_y);
+ end_y = FFMIN(b->height, end_y);
+
+ if (start_y != end_y){
+ if (orientation == 0){
+ SubBand * correlate_band = &p->band[0][0];
+ int correlate_end_y = FFMIN(b->height, end_y + 1);
+ int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
+ decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
+ correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->buf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
+ dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->buf, correlate_band->stride, start_y, end_y);
+ }
+ else
+ decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
+ }
}
}
STOP_TIMER("decode_subband_slice");
@@ -3772,16 +3784,8 @@ if(s->avctx->debug&2048){
predict_slice_buffered(s, &s->sb, s->spatial_dwt_buffer, plane_index, 1, mb_y);
- /* Nasty hack based empirically on how predict_slice_buffered() hits the buffer. */
- /* FIXME If possible, make predict_slice fit into the slice. As of now, it works on some previous lines (up to slice_height / 2) if the condition on the next line is false. */
- if (s->keyframe || (s->avctx->debug&512)){
- y = FFMIN(p->height, slice_starty);
- end_y = FFMIN(p->height, slice_h);
- }
- else{
- y = FFMAX(0, FFMIN(p->height, slice_starty - (block_w >> 1)));
- end_y = FFMAX(0, FFMIN(p->height, slice_h - (block_w >> 1)));
- }
+ y = FFMIN(p->height, slice_starty);
+ end_y = FFMIN(p->height, slice_h);
while(y < end_y)
slice_buffer_release(&s->sb, y++);
}