annotate wmv2dec.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents c35d7bc64882
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
1 /*
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 8627
diff changeset
2 * Copyright (c) 2002 The FFmpeg Project
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
3 *
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
4 * This file is part of FFmpeg.
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
5 *
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
6 * FFmpeg is free software; you can redistribute it and/or
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
9 * version 2.1 of the License, or (at your option) any later version.
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
10 *
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
11 * FFmpeg is distributed in the hope that it will be useful,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
14 * Lesser General Public License for more details.
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
15 *
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
17 * License along with FFmpeg; if not, write to the Free Software
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
19 */
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
20
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
21 #include "avcodec.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
22 #include "dsputil.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
23 #include "mpegvideo.h"
10828
d0657e337f91 Split H263 encoder and decoder from common code.
michael
parents: 10822
diff changeset
24 #include "h263.h"
8627
d6bab465b82c moves mid_pred() into mathops.h (with arch specific code split by directory)
aurel
parents: 7040
diff changeset
25 #include "mathops.h"
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
26 #include "msmpeg4.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
27 #include "msmpeg4data.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
28 #include "intrax8.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
29 #include "wmv2.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
30
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
31
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
32 static void parse_mb_skip(Wmv2Context * w){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
33 int mb_x, mb_y;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
34 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
35 uint32_t * const mb_type= s->current_picture_ptr->mb_type;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
36
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
37 w->skip_type= get_bits(&s->gb, 2);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
38 switch(w->skip_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
39 case SKIP_TYPE_NONE:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
40 for(mb_y=0; mb_y<s->mb_height; mb_y++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
41 for(mb_x=0; mb_x<s->mb_width; mb_x++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
42 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_16x16 | MB_TYPE_L0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
43 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
44 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
45 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
46 case SKIP_TYPE_MPEG:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
47 for(mb_y=0; mb_y<s->mb_height; mb_y++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
48 for(mb_x=0; mb_x<s->mb_width; mb_x++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
49 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
50 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
51 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
52 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
53 case SKIP_TYPE_ROW:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
54 for(mb_y=0; mb_y<s->mb_height; mb_y++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
55 if(get_bits1(&s->gb)){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
56 for(mb_x=0; mb_x<s->mb_width; mb_x++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
57 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
58 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
59 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
60 for(mb_x=0; mb_x<s->mb_width; mb_x++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
61 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
62 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
63 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
64 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
65 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
66 case SKIP_TYPE_COL:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
67 for(mb_x=0; mb_x<s->mb_width; mb_x++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
68 if(get_bits1(&s->gb)){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
69 for(mb_y=0; mb_y<s->mb_height; mb_y++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
70 mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
71 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
72 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
73 for(mb_y=0; mb_y<s->mb_height; mb_y++){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
74 mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
75 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
76 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
77 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
78 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
79 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
80 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
81
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
82 static int decode_ext_header(Wmv2Context *w){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
83 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
84 GetBitContext gb;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
85 int fps;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
86 int code;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
87
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
88 if(s->avctx->extradata_size<4) return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
89
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
90 init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
91
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
92 fps = get_bits(&gb, 5);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
93 s->bit_rate = get_bits(&gb, 11)*1024;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
94 w->mspel_bit = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
95 s->loop_filter = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
96 w->abt_flag = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
97 w->j_type_bit = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
98 w->top_left_mv_flag= get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
99 w->per_mb_rl_bit = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
100 code = get_bits(&gb, 3);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
101
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
102 if(code==0) return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
103
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
104 s->slice_height = s->mb_height / code;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
105
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
106 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
107 av_log(s->avctx, AV_LOG_DEBUG, "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, tl_mv_flag:%d, mbrl_bit:%d, code:%d, loop_filter:%d, slices:%d\n",
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
108 fps, s->bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit, w->top_left_mv_flag, w->per_mb_rl_bit, code, s->loop_filter,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
109 code);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
110 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
111 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
112 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
113
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
114 int ff_wmv2_decode_picture_header(MpegEncContext * s)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
115 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
116 Wmv2Context * const w= (Wmv2Context*)s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
117 int code;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
118
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
119 #if 0
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
120 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
121 int i;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
122 for(i=0; i<s->gb.size*8; i++)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
123 printf("%d", get_bits1(&s->gb));
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
124 // get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
125 printf("END\n");
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
126 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
127 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
128 #endif
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
129 if(s->picture_number==0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
130 decode_ext_header(w);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
131
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
132 s->pict_type = get_bits1(&s->gb) + 1;
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
133 if(s->pict_type == FF_I_TYPE){
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
134 code = get_bits(&s->gb, 7);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
135 av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
136 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
137 s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
6149
b1bd3188bdef qscale==0 is invalid
michael
parents: 5939
diff changeset
138 if(s->qscale <= 0)
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
139 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
140
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
141 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
142 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
143
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
144 int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
145 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
146 Wmv2Context * const w= (Wmv2Context*)s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
147
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
148 if (s->pict_type == FF_I_TYPE) {
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
149 if(w->j_type_bit) w->j_type= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
150 else w->j_type= 0; //FIXME check
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
151
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
152 if(!w->j_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
153 if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
154 else s->per_mb_rl_table= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
155
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
156 if(!s->per_mb_rl_table){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
157 s->rl_chroma_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
158 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
159 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
160
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
161 s->dc_table_index = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
162 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
163 s->inter_intra_pred= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
164 s->no_rounding = 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
165 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
166 av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n",
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
167 s->qscale,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
168 s->rl_chroma_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
169 s->rl_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
170 s->dc_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
171 s->per_mb_rl_table,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
172 w->j_type);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
173 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
174 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
175 int cbp_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
176 w->j_type=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
177
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
178 parse_mb_skip(w);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
179 cbp_index= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
180 if(s->qscale <= 10){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
181 int map[3]= {0,2,1};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
182 w->cbp_table_index= map[cbp_index];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
183 }else if(s->qscale <= 20){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
184 int map[3]= {1,0,2};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
185 w->cbp_table_index= map[cbp_index];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
186 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
187 int map[3]= {2,1,0};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
188 w->cbp_table_index= map[cbp_index];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
189 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
190
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
191 if(w->mspel_bit) s->mspel= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
192 else s->mspel= 0; //FIXME check
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
193
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
194 if(w->abt_flag){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
195 w->per_mb_abt= get_bits1(&s->gb)^1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
196 if(!w->per_mb_abt){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
197 w->abt_type= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
198 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
199 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
200
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
201 if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
202 else s->per_mb_rl_table= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
203
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
204 if(!s->per_mb_rl_table){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
205 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
206 s->rl_chroma_table_index = s->rl_table_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
207 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
208
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
209 s->dc_table_index = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
210 s->mv_table_index = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
211
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
212 s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
213 s->no_rounding ^= 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
214
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
215 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
216 av_log(s->avctx, AV_LOG_DEBUG, "rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d mspel:%d per_mb_abt:%d abt_type:%d cbp:%d ii:%d\n",
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
217 s->rl_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
218 s->rl_chroma_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
219 s->dc_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
220 s->mv_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
221 s->per_mb_rl_table,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
222 s->qscale,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
223 s->mspel,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
224 w->per_mb_abt,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
225 w->abt_type,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
226 w->cbp_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
227 s->inter_intra_pred);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
228 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
229 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
230 s->esc3_level_length= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
231 s->esc3_run_length= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
232
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
233 s->picture_number++; //FIXME ?
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
234
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
235
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
236 if(w->j_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
237 ff_intrax8_decode_picture(&w->x8, 2*s->qscale, (s->qscale-1)|1 );
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
238 return 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
239 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
240
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
241 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
242 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
243
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
244 static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
245 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
246 int ret;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
247
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
248 ret= ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
249
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
250 if(ret<0) return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
251
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
252 if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
253 w->hshift= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
254 else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
255 w->hshift= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
256
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
257 //printf("%d %d ", *mx_ptr, *my_ptr);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
258
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
259 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
260 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
261
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
262 static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
263 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
264 int xy, wrap, diff, type;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
265 int16_t *A, *B, *C, *mot_val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
266
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
267 wrap = s->b8_stride;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
268 xy = s->block_index[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
269
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
270 mot_val = s->current_picture.motion_val[0][xy];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
271
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
272 A = s->current_picture.motion_val[0][xy - 1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
273 B = s->current_picture.motion_val[0][xy - wrap];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
274 C = s->current_picture.motion_val[0][xy + 2 - wrap];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
275
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
276 if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
277 diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1]));
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
278 else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
279 diff=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
280
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
281 if(diff >= 8)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
282 type= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
283 else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
284 type= 2;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
285
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
286 if(type == 0){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
287 *px= A[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
288 *py= A[1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
289 }else if(type == 1){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
290 *px= B[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
291 *py= B[1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
292 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
293 /* special case for first (slice) line */
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
294 if (s->first_slice_line) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
295 *px = A[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
296 *py = A[1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
297 } else {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
298 *px = mid_pred(A[0], B[0], C[0]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
299 *py = mid_pred(A[1], B[1], C[1]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
300 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
301 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
302
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
303 return mot_val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
304 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
305
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
306 static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
307 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
308 static const int sub_cbp_table[3]= {2,3,1};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
309 int sub_cbp;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
310
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
311 if(!cbp){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
312 s->block_last_index[n] = -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
313
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
314 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
315 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
316
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
317 if(w->per_block_abt)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
318 w->abt_type= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
319 #if 0
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
320 if(w->per_block_abt)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
321 printf("B%d", w->abt_type);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
322 #endif
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
323 w->abt_type_table[n]= w->abt_type;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
324
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
325 if(w->abt_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
326 // const uint8_t *scantable= w->abt_scantable[w->abt_type-1].permutated;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
327 const uint8_t *scantable= w->abt_scantable[w->abt_type-1].scantable;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
328 // const uint8_t *scantable= w->abt_type-1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
329
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
330 sub_cbp= sub_cbp_table[ decode012(&s->gb) ];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
331 // printf("S%d", sub_cbp);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
332
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
333 if(sub_cbp&1){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
334 if (ff_msmpeg4_decode_block(s, block, n, 1, scantable) < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
335 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
336 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
337
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
338 if(sub_cbp&2){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
339 if (ff_msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
340 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
341 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
342 s->block_last_index[n] = 63;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
343
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
344 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
345 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
346 return ff_msmpeg4_decode_block(s, block, n, 1, s->inter_scantable.permutated);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
347 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
348 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
349
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
350
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
351 int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
352 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
353 Wmv2Context * const w= (Wmv2Context*)s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
354 int cbp, code, i;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
355 uint8_t *coded_val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
356
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
357 if(w->j_type) return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
358
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
359 if (s->pict_type == FF_P_TYPE) {
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
360 if(IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
361 /* skip mb */
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
362 s->mb_intra = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
363 for(i=0;i<6;i++)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
364 s->block_last_index[i] = -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
365 s->mv_dir = MV_DIR_FORWARD;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
366 s->mv_type = MV_TYPE_16X16;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
367 s->mv[0][0][0] = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
368 s->mv[0][0][1] = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
369 s->mb_skipped = 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
370 w->hshift=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
371 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
372 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
373
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
374 code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
375 if (code < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
376 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
377 s->mb_intra = (~code & 0x40) >> 6;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
378
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
379 cbp = code & 0x3f;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
380 } else {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
381 s->mb_intra = 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
382 code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
383 if (code < 0){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
384 av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
385 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
386 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
387 /* predict coded block pattern */
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
388 cbp = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
389 for(i=0;i<6;i++) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
390 int val = ((code >> (5 - i)) & 1);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
391 if (i < 4) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
392 int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
393 val = val ^ pred;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
394 *coded_val = val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
395 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
396 cbp |= val << (5 - i);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
397 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
398 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
399
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
400 if (!s->mb_intra) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
401 int mx, my;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
402 //printf("P at %d %d\n", s->mb_x, s->mb_y);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
403 wmv2_pred_motion(w, &mx, &my);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
404
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
405 if(cbp){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
406 s->dsp.clear_blocks(s->block[0]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
407 if(s->per_mb_rl_table){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
408 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
409 s->rl_chroma_table_index = s->rl_table_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
410 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
411
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
412 if(w->abt_flag && w->per_mb_abt){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
413 w->per_block_abt= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
414 if(!w->per_block_abt)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
415 w->abt_type= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
416 }else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
417 w->per_block_abt=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
418 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
419
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
420 if (wmv2_decode_motion(w, &mx, &my) < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
421 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
422
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
423 s->mv_dir = MV_DIR_FORWARD;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
424 s->mv_type = MV_TYPE_16X16;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
425 s->mv[0][0][0] = mx;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
426 s->mv[0][0][1] = my;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
427
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
428 for (i = 0; i < 6; i++) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
429 if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
430 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
431 av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding inter block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
432 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
433 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
434 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
435 } else {
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
436 //if(s->pict_type==FF_P_TYPE)
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
437 // printf("%d%d ", s->inter_intra_pred, cbp);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
438 //printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24));
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
439 s->ac_pred = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
440 if(s->inter_intra_pred){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
441 s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
442 // printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
443 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
444 if(s->per_mb_rl_table && cbp){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
445 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
446 s->rl_chroma_table_index = s->rl_table_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
447 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
448
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
449 s->dsp.clear_blocks(s->block[0]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
450 for (i = 0; i < 6; i++) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
451 if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
452 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
453 av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding intra block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
454 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
455 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
456 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
457 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
458
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
459 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
460 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
461
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6481
diff changeset
462 static av_cold int wmv2_decode_init(AVCodecContext *avctx){
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
463 Wmv2Context * const w= avctx->priv_data;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
464
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
465 if(avctx->idct_algo==FF_IDCT_AUTO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
466 avctx->idct_algo=FF_IDCT_WMV2;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
467 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
468
10822
9ccc13d1144d Move AVCodecs from h263dec.c to msmpeg4.c and disentangle init decode init.
michael
parents: 9028
diff changeset
469 if(ff_msmpeg4_decode_init(avctx) < 0)
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
470 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
471
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
472 ff_wmv2_common_init(w);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
473
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
474 ff_intrax8_common_init(&w->x8,&w->s);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
475
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
476 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
477 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
478
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6481
diff changeset
479 static av_cold int wmv2_decode_end(AVCodecContext *avctx)
6176
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
480 {
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
481 Wmv2Context *w = avctx->priv_data;
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
482
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
483 ff_intrax8_common_end(&w->x8);
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
484 return ff_h263_decode_end(avctx);
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
485 }
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
486
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
487 AVCodec wmv2_decoder = {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
488 "wmv2",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10828
diff changeset
489 AVMEDIA_TYPE_VIDEO,
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
490 CODEC_ID_WMV2,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
491 sizeof(Wmv2Context),
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
492 wmv2_decode_init,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
493 NULL,
6176
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
494 wmv2_decode_end,
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
495 ff_h263_decode_frame,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
496 CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
12108
c35d7bc64882 Add new decoder property max_lowres and do not init decoder if requested value is higher.
cehoyos
parents: 11560
diff changeset
497 .max_lowres = 3,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6710
diff changeset
498 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
9028
0f95e4f0a3f5 Add and use ff_pixfmt_list_420.
michael
parents: 8629
diff changeset
499 .pix_fmts= ff_pixfmt_list_420,
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
500 };