2 * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libavutil/intmath.h"
22 #include "libavutil/log.h"
23 #include "libavutil/opt.h"
29 #include "rangecoder.h"
32 #include "mpegvideo.h"
35 static av_always_inline
void predict_slice_buffered(SnowContext
*s
, slice_buffer
* sb
, IDWTELEM
* old_buffer
, int plane_index
, int add
, int mb_y
){
36 Plane
*p
= &s
->plane
[plane_index
];
37 const int mb_w
= s
->b_width
<< s
->block_max_depth
;
38 const int mb_h
= s
->b_height
<< s
->block_max_depth
;
40 int block_size
= MB_SIZE
>> s
->block_max_depth
;
41 int block_w
= plane_index
? block_size
>>s
->chroma_h_shift
: block_size
;
42 int block_h
= plane_index
? block_size
>>s
->chroma_v_shift
: block_size
;
43 const uint8_t *obmc
= plane_index
? ff_obmc_tab
[s
->block_max_depth
+s
->chroma_h_shift
] : ff_obmc_tab
[s
->block_max_depth
];
44 int obmc_stride
= plane_index
? (2*block_size
)>>s
->chroma_h_shift
: 2*block_size
;
45 int ref_stride
= s
->current_picture
->linesize
[plane_index
];
46 uint8_t *dst8
= s
->current_picture
->data
[plane_index
];
50 if(s
->keyframe
|| (s
->avctx
->debug
&512)){
55 for(y
=block_h
*mb_y
; y
<FFMIN(h
,block_h
*(mb_y
+1)); y
++){
56 // DWTELEM * line = slice_buffer_get_line(sb, y);
57 IDWTELEM
* line
= sb
->line
[y
];
59 // int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
60 int v
= line
[x
] + (128<<FRAC_BITS
) + (1<<(FRAC_BITS
-1));
62 if(v
&(~255)) v
= ~(v
>>31);
63 dst8
[x
+ y
*ref_stride
]= v
;
67 for(y
=block_h
*mb_y
; y
<FFMIN(h
,block_h
*(mb_y
+1)); y
++){
68 // DWTELEM * line = slice_buffer_get_line(sb, y);
69 IDWTELEM
* line
= sb
->line
[y
];
71 line
[x
] -= 128 << FRAC_BITS
;
72 // buf[x + y*w]-= 128<<FRAC_BITS;
80 for(mb_x
=0; mb_x
<=mb_w
; mb_x
++){
81 add_yblock(s
, 1, sb
, old_buffer
, dst8
, obmc
,
82 block_w
*mb_x
- block_w
/2,
83 block_h
*mb_y
- block_h
/2,
86 w
, ref_stride
, obmc_stride
,
92 static inline void decode_subband_slice_buffered(SnowContext
*s
, SubBand
*b
, slice_buffer
* sb
, int start_y
, int h
, int save_state
[1]){
93 const int w
= b
->width
;
95 const int qlog
= av_clip(s
->qlog
+ b
->qlog
, 0, QROOT
*16);
96 int qmul
= ff_qexp
[qlog
&(QROOT
-1)]<<(qlog
>>QSHIFT
);
97 int qadd
= (s
->qbias
*qmul
)>>QBIAS_SHIFT
;
100 if(b
->ibuf
== s
->spatial_idwt_buffer
|| s
->qlog
== LOSSLESS_QLOG
){
105 /* If we are on the second or later slice, restore our index. */
107 new_index
= save_state
[0];
110 for(y
=start_y
; y
<h
; y
++){
113 IDWTELEM
* line
= slice_buffer_get_line(sb
, y
* b
->stride_line
+ b
->buf_y_offset
) + b
->buf_x_offset
;
114 memset(line
, 0, b
->width
*sizeof(IDWTELEM
));
115 v
= b
->x_coeff
[new_index
].coeff
;
116 x
= b
->x_coeff
[new_index
++].x
;
118 register int t
= ( (v
>>1)*qmul
+ qadd
)>>QEXPSHIFT
;
119 register int u
= -(v
&1);
122 v
= b
->x_coeff
[new_index
].coeff
;
123 x
= b
->x_coeff
[new_index
++].x
;
127 /* Save our variables for the next slice. */
128 save_state
[0] = new_index
;
133 static int decode_q_branch(SnowContext
*s
, int level
, int x
, int y
){
134 const int w
= s
->b_width
<< s
->block_max_depth
;
135 const int rem_depth
= s
->block_max_depth
- level
;
136 const int index
= (x
+ y
*w
) << rem_depth
;
137 int trx
= (x
+1)<<rem_depth
;
138 const BlockNode
*left
= x
? &s
->block
[index
-1] : &null_block
;
139 const BlockNode
*top
= y
? &s
->block
[index
-w
] : &null_block
;
140 const BlockNode
*tl
= y
&& x
? &s
->block
[index
-w
-1] : left
;
141 const BlockNode
*tr
= y
&& trx
<w
&& ((x
&1)==0 || level
==0) ? &s
->block
[index
-w
+(1<<rem_depth
)] : tl
; //FIXME use lt
142 int s_context
= 2*left
->level
+ 2*top
->level
+ tl
->level
+ tr
->level
;
146 set_blocks(s
, level
, x
, y
, null_block
.color
[0], null_block
.color
[1], null_block
.color
[2], null_block
.mx
, null_block
.my
, null_block
.ref
, BLOCK_INTRA
);
150 if(level
==s
->block_max_depth
|| get_rac(&s
->c
, &s
->block_state
[4 + s_context
])){
152 int l
= left
->color
[0];
153 int cb
= left
->color
[1];
154 int cr
= left
->color
[2];
156 int ref_context
= av_log2(2*left
->ref
) + av_log2(2*top
->ref
);
157 int mx_context
= av_log2(2*FFABS(left
->mx
- top
->mx
)) + 0*av_log2(2*FFABS(tr
->mx
- top
->mx
));
158 int my_context
= av_log2(2*FFABS(left
->my
- top
->my
)) + 0*av_log2(2*FFABS(tr
->my
- top
->my
));
160 type
= get_rac(&s
->c
, &s
->block_state
[1 + left
->type
+ top
->type
]) ? BLOCK_INTRA
: 0;
163 pred_mv(s
, &mx
, &my
, 0, left
, top
, tr
);
164 l
+= get_symbol(&s
->c
, &s
->block_state
[32], 1);
165 if (s
->nb_planes
> 2) {
166 cb
+= get_symbol(&s
->c
, &s
->block_state
[64], 1);
167 cr
+= get_symbol(&s
->c
, &s
->block_state
[96], 1);
170 if(s
->ref_frames
> 1)
171 ref
= get_symbol(&s
->c
, &s
->block_state
[128 + 1024 + 32*ref_context
], 0);
172 if (ref
>= s
->ref_frames
) {
173 av_log(s
->avctx
, AV_LOG_ERROR
, "Invalid ref\n");
174 return AVERROR_INVALIDDATA
;
176 pred_mv(s
, &mx
, &my
, ref
, left
, top
, tr
);
177 mx
+= get_symbol(&s
->c
, &s
->block_state
[128 + 32*(mx_context
+ 16*!!ref
)], 1);
178 my
+= get_symbol(&s
->c
, &s
->block_state
[128 + 32*(my_context
+ 16*!!ref
)], 1);
180 set_blocks(s
, level
, x
, y
, l
, cb
, cr
, mx
, my
, ref
, type
);
182 if ((res
= decode_q_branch(s
, level
+1, 2*x
+0, 2*y
+0)) < 0 ||
183 (res
= decode_q_branch(s
, level
+1, 2*x
+1, 2*y
+0)) < 0 ||
184 (res
= decode_q_branch(s
, level
+1, 2*x
+0, 2*y
+1)) < 0 ||
185 (res
= decode_q_branch(s
, level
+1, 2*x
+1, 2*y
+1)) < 0)
191 static void dequantize_slice_buffered(SnowContext
*s
, slice_buffer
* sb
, SubBand
*b
, IDWTELEM
*src
, int stride
, int start_y
, int end_y
){
192 const int w
= b
->width
;
193 const int qlog
= av_clip(s
->qlog
+ b
->qlog
, 0, QROOT
*16);
194 const int qmul
= ff_qexp
[qlog
&(QROOT
-1)]<<(qlog
>>QSHIFT
);
195 const int qadd
= (s
->qbias
*qmul
)>>QBIAS_SHIFT
;
198 if(s
->qlog
== LOSSLESS_QLOG
) return;
200 for(y
=start_y
; y
<end_y
; y
++){
201 // DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
202 IDWTELEM
* line
= slice_buffer_get_line(sb
, (y
* b
->stride_line
) + b
->buf_y_offset
) + b
->buf_x_offset
;
206 line
[x
]= -((-i
*qmul
+ qadd
)>>(QEXPSHIFT
)); //FIXME try different bias
208 line
[x
]= (( i
*qmul
+ qadd
)>>(QEXPSHIFT
));
214 static void correlate_slice_buffered(SnowContext
*s
, slice_buffer
* sb
, SubBand
*b
, IDWTELEM
*src
, int stride
, int inverse
, int use_median
, int start_y
, int end_y
){
215 const int w
= b
->width
;
218 IDWTELEM
* line
=0; // silence silly "could be used without having been initialized" warning
222 line
= slice_buffer_get_line(sb
, ((start_y
- 1) * b
->stride_line
) + b
->buf_y_offset
) + b
->buf_x_offset
;
224 for(y
=start_y
; y
<end_y
; y
++){
226 // line = slice_buffer_get_line_from_address(sb, src + (y * stride));
227 line
= slice_buffer_get_line(sb
, (y
* b
->stride_line
) + b
->buf_y_offset
) + b
->buf_x_offset
;
231 if(y
&& x
+1<w
) line
[x
] += mid_pred(line
[x
- 1], prev
[x
], prev
[x
+ 1]);
232 else line
[x
] += line
[x
- 1];
234 if(y
) line
[x
] += mid_pred(line
[x
- 1], prev
[x
], line
[x
- 1] + prev
[x
] - prev
[x
- 1]);
235 else line
[x
] += line
[x
- 1];
238 if(y
) line
[x
] += prev
[x
];
244 static void decode_qlogs(SnowContext
*s
){
245 int plane_index
, level
, orientation
;
247 for(plane_index
=0; plane_index
< s
->nb_planes
; plane_index
++){
248 for(level
=0; level
<s
->spatial_decomposition_count
; level
++){
249 for(orientation
=level
? 1:0; orientation
<4; orientation
++){
251 if (plane_index
==2) q
= s
->plane
[1].band
[level
][orientation
].qlog
;
252 else if(orientation
==2) q
= s
->plane
[plane_index
].band
[level
][1].qlog
;
253 else q
= get_symbol(&s
->c
, s
->header_state
, 1);
254 s
->plane
[plane_index
].band
[level
][orientation
].qlog
= q
;
260 #define GET_S(dst, check) \
261 tmp= get_symbol(&s->c, s->header_state, 0);\
263 av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
264 return AVERROR_INVALIDDATA;\
268 static int decode_header(SnowContext
*s
){
269 int plane_index
, tmp
;
272 memset(kstate
, MID_STATE
, sizeof(kstate
));
274 s
->keyframe
= get_rac(&s
->c
, kstate
);
275 if(s
->keyframe
|| s
->always_reset
){
276 ff_snow_reset_contexts(s
);
277 s
->spatial_decomposition_type
=
281 s
->block_max_depth
= 0;
284 GET_S(s
->version
, tmp
<= 0U)
285 s
->always_reset
= get_rac(&s
->c
, s
->header_state
);
286 s
->temporal_decomposition_type
= get_symbol(&s
->c
, s
->header_state
, 0);
287 s
->temporal_decomposition_count
= get_symbol(&s
->c
, s
->header_state
, 0);
288 GET_S(s
->spatial_decomposition_count
, 0 < tmp
&& tmp
<= MAX_DECOMPOSITIONS
)
289 s
->colorspace_type
= get_symbol(&s
->c
, s
->header_state
, 0);
290 if (s
->colorspace_type
== 1) {
291 s
->avctx
->pix_fmt
= AV_PIX_FMT_GRAY8
;
293 } else if(s
->colorspace_type
== 0) {
294 s
->chroma_h_shift
= get_symbol(&s
->c
, s
->header_state
, 0);
295 s
->chroma_v_shift
= get_symbol(&s
->c
, s
->header_state
, 0);
297 if(s
->chroma_h_shift
== 1 && s
->chroma_v_shift
==1){
298 s
->avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
299 }else if(s
->chroma_h_shift
== 0 && s
->chroma_v_shift
==0){
300 s
->avctx
->pix_fmt
= AV_PIX_FMT_YUV444P
;
301 }else if(s
->chroma_h_shift
== 2 && s
->chroma_v_shift
==2){
302 s
->avctx
->pix_fmt
= AV_PIX_FMT_YUV410P
;
304 av_log(s
, AV_LOG_ERROR
, "unsupported color subsample mode %d %d\n", s
->chroma_h_shift
, s
->chroma_v_shift
);
305 s
->chroma_h_shift
= s
->chroma_v_shift
= 1;
306 s
->avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
307 return AVERROR_INVALIDDATA
;
311 av_log(s
, AV_LOG_ERROR
, "unsupported color space\n");
312 s
->chroma_h_shift
= s
->chroma_v_shift
= 1;
313 s
->avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
314 return AVERROR_INVALIDDATA
;
318 s
->spatial_scalability
= get_rac(&s
->c
, s
->header_state
);
319 // s->rate_scalability= get_rac(&s->c, s->header_state);
320 GET_S(s
->max_ref_frames
, tmp
< (unsigned)MAX_REF_FRAMES
)
327 if(get_rac(&s
->c
, s
->header_state
)){
328 for(plane_index
=0; plane_index
<FFMIN(s
->nb_planes
, 2); plane_index
++){
330 Plane
*p
= &s
->plane
[plane_index
];
331 p
->diag_mc
= get_rac(&s
->c
, s
->header_state
);
332 htaps
= get_symbol(&s
->c
, s
->header_state
, 0)*2 + 2;
333 if((unsigned)htaps
> HTAPS_MAX
|| htaps
==0)
334 return AVERROR_INVALIDDATA
;
336 for(i
= htaps
/2; i
; i
--){
337 p
->hcoeff
[i
]= get_symbol(&s
->c
, s
->header_state
, 0) * (1-2*(i
&1));
340 p
->hcoeff
[0]= 32-sum
;
342 s
->plane
[2].diag_mc
= s
->plane
[1].diag_mc
;
343 s
->plane
[2].htaps
= s
->plane
[1].htaps
;
344 memcpy(s
->plane
[2].hcoeff
, s
->plane
[1].hcoeff
, sizeof(s
->plane
[1].hcoeff
));
346 if(get_rac(&s
->c
, s
->header_state
)){
347 GET_S(s
->spatial_decomposition_count
, 0 < tmp
&& tmp
<= MAX_DECOMPOSITIONS
)
352 s
->spatial_decomposition_type
+= get_symbol(&s
->c
, s
->header_state
, 1);
353 if(s
->spatial_decomposition_type
> 1U){
354 av_log(s
->avctx
, AV_LOG_ERROR
, "spatial_decomposition_type %d not supported\n", s
->spatial_decomposition_type
);
355 return AVERROR_INVALIDDATA
;
357 if(FFMIN(s
->avctx
-> width
>>s
->chroma_h_shift
,
358 s
->avctx
->height
>>s
->chroma_v_shift
) >> (s
->spatial_decomposition_count
-1) <= 1){
359 av_log(s
->avctx
, AV_LOG_ERROR
, "spatial_decomposition_count %d too large for size\n", s
->spatial_decomposition_count
);
360 return AVERROR_INVALIDDATA
;
364 s
->qlog
+= get_symbol(&s
->c
, s
->header_state
, 1);
365 s
->mv_scale
+= get_symbol(&s
->c
, s
->header_state
, 1);
366 s
->qbias
+= get_symbol(&s
->c
, s
->header_state
, 1);
367 s
->block_max_depth
+= get_symbol(&s
->c
, s
->header_state
, 1);
368 if(s
->block_max_depth
> 1 || s
->block_max_depth
< 0){
369 av_log(s
->avctx
, AV_LOG_ERROR
, "block_max_depth= %d is too large\n", s
->block_max_depth
);
370 s
->block_max_depth
= 0;
371 return AVERROR_INVALIDDATA
;
377 static av_cold
int decode_init(AVCodecContext
*avctx
)
381 if ((ret
= ff_snow_common_init(avctx
)) < 0) {
382 ff_snow_common_end(avctx
->priv_data
);
389 static int decode_blocks(SnowContext
*s
){
397 if ((res
= decode_q_branch(s
, 0, x
, y
)) < 0)
404 static int decode_frame(AVCodecContext
*avctx
, void *data
, int *got_frame
,
407 const uint8_t *buf
= avpkt
->data
;
408 int buf_size
= avpkt
->size
;
409 SnowContext
*s
= avctx
->priv_data
;
410 RangeCoder
* const c
= &s
->c
;
412 AVFrame
*picture
= data
;
413 int level
, orientation
, plane_index
;
416 ff_init_range_decoder(c
, buf
, buf_size
);
417 ff_build_rac_states(c
, 0.05*(1LL<<32), 256-8);
419 s
->current_picture
->pict_type
= AV_PICTURE_TYPE_I
; //FIXME I vs. P
420 if ((res
= decode_header(s
)) < 0)
422 if ((res
=ff_snow_common_init_after_header(avctx
)) < 0)
425 // realloc slice buffer for the case that spatial_decomposition_count changed
426 ff_slice_buffer_destroy(&s
->sb
);
427 if ((res
= ff_slice_buffer_init(&s
->sb
, s
->plane
[0].height
,
428 (MB_SIZE
>> s
->block_max_depth
) +
429 s
->spatial_decomposition_count
* 11 + 1,
431 s
->spatial_idwt_buffer
)) < 0)
434 for(plane_index
=0; plane_index
< s
->nb_planes
; plane_index
++){
435 Plane
*p
= &s
->plane
[plane_index
];
436 p
->fast_mc
= p
->diag_mc
&& p
->htaps
==6 && p
->hcoeff
[0]==40
441 ff_snow_alloc_blocks(s
);
443 if((res
= ff_snow_frame_start(s
)) < 0)
445 //keyframe flag duplication mess FIXME
446 if(avctx
->debug
&FF_DEBUG_PICT_INFO
)
447 av_log(avctx
, AV_LOG_ERROR
,
448 "keyframe:%d qlog:%d qbias: %d mvscale: %d "
449 "decomposition_type:%d decomposition_count:%d\n",
450 s
->keyframe
, s
->qlog
, s
->qbias
, s
->mv_scale
,
451 s
->spatial_decomposition_type
,
452 s
->spatial_decomposition_count
455 if ((res
= decode_blocks(s
)) < 0)
458 for(plane_index
=0; plane_index
< s
->nb_planes
; plane_index
++){
459 Plane
*p
= &s
->plane
[plane_index
];
463 int decode_state
[MAX_DECOMPOSITIONS
][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
465 if(s
->avctx
->debug
&2048){
466 memset(s
->spatial_dwt_buffer
, 0, sizeof(DWTELEM
)*w
*h
);
467 predict_plane(s
, s
->spatial_idwt_buffer
, plane_index
, 1);
471 int v
= s
->current_picture
->data
[plane_index
][y
*s
->current_picture
->linesize
[plane_index
] + x
];
472 s
->mconly_picture
->data
[plane_index
][y
*s
->mconly_picture
->linesize
[plane_index
] + x
]= v
;
478 for(level
=0; level
<s
->spatial_decomposition_count
; level
++){
479 for(orientation
=level
? 1 : 0; orientation
<4; orientation
++){
480 SubBand
*b
= &p
->band
[level
][orientation
];
481 unpack_coeffs(s
, b
, b
->parent
, orientation
);
487 const int mb_h
= s
->b_height
<< s
->block_max_depth
;
488 const int block_size
= MB_SIZE
>> s
->block_max_depth
;
489 const int block_h
= plane_index
? block_size
>>s
->chroma_v_shift
: block_size
;
491 DWTCompose cs
[MAX_DECOMPOSITIONS
];
496 ff_spatial_idwt_buffered_init(cs
, &s
->sb
, w
, h
, 1, s
->spatial_decomposition_type
, s
->spatial_decomposition_count
);
497 for(mb_y
=0; mb_y
<=mb_h
; mb_y
++){
499 int slice_starty
= block_h
*mb_y
;
500 int slice_h
= block_h
*(mb_y
+1);
502 if (!(s
->keyframe
|| s
->avctx
->debug
&512)){
503 slice_starty
= FFMAX(0, slice_starty
- (block_h
>> 1));
504 slice_h
-= (block_h
>> 1);
507 for(level
=0; level
<s
->spatial_decomposition_count
; level
++){
508 for(orientation
=level
? 1 : 0; orientation
<4; orientation
++){
509 SubBand
*b
= &p
->band
[level
][orientation
];
512 int our_mb_start
= mb_y
;
513 int our_mb_end
= (mb_y
+ 1);
515 start_y
= (mb_y
? ((block_h
* our_mb_start
) >> (s
->spatial_decomposition_count
- level
)) + s
->spatial_decomposition_count
- level
+ extra
: 0);
516 end_y
= (((block_h
* our_mb_end
) >> (s
->spatial_decomposition_count
- level
)) + s
->spatial_decomposition_count
- level
+ extra
);
517 if (!(s
->keyframe
|| s
->avctx
->debug
&512)){
518 start_y
= FFMAX(0, start_y
- (block_h
>> (1+s
->spatial_decomposition_count
- level
)));
519 end_y
= FFMAX(0, end_y
- (block_h
>> (1+s
->spatial_decomposition_count
- level
)));
521 start_y
= FFMIN(b
->height
, start_y
);
522 end_y
= FFMIN(b
->height
, end_y
);
524 if (start_y
!= end_y
){
525 if (orientation
== 0){
526 SubBand
* correlate_band
= &p
->band
[0][0];
527 int correlate_end_y
= FFMIN(b
->height
, end_y
+ 1);
528 int correlate_start_y
= FFMIN(b
->height
, (start_y
? start_y
+ 1 : 0));
529 decode_subband_slice_buffered(s
, correlate_band
, &s
->sb
, correlate_start_y
, correlate_end_y
, decode_state
[0][0]);
530 correlate_slice_buffered(s
, &s
->sb
, correlate_band
, correlate_band
->ibuf
, correlate_band
->stride
, 1, 0, correlate_start_y
, correlate_end_y
);
531 dequantize_slice_buffered(s
, &s
->sb
, correlate_band
, correlate_band
->ibuf
, correlate_band
->stride
, start_y
, end_y
);
534 decode_subband_slice_buffered(s
, b
, &s
->sb
, start_y
, end_y
, decode_state
[level
][orientation
]);
539 for(; yd
<slice_h
; yd
+=4){
540 ff_spatial_idwt_buffered_slice(&s
->dwt
, cs
, &s
->sb
, s
->temp_idwt_buffer
, w
, h
, 1, s
->spatial_decomposition_type
, s
->spatial_decomposition_count
, yd
);
543 if(s
->qlog
== LOSSLESS_QLOG
){
544 for(; yq
<slice_h
&& yq
<h
; yq
++){
545 IDWTELEM
* line
= slice_buffer_get_line(&s
->sb
, yq
);
547 line
[x
] <<= FRAC_BITS
;
552 predict_slice_buffered(s
, &s
->sb
, s
->spatial_idwt_buffer
, plane_index
, 1, mb_y
);
554 y
= FFMIN(p
->height
, slice_starty
);
555 end_y
= FFMIN(p
->height
, slice_h
);
557 ff_slice_buffer_release(&s
->sb
, y
++);
560 ff_slice_buffer_flush(&s
->sb
);
567 ff_snow_release_buffer(avctx
);
569 if(!(s
->avctx
->debug
&2048))
570 res
= av_frame_ref(picture
, s
->current_picture
);
572 res
= av_frame_ref(picture
, s
->mconly_picture
);
579 bytes_read
= c
->bytestream
- c
->bytestream_start
;
580 if(bytes_read
==0) av_log(s
->avctx
, AV_LOG_ERROR
, "error at end of frame\n"); //FIXME
585 static av_cold
int decode_end(AVCodecContext
*avctx
)
587 SnowContext
*s
= avctx
->priv_data
;
589 ff_slice_buffer_destroy(&s
->sb
);
591 ff_snow_common_end(s
);
596 AVCodec ff_snow_decoder
= {
598 .long_name
= NULL_IF_CONFIG_SMALL("Snow"),
599 .type
= AVMEDIA_TYPE_VIDEO
,
600 .id
= AV_CODEC_ID_SNOW
,
601 .priv_data_size
= sizeof(SnowContext
),
604 .decode
= decode_frame
,
605 .capabilities
= CODEC_CAP_DR1
/*| CODEC_CAP_DRAW_HORIZ_BAND*/,