3 * Copyright (c) 2007 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
28 #include "mpegutils.h"
29 #include "mpegvideo.h"
36 static int rv30_parse_slice_header(RV34DecContext
*r
, GetBitContext
*gb
, SliceInfo
*si
)
38 AVCodecContext
*avctx
= r
->s
.avctx
;
40 int w
= r
->s
.width
, h
= r
->s
.height
;
44 memset(si
, 0, sizeof(SliceInfo
));
47 si
->type
= get_bits(gb
, 2);
48 if(si
->type
== 1) si
->type
= 0;
51 si
->quant
= get_bits(gb
, 5);
53 si
->pts
= get_bits(gb
, 13);
54 rpr
= get_bits(gb
, av_log2(r
->max_rpr
) + 1);
56 if (rpr
> r
->max_rpr
) {
57 av_log(avctx
, AV_LOG_ERROR
, "rpr too large\n");
58 return AVERROR_INVALIDDATA
;
61 if (avctx
->extradata_size
< rpr
* 2 + 8) {
62 av_log(avctx
, AV_LOG_ERROR
,
63 "Insufficient extradata - need at least %d bytes, got %d\n",
64 8 + rpr
* 2, avctx
->extradata_size
);
65 return AVERROR(EINVAL
);
68 w
= r
->s
.avctx
->extradata
[6 + rpr
*2] << 2;
69 h
= r
->s
.avctx
->extradata
[7 + rpr
*2] << 2;
73 mb_size
= ((w
+ 15) >> 4) * ((h
+ 15) >> 4);
74 mb_bits
= ff_rv34_get_start_offset(gb
, mb_size
);
75 si
->start
= get_bits(gb
, mb_bits
);
81 * Decode 4x4 intra types array.
83 static int rv30_decode_intra_types(RV34DecContext
*r
, GetBitContext
*gb
, int8_t *dst
)
87 for(i
= 0; i
< 4; i
++, dst
+= r
->intra_types_stride
- 4){
88 for(j
= 0; j
< 4; j
+= 2){
89 unsigned code
= svq3_get_ue_golomb(gb
) << 1;
91 av_log(r
->s
.avctx
, AV_LOG_ERROR
, "Incorrect intra prediction code\n");
94 for(k
= 0; k
< 2; k
++){
95 int A
= dst
[-r
->intra_types_stride
] + 1;
97 *dst
++ = rv30_itype_from_context
[A
* 90 + B
* 9 + rv30_itype_code
[code
+ k
]];
99 av_log(r
->s
.avctx
, AV_LOG_ERROR
, "Incorrect intra prediction mode\n");
109 * Decode macroblock information.
111 static int rv30_decode_mb_info(RV34DecContext
*r
)
113 static const int rv30_p_types
[6] = { RV34_MB_SKIP
, RV34_MB_P_16x16
, RV34_MB_P_8x8
, -1, RV34_MB_TYPE_INTRA
, RV34_MB_TYPE_INTRA16x16
};
114 static const int rv30_b_types
[6] = { RV34_MB_SKIP
, RV34_MB_B_DIRECT
, RV34_MB_B_FORWARD
, RV34_MB_B_BACKWARD
, RV34_MB_TYPE_INTRA
, RV34_MB_TYPE_INTRA16x16
};
115 MpegEncContext
*s
= &r
->s
;
116 GetBitContext
*gb
= &s
->gb
;
117 unsigned code
= svq3_get_ue_golomb(gb
);
120 av_log(s
->avctx
, AV_LOG_ERROR
, "Incorrect MB type code\n");
124 av_log(s
->avctx
, AV_LOG_ERROR
, "dquant needed\n");
127 if(s
->pict_type
!= AV_PICTURE_TYPE_B
)
128 return rv30_p_types
[code
];
130 return rv30_b_types
[code
];
133 static inline void rv30_weak_loop_filter(uint8_t *src
, const int step
,
134 const int stride
, const int lim
)
136 const uint8_t *cm
= ff_crop_tab
+ MAX_NEG_CROP
;
139 for(i
= 0; i
< 4; i
++){
140 diff
= ((src
[-2*step
] - src
[1*step
]) - (src
[-1*step
] - src
[0*step
])*4) >> 3;
141 diff
= av_clip(diff
, -lim
, lim
);
142 src
[-1*step
] = cm
[src
[-1*step
] + diff
];
143 src
[ 0*step
] = cm
[src
[ 0*step
] - diff
];
148 static void rv30_loop_filter(RV34DecContext
*r
, int row
)
150 MpegEncContext
*s
= &r
->s
;
154 int loc_lim
, cur_lim
, left_lim
= 0, top_lim
= 0;
156 mb_pos
= row
* s
->mb_stride
;
157 for(mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++, mb_pos
++){
158 int mbtype
= s
->current_picture_ptr
->mb_type
[mb_pos
];
159 if(IS_INTRA(mbtype
) || IS_SEPARATE_DC(mbtype
))
160 r
->deblock_coefs
[mb_pos
] = 0xFFFF;
162 r
->cbp_chroma
[mb_pos
] = 0xFF;
165 /* all vertical edges are filtered first
166 * and horizontal edges are filtered on the next iteration
168 mb_pos
= row
* s
->mb_stride
;
169 for(mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++, mb_pos
++){
170 cur_lim
= rv30_loop_filt_lim
[s
->current_picture_ptr
->qscale_table
[mb_pos
]];
172 left_lim
= rv30_loop_filt_lim
[s
->current_picture_ptr
->qscale_table
[mb_pos
- 1]];
173 for(j
= 0; j
< 16; j
+= 4){
174 Y
= s
->current_picture_ptr
->f
->data
[0] + mb_x
*16 + (row
*16 + j
) * s
->linesize
+ 4 * !mb_x
;
175 for(i
= !mb_x
; i
< 4; i
++, Y
+= 4){
178 if(r
->deblock_coefs
[mb_pos
] & (1 << ij
))
180 else if(!i
&& r
->deblock_coefs
[mb_pos
- 1] & (1 << (ij
+ 3)))
182 else if( i
&& r
->deblock_coefs
[mb_pos
] & (1 << (ij
- 1)))
185 rv30_weak_loop_filter(Y
, 1, s
->linesize
, loc_lim
);
188 for(k
= 0; k
< 2; k
++){
189 int cur_cbp
, left_cbp
= 0;
190 cur_cbp
= (r
->cbp_chroma
[mb_pos
] >> (k
*4)) & 0xF;
192 left_cbp
= (r
->cbp_chroma
[mb_pos
- 1] >> (k
*4)) & 0xF;
193 for(j
= 0; j
< 8; j
+= 4){
194 C
= s
->current_picture_ptr
->f
->data
[k
+ 1] + mb_x
*8 + (row
*8 + j
) * s
->uvlinesize
+ 4 * !mb_x
;
195 for(i
= !mb_x
; i
< 2; i
++, C
+= 4){
196 int ij
= i
+ (j
>> 1);
198 if (cur_cbp
& (1 << ij
))
200 else if(!i
&& left_cbp
& (1 << (ij
+ 1)))
202 else if( i
&& cur_cbp
& (1 << (ij
- 1)))
205 rv30_weak_loop_filter(C
, 1, s
->uvlinesize
, loc_lim
);
210 mb_pos
= row
* s
->mb_stride
;
211 for(mb_x
= 0; mb_x
< s
->mb_width
; mb_x
++, mb_pos
++){
212 cur_lim
= rv30_loop_filt_lim
[s
->current_picture_ptr
->qscale_table
[mb_pos
]];
214 top_lim
= rv30_loop_filt_lim
[s
->current_picture_ptr
->qscale_table
[mb_pos
- s
->mb_stride
]];
215 for(j
= 4*!row
; j
< 16; j
+= 4){
216 Y
= s
->current_picture_ptr
->f
->data
[0] + mb_x
*16 + (row
*16 + j
) * s
->linesize
;
217 for(i
= 0; i
< 4; i
++, Y
+= 4){
220 if(r
->deblock_coefs
[mb_pos
] & (1 << ij
))
222 else if(!j
&& r
->deblock_coefs
[mb_pos
- s
->mb_stride
] & (1 << (ij
+ 12)))
224 else if( j
&& r
->deblock_coefs
[mb_pos
] & (1 << (ij
- 4)))
227 rv30_weak_loop_filter(Y
, s
->linesize
, 1, loc_lim
);
230 for(k
= 0; k
< 2; k
++){
231 int cur_cbp
, top_cbp
= 0;
232 cur_cbp
= (r
->cbp_chroma
[mb_pos
] >> (k
*4)) & 0xF;
234 top_cbp
= (r
->cbp_chroma
[mb_pos
- s
->mb_stride
] >> (k
*4)) & 0xF;
235 for(j
= 4*!row
; j
< 8; j
+= 4){
236 C
= s
->current_picture_ptr
->f
->data
[k
+1] + mb_x
*8 + (row
*8 + j
) * s
->uvlinesize
;
237 for(i
= 0; i
< 2; i
++, C
+= 4){
238 int ij
= i
+ (j
>> 1);
240 if (r
->cbp_chroma
[mb_pos
] & (1 << ij
))
242 else if(!j
&& top_cbp
& (1 << (ij
+ 2)))
244 else if( j
&& cur_cbp
& (1 << (ij
- 2)))
247 rv30_weak_loop_filter(C
, s
->uvlinesize
, 1, loc_lim
);
255 * Initialize decoder.
257 static av_cold
int rv30_decode_init(AVCodecContext
*avctx
)
259 RV34DecContext
*r
= avctx
->priv_data
;
262 if (avctx
->extradata_size
< 2) {
263 av_log(avctx
, AV_LOG_ERROR
, "Extradata is too small.\n");
264 return AVERROR(EINVAL
);
267 if ((ret
= ff_rv34_decode_init(avctx
)) < 0)
270 r
->max_rpr
= avctx
->extradata
[1] & 7;
271 if(avctx
->extradata_size
< 2*r
->max_rpr
+ 8){
272 av_log(avctx
, AV_LOG_WARNING
, "Insufficient extradata - need at least %d bytes, got %d\n",
273 2*r
->max_rpr
+ 8, avctx
->extradata_size
);
276 r
->parse_slice_header
= rv30_parse_slice_header
;
277 r
->decode_intra_types
= rv30_decode_intra_types
;
278 r
->decode_mb_info
= rv30_decode_mb_info
;
279 r
->loop_filter
= rv30_loop_filter
;
280 r
->luma_dc_quant_i
= rv30_luma_dc_quant
;
281 r
->luma_dc_quant_p
= rv30_luma_dc_quant
;
285 AVCodec ff_rv30_decoder
= {
287 .long_name
= NULL_IF_CONFIG_SMALL("RealVideo 3.0"),
288 .type
= AVMEDIA_TYPE_VIDEO
,
289 .id
= AV_CODEC_ID_RV30
,
290 .priv_data_size
= sizeof(RV34DecContext
),
291 .init
= rv30_decode_init
,
292 .close
= ff_rv34_decode_end
,
293 .decode
= ff_rv34_decode_frame
,
294 .capabilities
= CODEC_CAP_DR1
| CODEC_CAP_DELAY
|
295 CODEC_CAP_FRAME_THREADS
,
296 .flush
= ff_mpeg_flush
,
297 .pix_fmts
= (const enum AVPixelFormat
[]) {
301 .init_thread_copy
= ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy
),
302 .update_thread_context
= ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context
),