--- trunk/xvidcore/src/decoder.c 2010/11/12 10:10:40 1905 +++ trunk/xvidcore/src/decoder.c 2022/01/27 17:47:14 2197 @@ -4,7 +4,7 @@ * - Decoder Module - * * Copyright(C) 2002 MinChen - * 2002-2004 Peter Ross + * 2002-2010 Peter Ross * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: decoder.c,v 1.84 2010-11-12 10:10:40 Isibaar Exp $ + * $Id$ * ****************************************************************************/ @@ -149,6 +149,7 @@ int decoder_create(xvid_dec_create_t * create) { + int ret = 0; DECODER *dec; if (XVID_VERSION_MAJOR(create->version) != 1) /* v1.x.x */ @@ -169,8 +170,10 @@ create->handle = dec; - dec->width = create->width; - dec->height = create->height; + dec->width = MAX(0, create->width); + dec->height = MAX(0, create->height); + + dec->num_threads = MAX(0, create->num_threads); image_null(&dec->cur); image_null(&dec->refn[0]); @@ -207,13 +210,10 @@ dec->fixed_dimensions = (dec->width > 0 && dec->height > 0); - if (dec->fixed_dimensions) { - int ret = decoder_resize(dec); - if (ret == XVID_ERR_MEMORY) create->handle = NULL; - return ret; - } - else - return 0; + ret = decoder_resize(dec); + if (ret == XVID_ERR_MEMORY) create->handle = NULL; + + return ret; } @@ -264,7 +264,7 @@ uint32_t stride2 = stride / 2; uint32_t next_block = stride * 8; uint32_t i; - uint32_t iQuant = pMB->quant; + uint32_t iQuant = MAX(1, pMB->quant); uint8_t *pY_Cur, *pU_Cur, *pV_Cur; pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4); @@ -361,7 +361,7 @@ int stride = dec->edged_width; int i; - const uint32_t iQuant = pMB->quant; + const uint32_t iQuant = MAX(1, pMB->quant); const int direction = dec->alternate_vertical_scan ? 2 : 0; typedef void (*get_inter_block_function_t)( Bitstream * bs, @@ -1389,17 +1389,6 @@ MACROBLOCK *last_mb = &dec->last_mbs[y * dec->mb_width + x]; int intra_dc_threshold; /* fake variable */ - if (check_resync_marker(bs, resync_len)) { - int bound = read_video_packet_header(bs, dec, resync_len, &quant, - &fcode_forward, &fcode_backward, &intra_dc_threshold); - x = bound % dec->mb_width; - y = MIN((bound / dec->mb_width), (dec->mb_height-1)); - /* reset predicted macroblocks */ - dec->p_fmv = dec->p_bmv = zeromv; - /* update resync len with new fcodes */ - resync_len = get_resync_len_b(fcode_backward, fcode_forward); - } - mv = mb->b_mvs[0] = mb->b_mvs[1] = mb->b_mvs[2] = mb->b_mvs[3] = mb->mvs[0] = mb->mvs[1] = mb->mvs[2] = mb->mvs[3] = zeromv; @@ -1418,6 +1407,20 @@ continue; } + if (check_resync_marker(bs, resync_len)) { + int bound = read_video_packet_header(bs, dec, resync_len, &quant, + &fcode_forward, &fcode_backward, &intra_dc_threshold); + + bound = MAX(0, bound-1); /* valid bound must always be >0 */ + x = bound % dec->mb_width; + y = MIN((bound / dec->mb_width), (dec->mb_height-1)); + /* reset predicted macroblocks */ + dec->p_fmv = dec->p_bmv = zeromv; + /* update resync len with new fcodes */ + resync_len = get_resync_len_b(fcode_backward, fcode_forward); + continue; /* re-init loop */ + } + if (!BitstreamGetBit(bs)) { /* modb=='0' */ const uint8_t modb2 = BitstreamGetBit(bs); @@ -1531,13 +1534,16 @@ image_copy(&dec->tmp, img, dec->edged_width, dec->height); image_postproc(&dec->postproc, &dec->tmp, dec->edged_width, mbs, dec->mb_width, dec->mb_height, dec->mb_width, - frame->general, brightness, dec->frames, (coding_type == B_VOP)); + frame->general, brightness, dec->frames, (coding_type == B_VOP), dec->num_threads); img = &dec->tmp; } - image_output(img, dec->width, dec->height, - dec->edged_width, (uint8_t**)frame->output.plane, frame->output.stride, - frame->output.csp, dec->interlacing); + if ((frame->output.csp == XVID_CSP_INTERNAL) || + ((frame->output.plane[0] != NULL) && (frame->output.stride[0] >= dec->width))) { + image_output(img, dec->width, dec->height, + dec->edged_width, (uint8_t**)frame->output.plane, frame->output.stride, + frame->output.csp, dec->interlacing); + } if (stats) { stats->type = coding2type(coding_type); @@ -1560,19 +1566,20 @@ { Bitstream bs; - uint32_t rounding; + uint32_t rounding = 0; uint32_t quant = 2; - uint32_t fcode_forward; - uint32_t fcode_backward; - uint32_t intra_dc_threshold; + uint32_t fcode_forward = 0; + uint32_t fcode_backward = 0; + uint32_t intra_dc_threshold = 0; WARPPOINTS gmc_warp; - int coding_type; + int coding_type = -1; int success, output, seen_something; if (XVID_VERSION_MAJOR(frame->version) != 1 || (stats && XVID_VERSION_MAJOR(stats->version) != 1)) /* v1.x.x */ return XVID_ERR_VERSION; start_global_timer(); + memset((void *)&gmc_warp, 0, sizeof(WARPPOINTS)); dec->low_delay_default = (frame->general & XVID_LOWDELAY); if ((frame->general & XVID_DISCONTINUITY)) @@ -1642,8 +1649,13 @@ if(stats) { stats->type = XVID_TYPE_VOL; stats->data.vol.general = 0; - /*XXX: if (dec->interlacing) - stats->data.vol.general |= ++INTERLACING; */ + stats->data.vop.general = 0; + if (dec->interlacing) { + stats->data.vol.general |= XVID_VOL_INTERLACING; + if (dec->top_field_first) { + stats->data.vop.general |= XVID_VOP_TOPFIELDFIRST; + } + } stats->data.vol.width = dec->width; stats->data.vol.height = dec->height; stats->data.vol.par = dec->aspect_ratio; @@ -1655,7 +1667,7 @@ goto repeat; } - if(dec->frames == 0 && coding_type != I_VOP) { + if((dec->frames == 0 && coding_type != I_VOP) || (!dec->width || !dec->height)) { /* 1st frame is not an i-vop */ goto repeat; }