2 * RV30/40 decoder common data
3 * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * @file libavcodec/rv34.c
24 * RV30/40 decoder common data
29 #include "mpegvideo.h"
32 #include "rectangle.h"
40 static inline void ZERO8x2(void* dst
, int stride
)
42 fill_rectangle(dst
, 1, 2, stride
, 0, 4);
43 fill_rectangle(((uint8_t*)(dst
))+4, 1, 2, stride
, 0, 4);
46 /** translation of RV30/40 macroblock types to lavc ones */
47 static const int rv34_mb_type_to_lavc
[12] = {
49 MB_TYPE_INTRA16x16
| MB_TYPE_SEPARATE_DC
,
50 MB_TYPE_16x16
| MB_TYPE_L0
,
51 MB_TYPE_8x8
| MB_TYPE_L0
,
52 MB_TYPE_16x16
| MB_TYPE_L0
,
53 MB_TYPE_16x16
| MB_TYPE_L1
,
55 MB_TYPE_DIRECT2
| MB_TYPE_16x16
,
56 MB_TYPE_16x8
| MB_TYPE_L0
,
57 MB_TYPE_8x16
| MB_TYPE_L0
,
58 MB_TYPE_16x16
| MB_TYPE_L0L1
,
59 MB_TYPE_16x16
| MB_TYPE_L0
| MB_TYPE_SEPARATE_DC
63 static RV34VLC intra_vlcs
[NUM_INTRA_TABLES
], inter_vlcs
[NUM_INTER_TABLES
];
66 * @defgroup vlc RV30/40 VLC generating functions
70 static const int table_offs
[] = {
71 0, 1818, 3622, 4144, 4698, 5234, 5804, 5868, 5900, 5932,
72 5996, 6252, 6316, 6348, 6380, 7674, 8944, 10274, 11668, 12250,
73 14060, 15846, 16372, 16962, 17512, 18148, 18180, 18212, 18244, 18308,
74 18564, 18628, 18660, 18692, 20036, 21314, 22648, 23968, 24614, 26384,
75 28190, 28736, 29366, 29938, 30608, 30640, 30672, 30704, 30768, 31024,
76 31088, 31120, 31184, 32570, 33898, 35236, 36644, 37286, 39020, 40802,
77 41368, 42052, 42692, 43348, 43380, 43412, 43444, 43476, 43604, 43668,
78 43700, 43732, 45100, 46430, 47778, 49160, 49802, 51550, 53340, 53972,
79 54648, 55348, 55994, 56122, 56154, 56186, 56218, 56346, 56410, 56442,
80 56474, 57878, 59290, 60636, 62036, 62682, 64460, 64524, 64588, 64716,
81 64844, 66076, 67466, 67978, 68542, 69064, 69648, 70296, 72010, 72074,
82 72138, 72202, 72330, 73572, 74936, 75454, 76030, 76566, 77176, 77822,
83 79582, 79646, 79678, 79742, 79870, 81180, 82536, 83064, 83672, 84242,
84 84934, 85576, 87384, 87448, 87480, 87544, 87672, 88982, 90340, 90902,
85 91598, 92182, 92846, 93488, 95246, 95278, 95310, 95374, 95502, 96878,
86 98266, 98848, 99542, 100234, 100884, 101524, 103320, 103352, 103384, 103416,
87 103480, 104874, 106222, 106910, 107584, 108258, 108902, 109544, 111366, 111398,
88 111430, 111462, 111494, 112878, 114320, 114988, 115660, 116310, 116950, 117592
91 static VLC_TYPE table_data
[117592][2];
94 * Generate VLC from codeword lengths.
95 * @param bits codeword lengths (zeroes are accepted)
96 * @param size length of input data
97 * @param vlc output VLC
98 * @param insyms symbols for input codes (NULL for default ones)
99 * @param num VLC table number (for static initialization)
101 static void rv34_gen_vlc(const uint8_t *bits
, int size
, VLC
*vlc
, const uint8_t *insyms
,
105 int counts
[17] = {0}, codes
[17];
106 uint16_t cw
[size
], syms
[size
];
108 int maxbits
= 0, realsize
= 0;
110 for(i
= 0; i
< size
; i
++){
112 bits2
[realsize
] = bits
[i
];
113 syms
[realsize
] = insyms
? insyms
[i
] : i
;
115 maxbits
= FFMAX(maxbits
, bits
[i
]);
121 for(i
= 0; i
< 16; i
++)
122 codes
[i
+1] = (codes
[i
] + counts
[i
]) << 1;
123 for(i
= 0; i
< realsize
; i
++)
124 cw
[i
] = codes
[bits2
[i
]]++;
126 vlc
->table
= &table_data
[table_offs
[num
]];
127 vlc
->table_allocated
= table_offs
[num
+ 1] - table_offs
[num
];
128 init_vlc_sparse(vlc
, FFMIN(maxbits
, 9), realsize
,
131 syms
, 2, 2, INIT_VLC_USE_NEW_STATIC
);
135 * Initialize all tables.
137 static av_cold
void rv34_init_tables(void)
141 for(i
= 0; i
< NUM_INTRA_TABLES
; i
++){
142 for(j
= 0; j
< 2; j
++){
143 rv34_gen_vlc(rv34_table_intra_cbppat
[i
][j
], CBPPAT_VLC_SIZE
, &intra_vlcs
[i
].cbppattern
[j
], NULL
, 19*i
+ 0 + j
);
144 rv34_gen_vlc(rv34_table_intra_secondpat
[i
][j
], OTHERBLK_VLC_SIZE
, &intra_vlcs
[i
].second_pattern
[j
], NULL
, 19*i
+ 2 + j
);
145 rv34_gen_vlc(rv34_table_intra_thirdpat
[i
][j
], OTHERBLK_VLC_SIZE
, &intra_vlcs
[i
].third_pattern
[j
], NULL
, 19*i
+ 4 + j
);
146 for(k
= 0; k
< 4; k
++){
147 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
);
150 for(j
= 0; j
< 4; j
++){
151 rv34_gen_vlc(rv34_table_intra_firstpat
[i
][j
], FIRSTBLK_VLC_SIZE
, &intra_vlcs
[i
].first_pattern
[j
], NULL
, 19*i
+ 14 + j
);
153 rv34_gen_vlc(rv34_intra_coeff
[i
], COEFF_VLC_SIZE
, &intra_vlcs
[i
].coefficient
, NULL
, 19*i
+ 18);
156 for(i
= 0; i
< NUM_INTER_TABLES
; i
++){
157 rv34_gen_vlc(rv34_inter_cbppat
[i
], CBPPAT_VLC_SIZE
, &inter_vlcs
[i
].cbppattern
[0], NULL
, i
*12 + 95);
158 for(j
= 0; j
< 4; j
++){
159 rv34_gen_vlc(rv34_inter_cbp
[i
][j
], CBP_VLC_SIZE
, &inter_vlcs
[i
].cbp
[0][j
], rv34_cbp_code
, i
*12 + 96 + j
);
161 for(j
= 0; j
< 2; j
++){
162 rv34_gen_vlc(rv34_table_inter_firstpat
[i
][j
], FIRSTBLK_VLC_SIZE
, &inter_vlcs
[i
].first_pattern
[j
], NULL
, i
*12 + 100 + j
);
163 rv34_gen_vlc(rv34_table_inter_secondpat
[i
][j
], OTHERBLK_VLC_SIZE
, &inter_vlcs
[i
].second_pattern
[j
], NULL
, i
*12 + 102 + j
);
164 rv34_gen_vlc(rv34_table_inter_thirdpat
[i
][j
], OTHERBLK_VLC_SIZE
, &inter_vlcs
[i
].third_pattern
[j
], NULL
, i
*12 + 104 + j
);
166 rv34_gen_vlc(rv34_inter_coeff
[i
], COEFF_VLC_SIZE
, &inter_vlcs
[i
].coefficient
, NULL
, i
*12 + 106);
170 /** @} */ // vlc group
174 * @defgroup transform RV30/40 inverse transform functions
178 static av_always_inline
void rv34_row_transform(int temp
[16], DCTELEM
*block
)
183 const int z0
= 13*(block
[i
+8*0] + block
[i
+8*2]);
184 const int z1
= 13*(block
[i
+8*0] - block
[i
+8*2]);
185 const int z2
= 7* block
[i
+8*1] - 17*block
[i
+8*3];
186 const int z3
= 17* block
[i
+8*1] + 7*block
[i
+8*3];
196 * Real Video 3.0/4.0 inverse transform
197 * Code is almost the same as in SVQ3, only scaling is different.
199 static void rv34_inv_transform(DCTELEM
*block
){
203 rv34_row_transform(temp
, block
);
206 const int z0
= 13*(temp
[4*0+i
] + temp
[4*2+i
]) + 0x200;
207 const int z1
= 13*(temp
[4*0+i
] - temp
[4*2+i
]) + 0x200;
208 const int z2
= 7* temp
[4*1+i
] - 17*temp
[4*3+i
];
209 const int z3
= 17* temp
[4*1+i
] + 7*temp
[4*3+i
];
211 block
[i
*8+0]= (z0
+ z3
)>>10;
212 block
[i
*8+1]= (z1
+ z2
)>>10;
213 block
[i
*8+2]= (z1
- z2
)>>10;
214 block
[i
*8+3]= (z0
- z3
)>>10;
220 * RealVideo 3.0/4.0 inverse transform for DC block
222 * Code is almost the same as rv34_inv_transform()
223 * but final coefficients are multiplied by 1.5 and have no rounding.
225 static void rv34_inv_transform_noround(DCTELEM
*block
){
229 rv34_row_transform(temp
, block
);
232 const int z0
= 13*(temp
[4*0+i
] + temp
[4*2+i
]);
233 const int z1
= 13*(temp
[4*0+i
] - temp
[4*2+i
]);
234 const int z2
= 7* temp
[4*1+i
] - 17*temp
[4*3+i
];
235 const int z3
= 17* temp
[4*1+i
] + 7*temp
[4*3+i
];
237 block
[i
*8+0]= ((z0
+ z3
)*3)>>11;
238 block
[i
*8+1]= ((z1
+ z2
)*3)>>11;
239 block
[i
*8+2]= ((z1
- z2
)*3)>>11;
240 block
[i
*8+3]= ((z0
- z3
)*3)>>11;
245 /** @} */ // transform
249 * @defgroup block RV30/40 4x4 block decoding functions
254 * Decode coded block pattern.
256 static int rv34_decode_cbp(GetBitContext
*gb
, RV34VLC
*vlc
, int table
)
258 int pattern
, code
, cbp
=0;
260 static const int cbp_masks
[3] = {0x100000, 0x010000, 0x110000};
261 static const int shifts
[4] = { 0, 2, 8, 10 };
262 const int *curshift
= shifts
;
265 code
= get_vlc2(gb
, vlc
->cbppattern
[table
].table
, 9, 2);
266 pattern
= code
& 0xF;
269 ones
= rv34_count_ones
[pattern
];
271 for(mask
= 8; mask
; mask
>>= 1, curshift
++){
273 cbp
|= get_vlc2(gb
, vlc
->cbp
[table
][ones
].table
, vlc
->cbp
[table
][ones
].bits
, 1) << curshift
[0];
276 for(i
= 0; i
< 4; i
++){
277 t
= modulo_three_table
[code
][i
];
279 cbp
|= cbp_masks
[get_bits1(gb
)] << i
;
281 cbp
|= cbp_masks
[2] << i
;
287 * Get one coefficient value from the bistream and store it.
289 static inline void decode_coeff(DCTELEM
*dst
, int coef
, int esc
, GetBitContext
*gb
, VLC
* vlc
)
293 coef
= get_vlc2(gb
, vlc
->table
, 9, 2);
296 coef
= 22 + ((1 << coef
) | get_bits(gb
, coef
));
307 * Decode 2x2 subblock of coefficients.
309 static inline void decode_subblock(DCTELEM
*dst
, int code
, const int is_block2
, GetBitContext
*gb
, VLC
*vlc
)
313 coeffs
[0] = modulo_three_table
[code
][0];
314 coeffs
[1] = modulo_three_table
[code
][1];
315 coeffs
[2] = modulo_three_table
[code
][2];
316 coeffs
[3] = modulo_three_table
[code
][3];
317 decode_coeff(dst
, coeffs
[0], 3, gb
, vlc
);
319 decode_coeff(dst
+8, coeffs
[1], 2, gb
, vlc
);
320 decode_coeff(dst
+1, coeffs
[2], 2, gb
, vlc
);
322 decode_coeff(dst
+1, coeffs
[1], 2, gb
, vlc
);
323 decode_coeff(dst
+8, coeffs
[2], 2, gb
, vlc
);
325 decode_coeff(dst
+9, coeffs
[3], 2, gb
, vlc
);
329 * Decode coefficients for 4x4 block.
331 * This is done by filling 2x2 subblocks with decoded coefficients
332 * in this order (the same for subblocks and subblock coefficients):
339 static inline void rv34_decode_block(DCTELEM
*dst
, GetBitContext
*gb
, RV34VLC
*rvlc
, int fc
, int sc
)
343 code
= get_vlc2(gb
, rvlc
->first_pattern
[fc
].table
, 9, 2);
345 pattern
= code
& 0x7;
348 decode_subblock(dst
, code
, 0, gb
, &rvlc
->coefficient
);
351 code
= get_vlc2(gb
, rvlc
->second_pattern
[sc
].table
, 9, 2);
352 decode_subblock(dst
+ 2, code
, 0, gb
, &rvlc
->coefficient
);
354 if(pattern
& 2){ // Looks like coefficients 1 and 2 are swapped for this block
355 code
= get_vlc2(gb
, rvlc
->second_pattern
[sc
].table
, 9, 2);
356 decode_subblock(dst
+ 8*2, code
, 1, gb
, &rvlc
->coefficient
);
359 code
= get_vlc2(gb
, rvlc
->third_pattern
[sc
].table
, 9, 2);
360 decode_subblock(dst
+ 8*2+2, code
, 0, gb
, &rvlc
->coefficient
);
366 * Dequantize ordinary 4x4 block.
369 static inline void rv34_dequant4x4(DCTELEM
*block
, int Qdc
, int Q
)
373 block
[0] = (block
[0] * Qdc
+ 8) >> 4;
374 for(i
= 0; i
< 4; i
++)
375 for(j
= !i
; j
< 4; j
++)
376 block
[j
+ i
*8] = (block
[j
+ i
*8] * Q
+ 8) >> 4;
380 * Dequantize 4x4 block of DC values for 16x16 macroblock.
383 static inline void rv34_dequant4x4_16x16(DCTELEM
*block
, int Qdc
, int Q
)
387 for(i
= 0; i
< 3; i
++)
388 block
[rv34_dezigzag
[i
]] = (block
[rv34_dezigzag
[i
]] * Qdc
+ 8) >> 4;
390 block
[rv34_dezigzag
[i
]] = (block
[rv34_dezigzag
[i
]] * Q
+ 8) >> 4;
392 /** @} */ //block functions
396 * @defgroup bitstream RV30/40 bitstream parsing
401 * Decode starting slice position.
402 * @todo Maybe replace with ff_h263_decode_mba() ?
404 int ff_rv34_get_start_offset(GetBitContext
*gb
, int mb_size
)
407 for(i
= 0; i
< 5; i
++)
408 if(rv34_mb_max_sizes
[i
] >= mb_size
- 1)
410 return rv34_mb_bits_sizes
[i
];
414 * Select VLC set for decoding from current quantizer, modifier and frame type.
416 static inline RV34VLC
* choose_vlc_set(int quant
, int mod
, int type
)
418 if(mod
== 2 && quant
< 19) quant
+= 10;
419 else if(mod
&& quant
< 26) quant
+= 5;
420 return type
? &inter_vlcs
[rv34_quant_to_vlc_set
[1][av_clip(quant
, 0, 30)]]
421 : &intra_vlcs
[rv34_quant_to_vlc_set
[0][av_clip(quant
, 0, 30)]];
425 * Decode quantizer difference and return modified quantizer.
427 static inline int rv34_decode_dquant(GetBitContext
*gb
, int quant
)
430 return rv34_dquant_tab
[get_bits1(gb
)][quant
];
432 return get_bits(gb
, 5);
435 /** @} */ //bitstream functions
438 * @defgroup mv motion vector related code (prediction, reconstruction, motion compensation)
442 /** macroblock partition width in 8x8 blocks */
443 static const uint8_t part_sizes_w
[RV34_MB_TYPES
] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 };
445 /** macroblock partition height in 8x8 blocks */
446 static const uint8_t part_sizes_h
[RV34_MB_TYPES
] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 };
448 /** availability index for subblocks */
449 static const uint8_t avail_indexes
[4] = { 6, 7, 10, 11 };
452 * motion vector prediction
454 * Motion prediction performed for the block by using median prediction of
455 * motion vectors from the left, top and right top blocks but in corner cases
456 * some other vectors may be used instead.
458 static void rv34_pred_mv(RV34DecContext
*r
, int block_type
, int subblock_no
, int dmv_no
)
460 MpegEncContext
*s
= &r
->s
;
461 int mv_pos
= s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
;
462 int A
[2] = {0}, B
[2], C
[2];
465 int avail_index
= avail_indexes
[subblock_no
];
466 int c_off
= part_sizes_w
[block_type
];
468 mv_pos
+= (subblock_no
& 1) + (subblock_no
>> 1)*s
->b8_stride
;
472 if(r
->avail_cache
[avail_index
- 1]){
473 A
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-1][0];
474 A
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-1][1];
476 if(r
->avail_cache
[avail_index
- 4]){
477 B
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
][0];
478 B
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
][1];
483 if(!r
->avail_cache
[avail_index
- 4 + c_off
]){
484 if(r
->avail_cache
[avail_index
- 4] && (r
->avail_cache
[avail_index
- 1] || r
->rv30
)){
485 C
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
-1][0];
486 C
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
-1][1];
492 C
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
+c_off
][0];
493 C
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
+c_off
][1];
495 mx
= mid_pred(A
[0], B
[0], C
[0]);
496 my
= mid_pred(A
[1], B
[1], C
[1]);
497 mx
+= r
->dmv
[dmv_no
][0];
498 my
+= r
->dmv
[dmv_no
][1];
499 for(j
= 0; j
< part_sizes_h
[block_type
]; j
++){
500 for(i
= 0; i
< part_sizes_w
[block_type
]; i
++){
501 s
->current_picture_ptr
->motion_val
[0][mv_pos
+ i
+ j
*s
->b8_stride
][0] = mx
;
502 s
->current_picture_ptr
->motion_val
[0][mv_pos
+ i
+ j
*s
->b8_stride
][1] = my
;
507 #define GET_PTS_DIFF(a, b) ((a - b + 8192) & 0x1FFF)
510 * Calculate motion vector component that should be added for direct blocks.
512 static int calc_add_mv(RV34DecContext
*r
, int dir
, int val
)
514 int refdist
= GET_PTS_DIFF(r
->next_pts
, r
->last_pts
);
515 int dist
= dir
? -GET_PTS_DIFF(r
->next_pts
, r
->cur_pts
) : GET_PTS_DIFF(r
->cur_pts
, r
->last_pts
);
518 if(!refdist
) return 0;
519 mul
= (dist
<< 14) / refdist
;
520 return (val
* mul
+ 0x2000) >> 14;
524 * Predict motion vector for B-frame macroblock.
526 static inline void rv34_pred_b_vector(int A
[2], int B
[2], int C
[2],
527 int A_avail
, int B_avail
, int C_avail
,
530 if(A_avail
+ B_avail
+ C_avail
!= 3){
531 *mx
= A
[0] + B
[0] + C
[0];
532 *my
= A
[1] + B
[1] + C
[1];
533 if(A_avail
+ B_avail
+ C_avail
== 2){
538 *mx
= mid_pred(A
[0], B
[0], C
[0]);
539 *my
= mid_pred(A
[1], B
[1], C
[1]);
544 * motion vector prediction for B-frames
546 static void rv34_pred_mv_b(RV34DecContext
*r
, int block_type
, int dir
)
548 MpegEncContext
*s
= &r
->s
;
549 int mb_pos
= s
->mb_x
+ s
->mb_y
* s
->mb_stride
;
550 int mv_pos
= s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
;
551 int A
[2], B
[2], C
[2];
552 int has_A
= 0, has_B
= 0, has_C
= 0;
555 Picture
*cur_pic
= s
->current_picture_ptr
;
556 const int mask
= dir
? MB_TYPE_L1
: MB_TYPE_L0
;
557 int type
= cur_pic
->mb_type
[mb_pos
];
559 memset(A
, 0, sizeof(A
));
560 memset(B
, 0, sizeof(B
));
561 memset(C
, 0, sizeof(C
));
562 if((r
->avail_cache
[6-1] & type
) & mask
){
563 A
[0] = cur_pic
->motion_val
[dir
][mv_pos
- 1][0];
564 A
[1] = cur_pic
->motion_val
[dir
][mv_pos
- 1][1];
567 if((r
->avail_cache
[6-4] & type
) & mask
){
568 B
[0] = cur_pic
->motion_val
[dir
][mv_pos
- s
->b8_stride
][0];
569 B
[1] = cur_pic
->motion_val
[dir
][mv_pos
- s
->b8_stride
][1];
572 if(r
->avail_cache
[6-4] && (r
->avail_cache
[6-2] & type
) & mask
){
573 C
[0] = cur_pic
->motion_val
[dir
][mv_pos
- s
->b8_stride
+ 2][0];
574 C
[1] = cur_pic
->motion_val
[dir
][mv_pos
- s
->b8_stride
+ 2][1];
576 }else if((s
->mb_x
+1) == s
->mb_width
&& (r
->avail_cache
[6-5] & type
) & mask
){
577 C
[0] = cur_pic
->motion_val
[dir
][mv_pos
- s
->b8_stride
- 1][0];
578 C
[1] = cur_pic
->motion_val
[dir
][mv_pos
- s
->b8_stride
- 1][1];
582 rv34_pred_b_vector(A
, B
, C
, has_A
, has_B
, has_C
, &mx
, &my
);
584 mx
+= r
->dmv
[dir
][0];
585 my
+= r
->dmv
[dir
][1];
587 for(j
= 0; j
< 2; j
++){
588 for(i
= 0; i
< 2; i
++){
589 cur_pic
->motion_val
[dir
][mv_pos
+ i
+ j
*s
->b8_stride
][0] = mx
;
590 cur_pic
->motion_val
[dir
][mv_pos
+ i
+ j
*s
->b8_stride
][1] = my
;
593 if(block_type
== RV34_MB_B_BACKWARD
|| block_type
== RV34_MB_B_FORWARD
){
594 ZERO8x2(cur_pic
->motion_val
[!dir
][mv_pos
], s
->b8_stride
);
599 * motion vector prediction - RV3 version
601 static void rv34_pred_mv_rv3(RV34DecContext
*r
, int block_type
, int dir
)
603 MpegEncContext
*s
= &r
->s
;
604 int mv_pos
= s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
;
605 int A
[2] = {0}, B
[2], C
[2];
608 int avail_index
= avail_indexes
[0];
610 if(r
->avail_cache
[avail_index
- 1]){
611 A
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-1][0];
612 A
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-1][1];
614 if(r
->avail_cache
[avail_index
- 4]){
615 B
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
][0];
616 B
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
][1];
621 if(!r
->avail_cache
[avail_index
- 4 + 2]){
622 if(r
->avail_cache
[avail_index
- 4] && (r
->avail_cache
[avail_index
- 1])){
623 C
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
-1][0];
624 C
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
-1][1];
630 C
[0] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
+2][0];
631 C
[1] = s
->current_picture_ptr
->motion_val
[0][mv_pos
-s
->b8_stride
+2][1];
633 mx
= mid_pred(A
[0], B
[0], C
[0]);
634 my
= mid_pred(A
[1], B
[1], C
[1]);
637 for(j
= 0; j
< 2; j
++){
638 for(i
= 0; i
< 2; i
++){
639 for(k
= 0; k
< 2; k
++){
640 s
->current_picture_ptr
->motion_val
[k
][mv_pos
+ i
+ j
*s
->b8_stride
][0] = mx
;
641 s
->current_picture_ptr
->motion_val
[k
][mv_pos
+ i
+ j
*s
->b8_stride
][1] = my
;
647 static const int chroma_coeffs
[3] = { 0, 3, 5 };
650 * generic motion compensation function
652 * @param r decoder context
653 * @param block_type type of the current block
654 * @param xoff horizontal offset from the start of the current block
655 * @param yoff vertical offset from the start of the current block
656 * @param mv_off offset to the motion vector information
657 * @param width width of the current partition in 8x8 blocks
658 * @param height height of the current partition in 8x8 blocks
659 * @param dir motion compensation direction (i.e. from the last or the next reference frame)
660 * @param thirdpel motion vectors are specified in 1/3 of pixel
661 * @param qpel_mc a set of functions used to perform luma motion compensation
662 * @param chroma_mc a set of functions used to perform chroma motion compensation
664 static inline void rv34_mc(RV34DecContext
*r
, const int block_type
,
665 const int xoff
, const int yoff
, int mv_off
,
666 const int width
, const int height
, int dir
,
668 qpel_mc_func (*qpel_mc
)[16],
669 h264_chroma_mc_func (*chroma_mc
))
671 MpegEncContext
*s
= &r
->s
;
672 uint8_t *Y
, *U
, *V
, *srcY
, *srcU
, *srcV
;
673 int dxy
, mx
, my
, umx
, umy
, lx
, ly
, uvmx
, uvmy
, src_x
, src_y
, uvsrc_x
, uvsrc_y
;
674 int mv_pos
= s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
+ mv_off
;
678 int chroma_mx
, chroma_my
;
679 mx
= (s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][0] + (3 << 24)) / 3 - (1 << 24);
680 my
= (s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][1] + (3 << 24)) / 3 - (1 << 24);
681 lx
= (s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][0] + (3 << 24)) % 3;
682 ly
= (s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][1] + (3 << 24)) % 3;
683 chroma_mx
= (s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][0] + 1) >> 1;
684 chroma_my
= (s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][1] + 1) >> 1;
685 umx
= (chroma_mx
+ (3 << 24)) / 3 - (1 << 24);
686 umy
= (chroma_my
+ (3 << 24)) / 3 - (1 << 24);
687 uvmx
= chroma_coeffs
[(chroma_mx
+ (3 << 24)) % 3];
688 uvmy
= chroma_coeffs
[(chroma_my
+ (3 << 24)) % 3];
691 mx
= s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][0] >> 2;
692 my
= s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][1] >> 2;
693 lx
= s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][0] & 3;
694 ly
= s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][1] & 3;
695 cx
= s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][0] / 2;
696 cy
= s
->current_picture_ptr
->motion_val
[dir
][mv_pos
][1] / 2;
699 uvmx
= (cx
& 3) << 1;
700 uvmy
= (cy
& 3) << 1;
701 //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3
702 if(uvmx
== 6 && uvmy
== 6)
706 srcY
= dir
? s
->next_picture_ptr
->data
[0] : s
->last_picture_ptr
->data
[0];
707 srcU
= dir
? s
->next_picture_ptr
->data
[1] : s
->last_picture_ptr
->data
[1];
708 srcV
= dir
? s
->next_picture_ptr
->data
[2] : s
->last_picture_ptr
->data
[2];
709 src_x
= s
->mb_x
* 16 + xoff
+ mx
;
710 src_y
= s
->mb_y
* 16 + yoff
+ my
;
711 uvsrc_x
= s
->mb_x
* 8 + (xoff
>> 1) + umx
;
712 uvsrc_y
= s
->mb_y
* 8 + (yoff
>> 1) + umy
;
713 srcY
+= src_y
* s
->linesize
+ src_x
;
714 srcU
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
715 srcV
+= uvsrc_y
* s
->uvlinesize
+ uvsrc_x
;
716 if( (unsigned)(src_x
- !!lx
*2) > s
->h_edge_pos
- !!lx
*2 - (width
<<3) - 4
717 || (unsigned)(src_y
- !!ly
*2) > s
->v_edge_pos
- !!ly
*2 - (height
<<3) - 4){
718 uint8_t *uvbuf
= s
->edge_emu_buffer
+ 22 * s
->linesize
;
720 srcY
-= 2 + 2*s
->linesize
;
721 ff_emulated_edge_mc(s
->edge_emu_buffer
, srcY
, s
->linesize
, (width
<<3)+6, (height
<<3)+6,
722 src_x
- 2, src_y
- 2, s
->h_edge_pos
, s
->v_edge_pos
);
723 srcY
= s
->edge_emu_buffer
+ 2 + 2*s
->linesize
;
724 ff_emulated_edge_mc(uvbuf
, srcU
, s
->uvlinesize
, (width
<<2)+1, (height
<<2)+1,
725 uvsrc_x
, uvsrc_y
, s
->h_edge_pos
>> 1, s
->v_edge_pos
>> 1);
726 ff_emulated_edge_mc(uvbuf
+ 16, srcV
, s
->uvlinesize
, (width
<<2)+1, (height
<<2)+1,
727 uvsrc_x
, uvsrc_y
, s
->h_edge_pos
>> 1, s
->v_edge_pos
>> 1);
731 Y
= s
->dest
[0] + xoff
+ yoff
*s
->linesize
;
732 U
= s
->dest
[1] + (xoff
>>1) + (yoff
>>1)*s
->uvlinesize
;
733 V
= s
->dest
[2] + (xoff
>>1) + (yoff
>>1)*s
->uvlinesize
;
735 if(block_type
== RV34_MB_P_16x8
){
736 qpel_mc
[1][dxy
](Y
, srcY
, s
->linesize
);
739 }else if(block_type
== RV34_MB_P_8x16
){
740 qpel_mc
[1][dxy
](Y
, srcY
, s
->linesize
);
741 Y
+= 8 * s
->linesize
;
742 srcY
+= 8 * s
->linesize
;
744 is16x16
= (block_type
!= RV34_MB_P_8x8
) && (block_type
!= RV34_MB_P_16x8
) && (block_type
!= RV34_MB_P_8x16
);
745 qpel_mc
[!is16x16
][dxy
](Y
, srcY
, s
->linesize
);
746 chroma_mc
[2-width
] (U
, srcU
, s
->uvlinesize
, height
*4, uvmx
, uvmy
);
747 chroma_mc
[2-width
] (V
, srcV
, s
->uvlinesize
, height
*4, uvmx
, uvmy
);
750 static void rv34_mc_1mv(RV34DecContext
*r
, const int block_type
,
751 const int xoff
, const int yoff
, int mv_off
,
752 const int width
, const int height
, int dir
)
754 rv34_mc(r
, block_type
, xoff
, yoff
, mv_off
, width
, height
, dir
, r
->rv30
,
755 r
->rv30
? r
->s
.dsp
.put_rv30_tpel_pixels_tab
756 : r
->s
.dsp
.put_rv40_qpel_pixels_tab
,
757 r
->rv30
? r
->s
.dsp
.put_h264_chroma_pixels_tab
758 : r
->s
.dsp
.put_rv40_chroma_pixels_tab
);
761 static void rv34_mc_2mv(RV34DecContext
*r
, const int block_type
)
763 rv34_mc(r
, block_type
, 0, 0, 0, 2, 2, 0, r
->rv30
,
764 r
->rv30
? r
->s
.dsp
.put_rv30_tpel_pixels_tab
765 : r
->s
.dsp
.put_rv40_qpel_pixels_tab
,
766 r
->rv30
? r
->s
.dsp
.put_h264_chroma_pixels_tab
767 : r
->s
.dsp
.put_rv40_chroma_pixels_tab
);
768 rv34_mc(r
, block_type
, 0, 0, 0, 2, 2, 1, r
->rv30
,
769 r
->rv30
? r
->s
.dsp
.avg_rv30_tpel_pixels_tab
770 : r
->s
.dsp
.avg_rv40_qpel_pixels_tab
,
771 r
->rv30
? r
->s
.dsp
.avg_h264_chroma_pixels_tab
772 : r
->s
.dsp
.avg_rv40_chroma_pixels_tab
);
775 static void rv34_mc_2mv_skip(RV34DecContext
*r
)
778 for(j
= 0; j
< 2; j
++)
779 for(i
= 0; i
< 2; i
++){
780 rv34_mc(r
, RV34_MB_P_8x8
, i
*8, j
*8, i
+j
*r
->s
.b8_stride
, 1, 1, 0, r
->rv30
,
781 r
->rv30
? r
->s
.dsp
.put_rv30_tpel_pixels_tab
782 : r
->s
.dsp
.put_rv40_qpel_pixels_tab
,
783 r
->rv30
? r
->s
.dsp
.put_h264_chroma_pixels_tab
784 : r
->s
.dsp
.put_rv40_chroma_pixels_tab
);
785 rv34_mc(r
, RV34_MB_P_8x8
, i
*8, j
*8, i
+j
*r
->s
.b8_stride
, 1, 1, 1, r
->rv30
,
786 r
->rv30
? r
->s
.dsp
.avg_rv30_tpel_pixels_tab
787 : r
->s
.dsp
.avg_rv40_qpel_pixels_tab
,
788 r
->rv30
? r
->s
.dsp
.avg_h264_chroma_pixels_tab
789 : r
->s
.dsp
.avg_rv40_chroma_pixels_tab
);
793 /** number of motion vectors in each macroblock type */
794 static const int num_mvs
[RV34_MB_TYPES
] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };
797 * Decode motion vector differences
798 * and perform motion vector reconstruction and motion compensation.
800 static int rv34_decode_mv(RV34DecContext
*r
, int block_type
)
802 MpegEncContext
*s
= &r
->s
;
803 GetBitContext
*gb
= &s
->gb
;
805 int mv_pos
= s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
;
808 memset(r
->dmv
, 0, sizeof(r
->dmv
));
809 for(i
= 0; i
< num_mvs
[block_type
]; i
++){
810 r
->dmv
[i
][0] = svq3_get_se_golomb(gb
);
811 r
->dmv
[i
][1] = svq3_get_se_golomb(gb
);
814 case RV34_MB_TYPE_INTRA
:
815 case RV34_MB_TYPE_INTRA16x16
:
816 ZERO8x2(s
->current_picture_ptr
->motion_val
[0][s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
], s
->b8_stride
);
819 if(s
->pict_type
== FF_P_TYPE
){
820 ZERO8x2(s
->current_picture_ptr
->motion_val
[0][s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
], s
->b8_stride
);
821 rv34_mc_1mv (r
, block_type
, 0, 0, 0, 2, 2, 0);
824 case RV34_MB_B_DIRECT
:
825 //surprisingly, it uses motion scheme from next reference frame
826 next_bt
= s
->next_picture_ptr
->mb_type
[s
->mb_x
+ s
->mb_y
* s
->mb_stride
];
827 if(IS_INTRA(next_bt
) || IS_SKIP(next_bt
)){
828 ZERO8x2(s
->current_picture_ptr
->motion_val
[0][s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
], s
->b8_stride
);
829 ZERO8x2(s
->current_picture_ptr
->motion_val
[1][s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
], s
->b8_stride
);
831 for(j
= 0; j
< 2; j
++)
832 for(i
= 0; i
< 2; i
++)
833 for(k
= 0; k
< 2; k
++)
834 for(l
= 0; l
< 2; l
++)
835 s
->current_picture_ptr
->motion_val
[l
][mv_pos
+ i
+ j
*s
->b8_stride
][k
] = calc_add_mv(r
, l
, s
->next_picture_ptr
->motion_val
[0][mv_pos
+ i
+ j
*s
->b8_stride
][k
]);
836 if(!(IS_16X8(next_bt
) || IS_8X16(next_bt
) || IS_8X8(next_bt
))) //we can use whole macroblock MC
837 rv34_mc_2mv(r
, block_type
);
840 ZERO8x2(s
->current_picture_ptr
->motion_val
[0][s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
], s
->b8_stride
);
842 case RV34_MB_P_16x16
:
843 case RV34_MB_P_MIX16x16
:
844 rv34_pred_mv(r
, block_type
, 0, 0);
845 rv34_mc_1mv (r
, block_type
, 0, 0, 0, 2, 2, 0);
847 case RV34_MB_B_FORWARD
:
848 case RV34_MB_B_BACKWARD
:
849 r
->dmv
[1][0] = r
->dmv
[0][0];
850 r
->dmv
[1][1] = r
->dmv
[0][1];
852 rv34_pred_mv_rv3(r
, block_type
, block_type
== RV34_MB_B_BACKWARD
);
854 rv34_pred_mv_b (r
, block_type
, block_type
== RV34_MB_B_BACKWARD
);
855 rv34_mc_1mv (r
, block_type
, 0, 0, 0, 2, 2, block_type
== RV34_MB_B_BACKWARD
);
859 rv34_pred_mv(r
, block_type
, 0, 0);
860 rv34_pred_mv(r
, block_type
, 1 + (block_type
== RV34_MB_P_16x8
), 1);
861 if(block_type
== RV34_MB_P_16x8
){
862 rv34_mc_1mv(r
, block_type
, 0, 0, 0, 2, 1, 0);
863 rv34_mc_1mv(r
, block_type
, 0, 8, s
->b8_stride
, 2, 1, 0);
865 if(block_type
== RV34_MB_P_8x16
){
866 rv34_mc_1mv(r
, block_type
, 0, 0, 0, 1, 2, 0);
867 rv34_mc_1mv(r
, block_type
, 8, 0, 1, 1, 2, 0);
870 case RV34_MB_B_BIDIR
:
871 rv34_pred_mv_b (r
, block_type
, 0);
872 rv34_pred_mv_b (r
, block_type
, 1);
873 rv34_mc_2mv (r
, block_type
);
877 rv34_pred_mv(r
, block_type
, i
, i
);
878 rv34_mc_1mv (r
, block_type
, (i
&1)<<3, (i
&2)<<2, (i
&1)+(i
>>1)*s
->b8_stride
, 1, 1, 0);
885 /** @} */ // mv group
888 * @defgroup recons Macroblock reconstruction functions
891 /** mapping of RV30/40 intra prediction types to standard H.264 types */
892 static const int ittrans
[9] = {
893 DC_PRED
, VERT_PRED
, HOR_PRED
, DIAG_DOWN_RIGHT_PRED
, DIAG_DOWN_LEFT_PRED
,
894 VERT_RIGHT_PRED
, VERT_LEFT_PRED
, HOR_UP_PRED
, HOR_DOWN_PRED
,
897 /** mapping of RV30/40 intra 16x16 prediction types to standard H.264 types */
898 static const int ittrans16
[4] = {
899 DC_PRED8x8
, VERT_PRED8x8
, HOR_PRED8x8
, PLANE_PRED8x8
,
903 * Perform 4x4 intra prediction.
905 static void rv34_pred_4x4_block(RV34DecContext
*r
, uint8_t *dst
, int stride
, int itype
, int up
, int left
, int down
, int right
)
907 uint8_t *prev
= dst
- stride
+ 4;
913 if(itype
== VERT_PRED
) itype
= HOR_PRED
;
914 if(itype
== DC_PRED
) itype
= LEFT_DC_PRED
;
916 if(itype
== HOR_PRED
) itype
= VERT_PRED
;
917 if(itype
== DC_PRED
) itype
= TOP_DC_PRED
;
918 if(itype
== DIAG_DOWN_LEFT_PRED
) itype
= DIAG_DOWN_LEFT_PRED_RV40_NODOWN
;
921 if(itype
== DIAG_DOWN_LEFT_PRED
) itype
= DIAG_DOWN_LEFT_PRED_RV40_NODOWN
;
922 if(itype
== HOR_UP_PRED
) itype
= HOR_UP_PRED_RV40_NODOWN
;
923 if(itype
== VERT_LEFT_PRED
) itype
= VERT_LEFT_PRED_RV40_NODOWN
;
926 topleft
= dst
[-stride
+ 3] * 0x01010101;
927 prev
= (uint8_t*)&topleft
;
929 r
->h
.pred4x4
[itype
](dst
, prev
, stride
);
932 /** add_pixels_clamped for 4x4 block */
933 static void rv34_add_4x4_block(uint8_t *dst
, int stride
, DCTELEM block
[64], int off
)
936 for(y
= 0; y
< 4; y
++)
937 for(x
= 0; x
< 4; x
++)
938 dst
[x
+ y
*stride
] = av_clip_uint8(dst
[x
+ y
*stride
] + block
[off
+ x
+y
*8]);
941 static inline int adjust_pred16(int itype
, int up
, int left
)
944 itype
= DC_128_PRED8x8
;
946 if(itype
== PLANE_PRED8x8
)itype
= HOR_PRED8x8
;
947 if(itype
== VERT_PRED8x8
) itype
= HOR_PRED8x8
;
948 if(itype
== DC_PRED8x8
) itype
= LEFT_DC_PRED8x8
;
950 if(itype
== PLANE_PRED8x8
)itype
= VERT_PRED8x8
;
951 if(itype
== HOR_PRED8x8
) itype
= VERT_PRED8x8
;
952 if(itype
== DC_PRED8x8
) itype
= TOP_DC_PRED8x8
;
957 static void rv34_output_macroblock(RV34DecContext
*r
, int8_t *intra_types
, int cbp
, int is16
)
959 MpegEncContext
*s
= &r
->s
;
960 DSPContext
*dsp
= &s
->dsp
;
964 int avail
[6*8] = {0};
967 // Set neighbour information.
968 if(r
->avail_cache
[1])
970 if(r
->avail_cache
[2])
971 avail
[1] = avail
[2] = 1;
972 if(r
->avail_cache
[3])
973 avail
[3] = avail
[4] = 1;
974 if(r
->avail_cache
[4])
976 if(r
->avail_cache
[5])
977 avail
[8] = avail
[16] = 1;
978 if(r
->avail_cache
[9])
979 avail
[24] = avail
[32] = 1;
985 for(j
= 0; j
< 4; j
++){
987 for(i
= 0; i
< 4; i
++, cbp
>>= 1, Y
+= 4, idx
++){
988 rv34_pred_4x4_block(r
, Y
, s
->linesize
, ittrans
[intra_types
[i
]], avail
[idx
-8], avail
[idx
-1], avail
[idx
+7], avail
[idx
-7]);
991 rv34_add_4x4_block(Y
, s
->linesize
, s
->block
[(i
>>1)+(j
&2)], (i
&1)*4+(j
&1)*32);
993 Y
+= s
->linesize
* 4 - 4*4;
994 intra_types
+= r
->intra_types_stride
;
996 intra_types
-= r
->intra_types_stride
* 4;
997 fill_rectangle(r
->avail_cache
+ 6, 2, 2, 4, 0, 4);
998 for(j
= 0; j
< 2; j
++){
1000 for(i
= 0; i
< 2; i
++, cbp
>>= 1, idx
++){
1001 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]);
1002 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]);
1003 r
->avail_cache
[idx
] = 1;
1005 rv34_add_4x4_block(U
+ i
*4 + j
*4*s
->uvlinesize
, s
->uvlinesize
, s
->block
[4], i
*4+j
*32);
1007 rv34_add_4x4_block(V
+ i
*4 + j
*4*s
->uvlinesize
, s
->uvlinesize
, s
->block
[5], i
*4+j
*32);
1011 itype
= ittrans16
[intra_types
[0]];
1012 itype
= adjust_pred16(itype
, r
->avail_cache
[6-4], r
->avail_cache
[6-1]);
1013 r
->h
.pred16x16
[itype
](Y
, s
->linesize
);
1014 dsp
->add_pixels_clamped(s
->block
[0], Y
, s
->linesize
);
1015 dsp
->add_pixels_clamped(s
->block
[1], Y
+ 8, s
->linesize
);
1016 Y
+= s
->linesize
* 8;
1017 dsp
->add_pixels_clamped(s
->block
[2], Y
, s
->linesize
);
1018 dsp
->add_pixels_clamped(s
->block
[3], Y
+ 8, s
->linesize
);
1020 itype
= ittrans16
[intra_types
[0]];
1021 if(itype
== PLANE_PRED8x8
) itype
= DC_PRED8x8
;
1022 itype
= adjust_pred16(itype
, r
->avail_cache
[6-4], r
->avail_cache
[6-1]);
1023 r
->h
.pred8x8
[itype
](U
, s
->uvlinesize
);
1024 dsp
->add_pixels_clamped(s
->block
[4], U
, s
->uvlinesize
);
1025 r
->h
.pred8x8
[itype
](V
, s
->uvlinesize
);
1026 dsp
->add_pixels_clamped(s
->block
[5], V
, s
->uvlinesize
);
1030 /** @} */ // recons group
1033 * @addtogroup bitstream
1034 * Decode macroblock header and return CBP in case of success, -1 otherwise.
1036 static int rv34_decode_mb_header(RV34DecContext
*r
, int8_t *intra_types
)
1038 MpegEncContext
*s
= &r
->s
;
1039 GetBitContext
*gb
= &s
->gb
;
1040 int mb_pos
= s
->mb_x
+ s
->mb_y
* s
->mb_stride
;
1044 r
->is16
= get_bits1(gb
);
1045 if(!r
->is16
&& !r
->rv30
){
1047 av_log(s
->avctx
, AV_LOG_ERROR
, "Need DQUANT\n");
1049 s
->current_picture_ptr
->mb_type
[mb_pos
] = r
->is16
? MB_TYPE_INTRA16x16
: MB_TYPE_INTRA
;
1050 r
->block_type
= r
->is16
? RV34_MB_TYPE_INTRA16x16
: RV34_MB_TYPE_INTRA
;
1052 r
->block_type
= r
->decode_mb_info(r
);
1053 if(r
->block_type
== -1)
1055 s
->current_picture_ptr
->mb_type
[mb_pos
] = rv34_mb_type_to_lavc
[r
->block_type
];
1056 r
->mb_type
[mb_pos
] = r
->block_type
;
1057 if(r
->block_type
== RV34_MB_SKIP
){
1058 if(s
->pict_type
== FF_P_TYPE
)
1059 r
->mb_type
[mb_pos
] = RV34_MB_P_16x16
;
1060 if(s
->pict_type
== FF_B_TYPE
)
1061 r
->mb_type
[mb_pos
] = RV34_MB_B_DIRECT
;
1063 r
->is16
= !!IS_INTRA16x16(s
->current_picture_ptr
->mb_type
[mb_pos
]);
1064 rv34_decode_mv(r
, r
->block_type
);
1065 if(r
->block_type
== RV34_MB_SKIP
){
1066 fill_rectangle(intra_types
, 4, 4, r
->intra_types_stride
, 0, sizeof(intra_types
[0]));
1072 if(IS_INTRA(s
->current_picture_ptr
->mb_type
[mb_pos
])){
1074 t
= get_bits(gb
, 2);
1075 fill_rectangle(intra_types
, 4, 4, r
->intra_types_stride
, t
, sizeof(intra_types
[0]));
1078 if(r
->decode_intra_types(r
, gb
, intra_types
) < 0)
1083 r
->cur_vlcs
= choose_vlc_set(r
->si
.quant
, r
->si
.vlc_set
, 0);
1085 for(i
= 0; i
< 16; i
++)
1086 intra_types
[(i
& 3) + (i
>>2) * r
->intra_types_stride
] = 0;
1087 r
->cur_vlcs
= choose_vlc_set(r
->si
.quant
, r
->si
.vlc_set
, 1);
1088 if(r
->mb_type
[mb_pos
] == RV34_MB_P_MIX16x16
){
1092 r
->cur_vlcs
= choose_vlc_set(r
->si
.quant
, r
->si
.vlc_set
, 0);
1096 return rv34_decode_cbp(gb
, r
->cur_vlcs
, r
->is16
);
1100 * @addtogroup recons
1104 * mask for retrieving all bits in coded block pattern
1105 * corresponding to one 8x8 block
1107 #define LUMA_CBP_BLOCK_MASK 0x33
1109 #define U_CBP_MASK 0x0F0000
1110 #define V_CBP_MASK 0xF00000
1113 static void rv34_apply_differences(RV34DecContext
*r
, int cbp
)
1115 static const int shifts
[4] = { 0, 2, 8, 10 };
1116 MpegEncContext
*s
= &r
->s
;
1119 for(i
= 0; i
< 4; i
++)
1120 if((cbp
& (LUMA_CBP_BLOCK_MASK
<< shifts
[i
])) || r
->block_type
== RV34_MB_P_MIX16x16
)
1121 s
->dsp
.add_pixels_clamped(s
->block
[i
], s
->dest
[0] + (i
& 1)*8 + (i
&2)*4*s
->linesize
, s
->linesize
);
1122 if(cbp
& U_CBP_MASK
)
1123 s
->dsp
.add_pixels_clamped(s
->block
[4], s
->dest
[1], s
->uvlinesize
);
1124 if(cbp
& V_CBP_MASK
)
1125 s
->dsp
.add_pixels_clamped(s
->block
[5], s
->dest
[2], s
->uvlinesize
);
1128 static int is_mv_diff_gt_3(int16_t (*motion_val
)[2], int step
)
1131 d
= motion_val
[0][0] - motion_val
[-step
][0];
1134 d
= motion_val
[0][1] - motion_val
[-step
][1];
1140 static int rv34_set_deblock_coef(RV34DecContext
*r
)
1142 MpegEncContext
*s
= &r
->s
;
1143 int hmvmask
= 0, vmvmask
= 0, i
, j
;
1144 int midx
= s
->mb_x
* 2 + s
->mb_y
* 2 * s
->b8_stride
;
1145 int16_t (*motion_val
)[2] = s
->current_picture_ptr
->motion_val
[0][midx
];
1146 for(j
= 0; j
< 16; j
+= 8){
1147 for(i
= 0; i
< 2; i
++){
1148 if(is_mv_diff_gt_3(motion_val
+ i
, 1))
1149 vmvmask
|= 0x11 << (j
+ i
*2);
1150 if((j
|| s
->mb_y
) && is_mv_diff_gt_3(motion_val
+ i
, s
->b8_stride
))
1151 hmvmask
|= 0x03 << (j
+ i
*2);
1153 motion_val
+= s
->b8_stride
;
1155 if(s
->first_slice_line
)
1159 if(r
->rv30
){ //RV30 marks both subblocks on the edge for filtering
1160 vmvmask
|= (vmvmask
& 0x4444) >> 1;
1161 hmvmask
|= (hmvmask
& 0x0F00) >> 4;
1163 r
->deblock_coefs
[s
->mb_x
- 1 + s
->mb_y
*s
->mb_stride
] |= (vmvmask
& 0x1111) << 3;
1164 if(!s
->first_slice_line
)
1165 r
->deblock_coefs
[s
->mb_x
+ (s
->mb_y
- 1)*s
->mb_stride
] |= (hmvmask
& 0xF) << 12;
1167 return hmvmask
| vmvmask
;
1170 static int rv34_decode_macroblock(RV34DecContext
*r
, int8_t *intra_types
)
1172 MpegEncContext
*s
= &r
->s
;
1173 GetBitContext
*gb
= &s
->gb
;
1175 int i
, blknum
, blkoff
;
1176 DCTELEM block16
[64];
1179 int mb_pos
= s
->mb_x
+ s
->mb_y
* s
->mb_stride
;
1181 // Calculate which neighbours are available. Maybe it's worth optimizing too.
1182 memset(r
->avail_cache
, 0, sizeof(r
->avail_cache
));
1183 fill_rectangle(r
->avail_cache
+ 6, 2, 2, 4, 1, 4);
1184 dist
= (s
->mb_x
- s
->resync_mb_x
) + (s
->mb_y
- s
->resync_mb_y
) * s
->mb_width
;
1187 r
->avail_cache
[9] = s
->current_picture_ptr
->mb_type
[mb_pos
- 1];
1188 if(dist
>= s
->mb_width
)
1190 r
->avail_cache
[3] = s
->current_picture_ptr
->mb_type
[mb_pos
- s
->mb_stride
];
1191 if(((s
->mb_x
+1) < s
->mb_width
) && dist
>= s
->mb_width
- 1)
1192 r
->avail_cache
[4] = s
->current_picture_ptr
->mb_type
[mb_pos
- s
->mb_stride
+ 1];
1193 if(s
->mb_x
&& dist
> s
->mb_width
)
1194 r
->avail_cache
[1] = s
->current_picture_ptr
->mb_type
[mb_pos
- s
->mb_stride
- 1];
1196 s
->qscale
= r
->si
.quant
;
1197 cbp
= cbp2
= rv34_decode_mb_header(r
, intra_types
);
1198 r
->cbp_luma
[mb_pos
] = cbp
;
1199 r
->cbp_chroma
[mb_pos
] = cbp
>> 16;
1200 if(s
->pict_type
== FF_I_TYPE
)
1201 r
->deblock_coefs
[mb_pos
] = 0xFFFF;
1203 r
->deblock_coefs
[mb_pos
] = rv34_set_deblock_coef(r
) | r
->cbp_luma
[mb_pos
];
1204 s
->current_picture_ptr
->qscale_table
[mb_pos
] = s
->qscale
;
1209 luma_dc_quant
= r
->block_type
== RV34_MB_P_MIX16x16
? r
->luma_dc_quant_p
[s
->qscale
] : r
->luma_dc_quant_i
[s
->qscale
];
1211 memset(block16
, 0, sizeof(block16
));
1212 rv34_decode_block(block16
, gb
, r
->cur_vlcs
, 3, 0);
1213 rv34_dequant4x4_16x16(block16
, rv34_qscale_tab
[luma_dc_quant
],rv34_qscale_tab
[s
->qscale
]);
1214 rv34_inv_transform_noround(block16
);
1217 for(i
= 0; i
< 16; i
++, cbp
>>= 1){
1218 if(!r
->is16
&& !(cbp
& 1)) continue;
1219 blknum
= ((i
& 2) >> 1) + ((i
& 8) >> 2);
1220 blkoff
= ((i
& 1) << 2) + ((i
& 4) << 3);
1222 rv34_decode_block(s
->block
[blknum
] + blkoff
, gb
, r
->cur_vlcs
, r
->luma_vlc
, 0);
1223 rv34_dequant4x4(s
->block
[blknum
] + blkoff
, rv34_qscale_tab
[s
->qscale
],rv34_qscale_tab
[s
->qscale
]);
1224 if(r
->is16
) //FIXME: optimize
1225 s
->block
[blknum
][blkoff
] = block16
[(i
& 3) | ((i
& 0xC) << 1)];
1226 rv34_inv_transform(s
->block
[blknum
] + blkoff
);
1228 if(r
->block_type
== RV34_MB_P_MIX16x16
)
1229 r
->cur_vlcs
= choose_vlc_set(r
->si
.quant
, r
->si
.vlc_set
, 1);
1230 for(; i
< 24; i
++, cbp
>>= 1){
1231 if(!(cbp
& 1)) continue;
1232 blknum
= ((i
& 4) >> 2) + 4;
1233 blkoff
= ((i
& 1) << 2) + ((i
& 2) << 4);
1234 rv34_decode_block(s
->block
[blknum
] + blkoff
, gb
, r
->cur_vlcs
, r
->chroma_vlc
, 1);
1235 rv34_dequant4x4(s
->block
[blknum
] + blkoff
, rv34_qscale_tab
[rv34_chroma_quant
[1][s
->qscale
]],rv34_qscale_tab
[rv34_chroma_quant
[0][s
->qscale
]]);
1236 rv34_inv_transform(s
->block
[blknum
] + blkoff
);
1238 if(IS_INTRA(s
->current_picture_ptr
->mb_type
[mb_pos
]))
1239 rv34_output_macroblock(r
, intra_types
, cbp2
, r
->is16
);
1241 rv34_apply_differences(r
, cbp2
);
1246 static int check_slice_end(RV34DecContext
*r
, MpegEncContext
*s
)
1249 if(s
->mb_y
>= s
->mb_height
)
1253 if(r
->s
.mb_skip_run
> 1)
1255 bits
= r
->bits
- get_bits_count(&s
->gb
);
1256 if(bits
< 0 || (bits
< 8 && !show_bits(&s
->gb
, bits
)))
1261 static inline int slice_compare(SliceInfo
*si1
, SliceInfo
*si2
)
1263 return si1
->type
!= si2
->type
||
1264 si1
->start
>= si2
->start
||
1265 si1
->width
!= si2
->width
||
1266 si1
->height
!= si2
->height
||
1267 si1
->pts
!= si2
->pts
;
1270 static int rv34_decode_slice(RV34DecContext
*r
, int end
, const uint8_t* buf
, int buf_size
)
1272 MpegEncContext
*s
= &r
->s
;
1273 GetBitContext
*gb
= &s
->gb
;
1277 init_get_bits(&r
->s
.gb
, buf
, buf_size
*8);
1278 res
= r
->parse_slice_header(r
, gb
, &r
->si
);
1280 av_log(s
->avctx
, AV_LOG_ERROR
, "Incorrect or unknown slice header\n");
1284 if ((s
->mb_x
== 0 && s
->mb_y
== 0) || s
->current_picture_ptr
==NULL
) {
1285 if(s
->width
!= r
->si
.width
|| s
->height
!= r
->si
.height
){
1286 av_log(s
->avctx
, AV_LOG_DEBUG
, "Changing dimensions to %dx%d\n", r
->si
.width
,r
->si
.height
);
1288 s
->width
= r
->si
.width
;
1289 s
->height
= r
->si
.height
;
1290 if(MPV_common_init(s
) < 0)
1292 r
->intra_types_stride
= s
->mb_width
*4 + 4;
1293 r
->intra_types_hist
= av_realloc(r
->intra_types_hist
, r
->intra_types_stride
* 4 * 2 * sizeof(*r
->intra_types_hist
));
1294 r
->intra_types
= r
->intra_types_hist
+ r
->intra_types_stride
* 4;
1295 r
->mb_type
= av_realloc(r
->mb_type
, r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->mb_type
));
1296 r
->cbp_luma
= av_realloc(r
->cbp_luma
, r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->cbp_luma
));
1297 r
->cbp_chroma
= av_realloc(r
->cbp_chroma
, r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->cbp_chroma
));
1298 r
->deblock_coefs
= av_realloc(r
->deblock_coefs
, r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->deblock_coefs
));
1300 s
->pict_type
= r
->si
.type
? r
->si
.type
: FF_I_TYPE
;
1301 if(MPV_frame_start(s
, s
->avctx
) < 0)
1303 ff_er_frame_start(s
);
1304 r
->cur_pts
= r
->si
.pts
;
1305 if(s
->pict_type
!= FF_B_TYPE
){
1306 r
->last_pts
= r
->next_pts
;
1307 r
->next_pts
= r
->cur_pts
;
1309 s
->mb_x
= s
->mb_y
= 0;
1313 s
->qscale
= r
->si
.quant
;
1314 r
->bits
= buf_size
*8;
1315 s
->mb_num_left
= r
->si
.end
- r
->si
.start
;
1316 r
->s
.mb_skip_run
= 0;
1318 mb_pos
= s
->mb_x
+ s
->mb_y
* s
->mb_width
;
1319 if(r
->si
.start
!= mb_pos
){
1320 av_log(s
->avctx
, AV_LOG_ERROR
, "Slice indicates MB offset %d, got %d\n", r
->si
.start
, mb_pos
);
1321 s
->mb_x
= r
->si
.start
% s
->mb_width
;
1322 s
->mb_y
= r
->si
.start
/ s
->mb_width
;
1324 memset(r
->intra_types_hist
, -1, r
->intra_types_stride
* 4 * 2 * sizeof(*r
->intra_types_hist
));
1325 s
->first_slice_line
= 1;
1326 s
->resync_mb_x
= s
->mb_x
;
1327 s
->resync_mb_y
= s
->mb_y
;
1329 ff_init_block_index(s
);
1330 while(!check_slice_end(r
, s
)) {
1331 ff_update_block_index(s
);
1332 s
->dsp
.clear_blocks(s
->block
[0]);
1334 if(rv34_decode_macroblock(r
, r
->intra_types
+ s
->mb_x
* 4 + 4) < 0){
1335 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
);
1338 if (++s
->mb_x
== s
->mb_width
) {
1341 ff_init_block_index(s
);
1343 memmove(r
->intra_types_hist
, r
->intra_types
, r
->intra_types_stride
* 4 * sizeof(*r
->intra_types_hist
));
1344 memset(r
->intra_types
, -1, r
->intra_types_stride
* 4 * sizeof(*r
->intra_types_hist
));
1346 if(r
->loop_filter
&& s
->mb_y
>= 2)
1347 r
->loop_filter(r
, s
->mb_y
- 2);
1349 if(s
->mb_x
== s
->resync_mb_x
)
1350 s
->first_slice_line
=0;
1353 ff_er_add_slice(s
, s
->resync_mb_x
, s
->resync_mb_y
, s
->mb_x
-1, s
->mb_y
, AC_END
|DC_END
|MV_END
);
1355 return s
->mb_y
== s
->mb_height
;
1358 /** @} */ // recons group end
1361 * Initialize decoder.
1363 av_cold
int ff_rv34_decode_init(AVCodecContext
*avctx
)
1365 RV34DecContext
*r
= avctx
->priv_data
;
1366 MpegEncContext
*s
= &r
->s
;
1368 MPV_decode_defaults(s
);
1370 s
->out_format
= FMT_H263
;
1371 s
->codec_id
= avctx
->codec_id
;
1373 s
->width
= avctx
->width
;
1374 s
->height
= avctx
->height
;
1377 avctx
->flags
|= CODEC_FLAG_EMU_EDGE
;
1378 r
->s
.flags
|= CODEC_FLAG_EMU_EDGE
;
1379 avctx
->pix_fmt
= PIX_FMT_YUV420P
;
1380 avctx
->has_b_frames
= 1;
1383 if (MPV_common_init(s
) < 0)
1386 ff_h264_pred_init(&r
->h
, CODEC_ID_RV40
);
1388 r
->intra_types_stride
= 4*s
->mb_stride
+ 4;
1389 r
->intra_types_hist
= av_malloc(r
->intra_types_stride
* 4 * 2 * sizeof(*r
->intra_types_hist
));
1390 r
->intra_types
= r
->intra_types_hist
+ r
->intra_types_stride
* 4;
1392 r
->mb_type
= av_mallocz(r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->mb_type
));
1394 r
->cbp_luma
= av_malloc(r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->cbp_luma
));
1395 r
->cbp_chroma
= av_malloc(r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->cbp_chroma
));
1396 r
->deblock_coefs
= av_malloc(r
->s
.mb_stride
* r
->s
.mb_height
* sizeof(*r
->deblock_coefs
));
1398 if(!intra_vlcs
[0].cbppattern
[0].bits
)
1404 static int get_slice_offset(AVCodecContext
*avctx
, const uint8_t *buf
, int n
)
1406 if(avctx
->slice_count
) return avctx
->slice_offset
[n
];
1407 else return AV_RL32(buf
+ n
*8 - 4) == 1 ? AV_RL32(buf
+ n
*8) : AV_RB32(buf
+ n
*8);
1410 int ff_rv34_decode_frame(AVCodecContext
*avctx
,
1411 void *data
, int *data_size
,
1414 const uint8_t *buf
= avpkt
->data
;
1415 int buf_size
= avpkt
->size
;
1416 RV34DecContext
*r
= avctx
->priv_data
;
1417 MpegEncContext
*s
= &r
->s
;
1418 AVFrame
*pict
= data
;
1422 const uint8_t *slices_hdr
= NULL
;
1425 /* no supplementary picture */
1426 if (buf_size
== 0) {
1427 /* special case for last picture */
1428 if (s
->low_delay
==0 && s
->next_picture_ptr
) {
1429 *pict
= *(AVFrame
*)s
->next_picture_ptr
;
1430 s
->next_picture_ptr
= NULL
;
1432 *data_size
= sizeof(AVFrame
);
1437 if(!avctx
->slice_count
){
1438 slice_count
= (*buf
++) + 1;
1439 slices_hdr
= buf
+ 4;
1440 buf
+= 8 * slice_count
;
1442 slice_count
= avctx
->slice_count
;
1444 //parse first slice header to check whether this frame can be decoded
1445 if(get_slice_offset(avctx
, slices_hdr
, 0) > buf_size
){
1446 av_log(avctx
, AV_LOG_ERROR
, "Slice offset is greater than frame size\n");
1449 init_get_bits(&s
->gb
, buf
+get_slice_offset(avctx
, slices_hdr
, 0), buf_size
-get_slice_offset(avctx
, slices_hdr
, 0));
1450 if(r
->parse_slice_header(r
, &r
->s
.gb
, &si
) < 0 || si
.start
){
1451 av_log(avctx
, AV_LOG_ERROR
, "First slice header is incorrect\n");
1454 if((!s
->last_picture_ptr
|| !s
->last_picture_ptr
->data
[0]) && si
.type
== FF_B_TYPE
)
1456 /* skip b frames if we are in a hurry */
1457 if(avctx
->hurry_up
&& si
.type
==FF_B_TYPE
) return buf_size
;
1458 if( (avctx
->skip_frame
>= AVDISCARD_NONREF
&& si
.type
==FF_B_TYPE
)
1459 || (avctx
->skip_frame
>= AVDISCARD_NONKEY
&& si
.type
!=FF_I_TYPE
)
1460 || avctx
->skip_frame
>= AVDISCARD_ALL
)
1462 /* skip everything if we are in a hurry>=5 */
1463 if(avctx
->hurry_up
>=5)
1466 for(i
=0; i
<slice_count
; i
++){
1467 int offset
= get_slice_offset(avctx
, slices_hdr
, i
);
1469 if(i
+1 == slice_count
)
1470 size
= buf_size
- offset
;
1472 size
= get_slice_offset(avctx
, slices_hdr
, i
+1) - offset
;
1474 if(offset
> buf_size
){
1475 av_log(avctx
, AV_LOG_ERROR
, "Slice offset is greater than frame size\n");
1479 r
->si
.end
= s
->mb_width
* s
->mb_height
;
1480 if(i
+1 < slice_count
){
1481 init_get_bits(&s
->gb
, buf
+get_slice_offset(avctx
, slices_hdr
, i
+1), (buf_size
-get_slice_offset(avctx
, slices_hdr
, i
+1))*8);
1482 if(r
->parse_slice_header(r
, &r
->s
.gb
, &si
) < 0){
1483 if(i
+2 < slice_count
)
1484 size
= get_slice_offset(avctx
, slices_hdr
, i
+2) - offset
;
1486 size
= buf_size
- offset
;
1488 r
->si
.end
= si
.start
;
1490 last
= rv34_decode_slice(r
, r
->si
.end
, buf
+ offset
, size
);
1491 s
->mb_num_left
= r
->s
.mb_x
+ r
->s
.mb_y
*r
->s
.mb_width
- r
->si
.start
;
1498 r
->loop_filter(r
, s
->mb_height
- 1);
1501 if (s
->pict_type
== FF_B_TYPE
|| s
->low_delay
) {
1502 *pict
= *(AVFrame
*)s
->current_picture_ptr
;
1503 } else if (s
->last_picture_ptr
!= NULL
) {
1504 *pict
= *(AVFrame
*)s
->last_picture_ptr
;
1507 if(s
->last_picture_ptr
|| s
->low_delay
){
1508 *data_size
= sizeof(AVFrame
);
1509 ff_print_debug_info(s
, pict
);
1511 s
->current_picture_ptr
= NULL
; //so we can detect if frame_end wasnt called (find some nicer solution...)
1516 av_cold
int ff_rv34_decode_end(AVCodecContext
*avctx
)
1518 RV34DecContext
*r
= avctx
->priv_data
;
1520 MPV_common_end(&r
->s
);
1522 av_freep(&r
->intra_types_hist
);
1523 r
->intra_types
= NULL
;
1524 av_freep(&r
->mb_type
);
1525 av_freep(&r
->cbp_luma
);
1526 av_freep(&r
->cbp_chroma
);
1527 av_freep(&r
->deblock_coefs
);