summaryrefslogtreecommitdiffstats
path: root/libavcodec/snowdec.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-06-22 15:17:33 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-06-22 15:46:13 +0200
commit68c845cdba48bf0853fcd7bb7f9efe2623e24e9b (patch)
tree3004a2be60cfed29daa5e9c814aa249fce3d5252 /libavcodec/snowdec.c
parent13ba872a2a7f1277f3c192e4dbaaaa22be5c6b07 (diff)
downloadffmpeg-streaming-68c845cdba48bf0853fcd7bb7f9efe2623e24e9b.zip
ffmpeg-streaming-68c845cdba48bf0853fcd7bb7f9efe2623e24e9b.tar.gz
snow: yuv444 support
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/snowdec.c')
-rw-r--r--libavcodec/snowdec.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index a4d8d4e..4a34cf8 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -41,9 +41,10 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer
const int mb_h= s->b_height << s->block_max_depth;
int x, y, mb_x;
int block_size = MB_SIZE >> s->block_max_depth;
- int block_w = plane_index ? block_size/2 : block_size;
- const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth];
- int obmc_stride= plane_index ? block_size : 2*block_size;
+ int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size;
+ int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
+ const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
+ int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
int ref_stride= s->current_picture.linesize[plane_index];
uint8_t *dst8= s->current_picture.data[plane_index];
int w= p->width;
@@ -54,7 +55,7 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer
return;
if(add){
- for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+ for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
// DWTELEM * line = slice_buffer_get_line(sb, y);
IDWTELEM * line = sb->line[y];
for(x=0; x<w; x++){
@@ -66,7 +67,7 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer
}
}
}else{
- for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+ for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
// DWTELEM * line = slice_buffer_get_line(sb, y);
IDWTELEM * line = sb->line[y];
for(x=0; x<w; x++){
@@ -82,8 +83,8 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer
for(mb_x=0; mb_x<=mb_w; mb_x++){
add_yblock(s, 1, sb, old_buffer, dst8, obmc,
block_w*mb_x - block_w/2,
- block_w*mb_y - block_w/2,
- block_w, block_w,
+ block_h*mb_y - block_h/2,
+ block_w, block_h,
w, h,
w, ref_stride, obmc_stride,
mb_x - 1, mb_y - 1,
@@ -289,6 +290,18 @@ static int decode_header(SnowContext *s){
s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
+
+ if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){
+ s->avctx->pix_fmt= PIX_FMT_YUV420P;
+ }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){
+ s->avctx->pix_fmt= PIX_FMT_YUV444P;
+ } else {
+ av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift);
+ s->chroma_h_shift = s->chroma_v_shift = 1;
+ s->avctx->pix_fmt= PIX_FMT_YUV420P;
+ return AVERROR_INVALIDDATA;
+ }
+
s->spatial_scalability= get_rac(&s->c, s->header_state);
// s->rate_scalability= get_rac(&s->c, s->header_state);
GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
@@ -334,10 +347,6 @@ static int decode_header(SnowContext *s){
return -1;
}
- if (s->chroma_h_shift != 1 || s->chroma_v_shift != 1) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid chroma shift\n");
- return AVERROR_PATCHWELCOME;
- }
s->qlog += get_symbol(&s->c, s->header_state, 1);
s->mv_scale += get_symbol(&s->c, s->header_state, 1);
@@ -354,8 +363,6 @@ static int decode_header(SnowContext *s){
static av_cold int decode_init(AVCodecContext *avctx)
{
- avctx->pix_fmt= PIX_FMT_YUV420P;
-
ff_snow_common_init(avctx);
return 0;
@@ -452,7 +459,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
{
const int mb_h= s->b_height << s->block_max_depth;
const int block_size = MB_SIZE >> s->block_max_depth;
- const int block_w = plane_index ? block_size/2 : block_size;
+ const int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size;
+ const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
int mb_y;
DWTCompose cs[MAX_DECOMPOSITIONS];
int yd=0, yq=0;
@@ -462,11 +470,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
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++){
- int slice_starty = block_w*mb_y;
- int slice_h = block_w*(mb_y+1);
+ int slice_starty = block_h*mb_y;
+ int slice_h = block_h*(mb_y+1);
+
if (!(s->keyframe || s->avctx->debug&512)){
- slice_starty = FFMAX(0, slice_starty - (block_w >> 1));
- slice_h -= (block_w >> 1);
+ slice_starty = FFMAX(0, slice_starty - (block_h >> 1));
+ slice_h -= (block_h >> 1);
}
for(level=0; level<s->spatial_decomposition_count; level++){
@@ -477,11 +486,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
int our_mb_start = mb_y;
int our_mb_end = (mb_y + 1);
const int extra= 3;
- start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
- end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
+ start_y = (mb_y ? ((block_h * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
+ end_y = (((block_h * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
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 = FFMAX(0, start_y - (block_h >> (1+s->spatial_decomposition_count - level)));
+ end_y = FFMAX(0, end_y - (block_h >> (1+s->spatial_decomposition_count - level)));
}
start_y = FFMIN(b->height, start_y);
end_y = FFMIN(b->height, end_y);
OpenPOWER on IntegriCloud