X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Frv34.c;h=c5dcfdcba45afc63720e2d4844d7dd76b4fc39ce;hb=82494cad9db1f32f13b6643b7dce15f2688e3f27;hp=66036414d547cc44753f9734b8bfc147dead3b6e;hpb=0304109df620e95e33edf43ba47ddf7bdccd7620;p=ffmpeg diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 66036414d54..c5dcfdcba45 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -2,25 +2,25 @@ * RV30/40 decoder common data * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file libavcodec/rv34.c + * @file * RV30/40 decoder common data */ @@ -37,6 +37,12 @@ //#define DEBUG +static inline void ZERO8x2(void* dst, int stride) +{ + fill_rectangle(dst, 1, 2, stride, 0, 4); + fill_rectangle(((uint8_t*)(dst))+4, 1, 2, stride, 0, 4); +} + /** translation of RV30/40 macroblock types to lavc ones */ static const int rv34_mb_type_to_lavc[12] = { MB_TYPE_INTRA, @@ -56,24 +62,51 @@ static const int rv34_mb_type_to_lavc[12] = { static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES]; +static int rv34_decode_mv(RV34DecContext *r, int block_type); + /** - * @defgroup vlc RV30/40 VLC generating functions + * @name RV30/40 VLC generating functions * @{ */ +static const int table_offs[] = { + 0, 1818, 3622, 4144, 4698, 5234, 5804, 5868, 5900, 5932, + 5996, 6252, 6316, 6348, 6380, 7674, 8944, 10274, 11668, 12250, + 14060, 15846, 16372, 16962, 17512, 18148, 18180, 18212, 18244, 18308, + 18564, 18628, 18660, 18692, 20036, 21314, 22648, 23968, 24614, 26384, + 28190, 28736, 29366, 29938, 30608, 30640, 30672, 30704, 30768, 31024, + 31088, 31120, 31184, 32570, 33898, 35236, 36644, 37286, 39020, 40802, + 41368, 42052, 42692, 43348, 43380, 43412, 43444, 43476, 43604, 43668, + 43700, 43732, 45100, 46430, 47778, 49160, 49802, 51550, 53340, 53972, + 54648, 55348, 55994, 56122, 56154, 56186, 56218, 56346, 56410, 56442, + 56474, 57878, 59290, 60636, 62036, 62682, 64460, 64524, 64588, 64716, + 64844, 66076, 67466, 67978, 68542, 69064, 69648, 70296, 72010, 72074, + 72138, 72202, 72330, 73572, 74936, 75454, 76030, 76566, 77176, 77822, + 79582, 79646, 79678, 79742, 79870, 81180, 82536, 83064, 83672, 84242, + 84934, 85576, 87384, 87448, 87480, 87544, 87672, 88982, 90340, 90902, + 91598, 92182, 92846, 93488, 95246, 95278, 95310, 95374, 95502, 96878, + 98266, 98848, 99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416, + 103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398, + 111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592 +}; + +static VLC_TYPE table_data[117592][2]; + /** * Generate VLC from codeword lengths. * @param bits codeword lengths (zeroes are accepted) * @param size length of input data * @param vlc output VLC * @param insyms symbols for input codes (NULL for default ones) + * @param num VLC table number (for static initialization) */ -static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms) +static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms, + const int num) { int i; int counts[17] = {0}, codes[17]; - uint16_t cw[size], syms[size]; - uint8_t bits2[size]; + uint16_t cw[MAX_VLC_SIZE], syms[MAX_VLC_SIZE]; + uint8_t bits2[MAX_VLC_SIZE]; int maxbits = 0, realsize = 0; for(i = 0; i < size; i++){ @@ -92,10 +125,12 @@ static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t for(i = 0; i < realsize; i++) cw[i] = codes[bits2[i]]++; + vlc->table = &table_data[table_offs[num]]; + vlc->table_allocated = table_offs[num + 1] - table_offs[num]; init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize, bits2, 1, 1, cw, 2, 2, - syms, 2, 2, INIT_VLC_USE_STATIC); + syms, 2, 2, INIT_VLC_USE_NEW_STATIC); } /** @@ -107,27 +142,30 @@ static av_cold void rv34_init_tables(void) for(i = 0; i < NUM_INTRA_TABLES; i++){ for(j = 0; j < 2; j++){ - rv34_gen_vlc(rv34_table_intra_cbppat [i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j], NULL); - rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL); - rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j], NULL); - for(k = 0; k < 4; k++) - rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k], rv34_cbp_code); + rv34_gen_vlc(rv34_table_intra_cbppat [i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j], NULL, 19*i + 0 + j); + rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL, 19*i + 2 + j); + rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j], NULL, 19*i + 4 + j); + for(k = 0; k < 4; k++){ + rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k], rv34_cbp_code, 19*i + 6 + j*4 + k); + } + } + for(j = 0; j < 4; j++){ + rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL, 19*i + 14 + j); } - for(j = 0; j < 4; j++) - rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL); - rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL); + rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18); } for(i = 0; i < NUM_INTER_TABLES; i++){ - rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL); - for(j = 0; j < 4; j++) - rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code); + rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL, i*12 + 95); + for(j = 0; j < 4; j++){ + rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code, i*12 + 96 + j); + } for(j = 0; j < 2; j++){ - rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j], NULL); - rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL); - rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j], NULL); + rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j], NULL, i*12 + 100 + j); + rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL, i*12 + 102 + j); + rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j], NULL, i*12 + 104 + j); } - rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL); + rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106); } } @@ -135,7 +173,7 @@ static av_cold void rv34_init_tables(void) /** - * @defgroup transform RV30/40 inverse transform functions + * @name RV30/40 inverse transform functions * @{ */ @@ -210,7 +248,7 @@ static void rv34_inv_transform_noround(DCTELEM *block){ /** - * @defgroup block RV30/40 4x4 block decoding functions + * @name RV30/40 4x4 block decoding functions * @{ */ @@ -357,7 +395,7 @@ static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q) /** - * @defgroup bitstream RV30/40 bitstream parsing + * @name RV30/40 bitstream parsing * @{ */ @@ -396,10 +434,76 @@ static inline int rv34_decode_dquant(GetBitContext *gb, int quant) return get_bits(gb, 5); } +/** + * Decode macroblock header and return CBP in case of success, -1 otherwise. + */ +static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) +{ + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int i, t; + + if(!r->si.type){ + r->is16 = get_bits1(gb); + if(!r->is16 && !r->rv30){ + if(!get_bits1(gb)) + av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); + } + s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA; + r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA; + }else{ + r->block_type = r->decode_mb_info(r); + if(r->block_type == -1) + return -1; + s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; + r->mb_type[mb_pos] = r->block_type; + if(r->block_type == RV34_MB_SKIP){ + if(s->pict_type == AV_PICTURE_TYPE_P) + r->mb_type[mb_pos] = RV34_MB_P_16x16; + if(s->pict_type == AV_PICTURE_TYPE_B) + r->mb_type[mb_pos] = RV34_MB_B_DIRECT; + } + r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); + rv34_decode_mv(r, r->block_type); + if(r->block_type == RV34_MB_SKIP){ + fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0])); + return 0; + } + r->chroma_vlc = 1; + r->luma_vlc = 0; + } + if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ + if(r->is16){ + t = get_bits(gb, 2); + fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0])); + r->luma_vlc = 2; + }else{ + if(r->decode_intra_types(r, gb, intra_types) < 0) + return -1; + r->luma_vlc = 1; + } + r->chroma_vlc = 0; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); + }else{ + for(i = 0; i < 16; i++) + intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); + if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){ + r->is16 = 1; + r->chroma_vlc = 1; + r->luma_vlc = 2; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); + } + } + + return rv34_decode_cbp(gb, r->cur_vlcs, r->is16); +} + /** @} */ //bitstream functions /** - * @defgroup mv motion vector related code (prediction, reconstruction, motion compensation) + * @name motion vector related code (prediction, reconstruction, motion compensation) * @{ */ @@ -410,7 +514,7 @@ static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 }; /** availability index for subblocks */ -static const uint8_t avail_indexes[4] = { 5, 6, 9, 10 }; +static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 }; /** * motion vector prediction @@ -523,21 +627,21 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir) memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B)); memset(C, 0, sizeof(C)); - if((r->avail_cache[5-1] & type) & mask){ + if((r->avail_cache[6-1] & type) & mask){ A[0] = cur_pic->motion_val[dir][mv_pos - 1][0]; A[1] = cur_pic->motion_val[dir][mv_pos - 1][1]; has_A = 1; } - if((r->avail_cache[5-4] & type) & mask){ + if((r->avail_cache[6-4] & type) & mask){ B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0]; B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1]; has_B = 1; } - if(r->avail_cache[5-4] && (r->avail_cache[5-2] & type) & mask){ + if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){ C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0]; C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1]; has_C = 1; - }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[5-5] & type) & mask){ + }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){ C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0]; C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1]; has_C = 1; @@ -554,8 +658,9 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir) cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my; } } - if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD) - fill_rectangle(cur_pic->motion_val[!dir][mv_pos], 2, 2, s->b8_stride, 0, 4); + if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){ + ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride); + } } /** @@ -681,12 +786,12 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type, uint8_t *uvbuf= s->edge_emu_buffer + 22 * s->linesize; srcY -= 2 + 2*s->linesize; - ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6, + s->dsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6, src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos); srcY = s->edge_emu_buffer + 2 + 2*s->linesize; - ff_emulated_edge_mc(uvbuf , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1, + s->dsp.emulated_edge_mc(uvbuf , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1, uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); - ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1, + s->dsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1, uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); srcU = uvbuf; srcV = uvbuf + 16; @@ -776,11 +881,11 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) switch(block_type){ case RV34_MB_TYPE_INTRA: case RV34_MB_TYPE_INTRA16x16: - fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); return 0; case RV34_MB_SKIP: - if(s->pict_type == FF_P_TYPE){ - fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); + if(s->pict_type == AV_PICTURE_TYPE_P){ + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); break; } @@ -788,8 +893,8 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) //surprisingly, it uses motion scheme from next reference frame next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride]; if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){ - fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); - fill_rectangle(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); + ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); }else for(j = 0; j < 2; j++) for(i = 0; i < 2; i++) @@ -800,7 +905,7 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) rv34_mc_2mv(r, block_type); else rv34_mc_2mv_skip(r); - fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); + ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride); break; case RV34_MB_P_16x16: case RV34_MB_P_MIX16x16: @@ -848,7 +953,7 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) /** @} */ // mv group /** - * @defgroup recons Macroblock reconstruction functions + * @name Macroblock reconstruction functions * @{ */ /** mapping of RV30/40 intra prediction types to standard H.264 types */ @@ -928,17 +1033,17 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c int idx; // Set neighbour information. - if(r->avail_cache[0]) - avail[0] = 1; if(r->avail_cache[1]) - avail[1] = avail[2] = 1; + avail[0] = 1; if(r->avail_cache[2]) - avail[3] = avail[4] = 1; + avail[1] = avail[2] = 1; if(r->avail_cache[3]) - avail[5] = 1; + avail[3] = avail[4] = 1; if(r->avail_cache[4]) + avail[5] = 1; + if(r->avail_cache[5]) avail[8] = avail[16] = 1; - if(r->avail_cache[8]) + if(r->avail_cache[9]) avail[24] = avail[32] = 1; Y = s->dest[0]; @@ -954,15 +1059,15 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32); } Y += s->linesize * 4 - 4*4; - intra_types += s->b4_stride; + intra_types += r->intra_types_stride; } - intra_types -= s->b4_stride * 4; - fill_rectangle(r->avail_cache + 5, 2, 2, 4, 0, 4); + intra_types -= r->intra_types_stride * 4; + fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4); for(j = 0; j < 2; j++){ - idx = 5 + j*4; + idx = 6 + j*4; for(i = 0; i < 2; i++, cbp >>= 1, idx++){ - rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); - rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); + rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); + rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*r->intra_types_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); r->avail_cache[idx] = 1; if(cbp & 0x01) rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32); @@ -972,7 +1077,7 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c } }else{ itype = ittrans16[intra_types[0]]; - itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]); + itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]); r->h.pred16x16[itype](Y, s->linesize); dsp->add_pixels_clamped(s->block[0], Y, s->linesize); dsp->add_pixels_clamped(s->block[1], Y + 8, s->linesize); @@ -982,7 +1087,7 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c itype = ittrans16[intra_types[0]]; if(itype == PLANE_PRED8x8) itype = DC_PRED8x8; - itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]); + itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]); r->h.pred8x8[itype](U, s->uvlinesize); dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize); r->h.pred8x8[itype](V, s->uvlinesize); @@ -990,79 +1095,6 @@ static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int c } } -/** @} */ // recons group - -/** - * @addtogroup bitstream - * Decode macroblock header and return CBP in case of success, -1 otherwise. - */ -static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) -{ - MpegEncContext *s = &r->s; - GetBitContext *gb = &s->gb; - int mb_pos = s->mb_x + s->mb_y * s->mb_stride; - int i, t; - - if(!r->si.type){ - r->is16 = get_bits1(gb); - if(!r->is16 && !r->rv30){ - if(!get_bits1(gb)) - av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); - } - s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA; - r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA; - }else{ - r->block_type = r->decode_mb_info(r); - if(r->block_type == -1) - return -1; - s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; - r->mb_type[mb_pos] = r->block_type; - if(r->block_type == RV34_MB_SKIP){ - if(s->pict_type == FF_P_TYPE) - r->mb_type[mb_pos] = RV34_MB_P_16x16; - if(s->pict_type == FF_B_TYPE) - r->mb_type[mb_pos] = RV34_MB_B_DIRECT; - } - r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); - rv34_decode_mv(r, r->block_type); - if(r->block_type == RV34_MB_SKIP){ - fill_rectangle(intra_types, 4, 4, s->b4_stride, 0, sizeof(intra_types[0])); - return 0; - } - r->chroma_vlc = 1; - r->luma_vlc = 0; - } - if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ - if(r->is16){ - t = get_bits(gb, 2); - fill_rectangle(intra_types, 4, 4, s->b4_stride, t, sizeof(intra_types[0])); - r->luma_vlc = 2; - }else{ - if(r->decode_intra_types(r, gb, intra_types) < 0) - return -1; - r->luma_vlc = 1; - } - r->chroma_vlc = 0; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); - }else{ - for(i = 0; i < 16; i++) - intra_types[(i & 3) + (i>>2) * s->b4_stride] = 0; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); - if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){ - r->is16 = 1; - r->chroma_vlc = 1; - r->luma_vlc = 2; - r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); - } - } - - return rv34_decode_cbp(gb, r->cur_vlcs, r->is16); -} - -/** - * @addtogroup recons - * @{ - */ /** * mask for retrieving all bits in coded block pattern * corresponding to one 8x8 block @@ -1072,6 +1104,8 @@ static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) #define U_CBP_MASK 0x0F0000 #define V_CBP_MASK 0xF00000 +/** @} */ // recons group + static void rv34_apply_differences(RV34DecContext *r, int cbp) { @@ -1105,7 +1139,7 @@ static int rv34_set_deblock_coef(RV34DecContext *r) MpegEncContext *s = &r->s; int hmvmask = 0, vmvmask = 0, i, j; int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; - int16_t (*motion_val)[2] = s->current_picture_ptr->motion_val[0][midx]; + int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx]; for(j = 0; j < 16; j += 8){ for(i = 0; i < 2; i++){ if(is_mv_diff_gt_3(motion_val + i, 1)) @@ -1143,24 +1177,24 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) // Calculate which neighbours are available. Maybe it's worth optimizing too. memset(r->avail_cache, 0, sizeof(r->avail_cache)); - fill_rectangle(r->avail_cache + 5, 2, 2, 4, 1, 4); + fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4); dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width; if(s->mb_x && dist) - r->avail_cache[4] = - r->avail_cache[8] = s->current_picture_ptr->mb_type[mb_pos - 1]; + r->avail_cache[5] = + r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1]; if(dist >= s->mb_width) - r->avail_cache[1] = - r->avail_cache[2] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]; + r->avail_cache[2] = + r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]; if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1) - r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1]; + r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1]; if(s->mb_x && dist > s->mb_width) - r->avail_cache[0] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1]; + r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1]; s->qscale = r->si.quant; cbp = cbp2 = rv34_decode_mb_header(r, intra_types); r->cbp_luma [mb_pos] = cbp; r->cbp_chroma[mb_pos] = cbp >> 16; - if(s->pict_type == FF_I_TYPE) + if(s->pict_type == AV_PICTURE_TYPE_I) r->deblock_coefs[mb_pos] = 0xFFFF; else r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos]; @@ -1250,21 +1284,23 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int MPV_common_end(s); s->width = r->si.width; s->height = r->si.height; + avcodec_set_dimensions(s->avctx, s->width, s->height); if(MPV_common_init(s) < 0) return -1; - r->intra_types_hist = av_realloc(r->intra_types_hist, s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist)); - r->intra_types = r->intra_types_hist + s->b4_stride * 4; + r->intra_types_stride = s->mb_width*4 + 4; + r->intra_types_hist = av_realloc(r->intra_types_hist, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); + r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); r->cbp_luma = av_realloc(r->cbp_luma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs)); } - s->pict_type = r->si.type ? r->si.type : FF_I_TYPE; + s->pict_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I; if(MPV_frame_start(s, s->avctx) < 0) return -1; ff_er_frame_start(s); r->cur_pts = r->si.pts; - if(s->pict_type != FF_B_TYPE){ + if(s->pict_type != AV_PICTURE_TYPE_B){ r->last_pts = r->next_pts; r->next_pts = r->cur_pts; } @@ -1283,7 +1319,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int s->mb_x = r->si.start % s->mb_width; s->mb_y = r->si.start / s->mb_width; } - memset(r->intra_types_hist, -1, s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist)); + memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); s->first_slice_line = 1; s->resync_mb_x= s->mb_x; s->resync_mb_y= s->mb_y; @@ -1293,7 +1329,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int ff_update_block_index(s); s->dsp.clear_blocks(s->block[0]); - if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 1) < 0){ + if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 4) < 0){ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_ERROR|DC_ERROR|MV_ERROR); return -1; } @@ -1302,8 +1338,8 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int s->mb_y++; ff_init_block_index(s); - memmove(r->intra_types_hist, r->intra_types, s->b4_stride * 4 * sizeof(*r->intra_types_hist)); - memset(r->intra_types, -1, s->b4_stride * 4 * sizeof(*r->intra_types_hist)); + memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist)); + memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist)); if(r->loop_filter && s->mb_y >= 2) r->loop_filter(r, s->mb_y - 2); @@ -1345,10 +1381,11 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; - ff_h264_pred_init(&r->h, CODEC_ID_RV40); + ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8); - r->intra_types_hist = av_malloc(s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist)); - r->intra_types = r->intra_types_hist + s->b4_stride * 4; + r->intra_types_stride = 4*s->mb_stride + 4; + r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); + r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); @@ -1370,8 +1407,10 @@ static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - const uint8_t *buf, int buf_size) + AVPacket *avpkt) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; RV34DecContext *r = avctx->priv_data; MpegEncContext *s = &r->s; AVFrame *pict = data; @@ -1410,17 +1449,12 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n"); return -1; } - if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == FF_B_TYPE) + if((!s->last_picture_ptr || !s->last_picture_ptr->data[0]) && si.type == AV_PICTURE_TYPE_B) return -1; - /* skip b frames if we are in a hurry */ - if(avctx->hurry_up && si.type==FF_B_TYPE) return buf_size; - if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==FF_B_TYPE) - || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=FF_I_TYPE) + if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B) + || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) return buf_size; - /* skip everything if we are in a hurry>=5 */ - if(avctx->hurry_up>=5) - return buf_size; for(i=0; iloop_filter(r, s->mb_height - 1); ff_er_frame_end(s); MPV_frame_end(s); - if (s->pict_type == FF_B_TYPE || s->low_delay) { + if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { *pict= *(AVFrame*)s->current_picture_ptr; } else if (s->last_picture_ptr != NULL) { *pict= *(AVFrame*)s->last_picture_ptr;