annotate wmv2dec.c @ 9473:e38284cd69dc libavcodec

Use memcpy instead of the very inefficient bytecopy where both are correct (i.e. no overlap of src and dst is possible).
author reimar
date Fri, 17 Apr 2009 17:20:48 +0000
parents 0f95e4f0a3f5
children 9ccc13d1144d
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"
8627
d6bab465b82c moves mid_pred() into mathops.h (with arch specific code split by directory)
aurel
parents: 7040
diff changeset
24 #include "mathops.h"
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
25 #include "msmpeg4.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
26 #include "msmpeg4data.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
27 #include "intrax8.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
28 #include "wmv2.h"
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
29
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 static void parse_mb_skip(Wmv2Context * w){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
32 int mb_x, mb_y;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
33 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
34 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
35
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
36 w->skip_type= get_bits(&s->gb, 2);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
37 switch(w->skip_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
38 case SKIP_TYPE_NONE:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
39 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
40 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
41 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
42 }
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 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
45 case SKIP_TYPE_MPEG:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
46 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
47 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
48 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
49 }
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 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
52 case SKIP_TYPE_ROW:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
53 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
54 if(get_bits1(&s->gb)){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
55 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
56 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
57 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
58 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
59 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
60 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
61 }
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 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
65 case SKIP_TYPE_COL:
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
66 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
67 if(get_bits1(&s->gb)){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
68 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
69 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
70 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
71 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
72 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
73 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
74 }
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 break;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
78 }
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 static int decode_ext_header(Wmv2Context *w){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
82 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
83 GetBitContext gb;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
84 int fps;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
85 int code;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
86
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
87 if(s->avctx->extradata_size<4) return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
88
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
89 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
90
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
91 fps = get_bits(&gb, 5);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
92 s->bit_rate = get_bits(&gb, 11)*1024;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
93 w->mspel_bit = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
94 s->loop_filter = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
95 w->abt_flag = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
96 w->j_type_bit = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
97 w->top_left_mv_flag= get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
98 w->per_mb_rl_bit = get_bits1(&gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
99 code = get_bits(&gb, 3);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
100
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
101 if(code==0) return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
102
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
103 s->slice_height = s->mb_height / code;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
104
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
105 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
106 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
107 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
108 code);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
109 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
110 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
111 }
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 int ff_wmv2_decode_picture_header(MpegEncContext * s)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
114 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
115 Wmv2Context * const w= (Wmv2Context*)s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
116 int code;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
117
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
118 #if 0
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
119 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
120 int i;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
121 for(i=0; i<s->gb.size*8; i++)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
122 printf("%d", get_bits1(&s->gb));
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
123 // get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
124 printf("END\n");
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
125 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
126 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
127 #endif
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
128 if(s->picture_number==0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
129 decode_ext_header(w);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
130
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
131 s->pict_type = get_bits1(&s->gb) + 1;
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
132 if(s->pict_type == FF_I_TYPE){
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
133 code = get_bits(&s->gb, 7);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
134 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
135 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
136 s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
6149
b1bd3188bdef qscale==0 is invalid
michael
parents: 5939
diff changeset
137 if(s->qscale <= 0)
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
138 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
139
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
140 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
141 }
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 int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
144 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
145 Wmv2Context * const w= (Wmv2Context*)s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
146
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
147 if (s->pict_type == FF_I_TYPE) {
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
148 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
149 else w->j_type= 0; //FIXME check
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
150
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
151 if(!w->j_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
152 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
153 else s->per_mb_rl_table= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
154
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
155 if(!s->per_mb_rl_table){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
156 s->rl_chroma_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
157 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
158 }
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 s->dc_table_index = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
161 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
162 s->inter_intra_pred= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
163 s->no_rounding = 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
164 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
165 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
166 s->qscale,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
167 s->rl_chroma_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
168 s->rl_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
169 s->dc_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
170 s->per_mb_rl_table,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
171 w->j_type);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
172 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
173 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
174 int cbp_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
175 w->j_type=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
176
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
177 parse_mb_skip(w);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
178 cbp_index= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
179 if(s->qscale <= 10){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
180 int map[3]= {0,2,1};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
181 w->cbp_table_index= map[cbp_index];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
182 }else if(s->qscale <= 20){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
183 int map[3]= {1,0,2};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
184 w->cbp_table_index= map[cbp_index];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
185 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
186 int map[3]= {2,1,0};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
187 w->cbp_table_index= map[cbp_index];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
188 }
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 if(w->mspel_bit) s->mspel= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
191 else s->mspel= 0; //FIXME check
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
192
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
193 if(w->abt_flag){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
194 w->per_mb_abt= get_bits1(&s->gb)^1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
195 if(!w->per_mb_abt){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
196 w->abt_type= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
197 }
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 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
201 else s->per_mb_rl_table= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
202
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
203 if(!s->per_mb_rl_table){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
204 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
205 s->rl_chroma_table_index = s->rl_table_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
206 }
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 s->dc_table_index = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
209 s->mv_table_index = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
210
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
211 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
212 s->no_rounding ^= 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
213
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
214 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
215 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
216 s->rl_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
217 s->rl_chroma_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
218 s->dc_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
219 s->mv_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
220 s->per_mb_rl_table,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
221 s->qscale,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
222 s->mspel,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
223 w->per_mb_abt,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
224 w->abt_type,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
225 w->cbp_table_index,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
226 s->inter_intra_pred);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
227 }
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 s->esc3_level_length= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
230 s->esc3_run_length= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
231
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
232 s->picture_number++; //FIXME ?
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
233
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 if(w->j_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
236 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
237 return 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
238 }
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 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
241 }
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 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
244 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
245 int ret;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
246
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
247 ret= ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
248
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
249 if(ret<0) return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
250
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
251 if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
252 w->hshift= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
253 else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
254 w->hshift= 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
255
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
256 //printf("%d %d ", *mx_ptr, *my_ptr);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
257
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
258 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
259 }
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 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
262 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
263 int xy, wrap, diff, type;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
264 int16_t *A, *B, *C, *mot_val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
265
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
266 wrap = s->b8_stride;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
267 xy = s->block_index[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
268
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
269 mot_val = s->current_picture.motion_val[0][xy];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
270
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
271 A = s->current_picture.motion_val[0][xy - 1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
272 B = s->current_picture.motion_val[0][xy - wrap];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
273 C = s->current_picture.motion_val[0][xy + 2 - wrap];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
274
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
275 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
276 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
277 else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
278 diff=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
279
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
280 if(diff >= 8)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
281 type= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
282 else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
283 type= 2;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
284
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
285 if(type == 0){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
286 *px= A[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
287 *py= A[1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
288 }else if(type == 1){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
289 *px= B[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
290 *py= B[1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
291 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
292 /* special case for first (slice) line */
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
293 if (s->first_slice_line) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
294 *px = A[0];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
295 *py = A[1];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
296 } else {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
297 *px = mid_pred(A[0], B[0], C[0]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
298 *py = mid_pred(A[1], B[1], C[1]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
299 }
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 return mot_val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
303 }
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 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
306 MpegEncContext * const s= &w->s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
307 static const int sub_cbp_table[3]= {2,3,1};
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
308 int sub_cbp;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
309
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
310 if(!cbp){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
311 s->block_last_index[n] = -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
312
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
313 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
314 }
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 if(w->per_block_abt)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
317 w->abt_type= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
318 #if 0
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
319 if(w->per_block_abt)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
320 printf("B%d", w->abt_type);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
321 #endif
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
322 w->abt_type_table[n]= w->abt_type;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
323
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
324 if(w->abt_type){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
325 // 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
326 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
327 // 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
328
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
329 sub_cbp= sub_cbp_table[ decode012(&s->gb) ];
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
330 // printf("S%d", sub_cbp);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
331
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
332 if(sub_cbp&1){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
333 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
334 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
335 }
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 if(sub_cbp&2){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
338 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
339 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
340 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
341 s->block_last_index[n] = 63;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
342
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
343 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
344 }else{
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
345 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
346 }
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 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
351 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
352 Wmv2Context * const w= (Wmv2Context*)s;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
353 int cbp, code, i;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
354 uint8_t *coded_val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
355
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
356 if(w->j_type) return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
357
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
358 if (s->pict_type == FF_P_TYPE) {
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
359 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
360 /* skip mb */
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
361 s->mb_intra = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
362 for(i=0;i<6;i++)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
363 s->block_last_index[i] = -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
364 s->mv_dir = MV_DIR_FORWARD;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
365 s->mv_type = MV_TYPE_16X16;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
366 s->mv[0][0][0] = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
367 s->mv[0][0][1] = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
368 s->mb_skipped = 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
369 w->hshift=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
370 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
371 }
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 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
374 if (code < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
375 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
376 s->mb_intra = (~code & 0x40) >> 6;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
377
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
378 cbp = code & 0x3f;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
379 } else {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
380 s->mb_intra = 1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
381 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
382 if (code < 0){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
383 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
384 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
385 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
386 /* predict coded block pattern */
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
387 cbp = 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
388 for(i=0;i<6;i++) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
389 int val = ((code >> (5 - i)) & 1);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
390 if (i < 4) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
391 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
392 val = val ^ pred;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
393 *coded_val = val;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
394 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
395 cbp |= val << (5 - i);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
396 }
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 if (!s->mb_intra) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
400 int mx, my;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
401 //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
402 wmv2_pred_motion(w, &mx, &my);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
403
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
404 if(cbp){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
405 s->dsp.clear_blocks(s->block[0]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
406 if(s->per_mb_rl_table){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
407 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
408 s->rl_chroma_table_index = s->rl_table_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
409 }
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 if(w->abt_flag && w->per_mb_abt){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
412 w->per_block_abt= get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
413 if(!w->per_block_abt)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
414 w->abt_type= decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
415 }else
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
416 w->per_block_abt=0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
417 }
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 if (wmv2_decode_motion(w, &mx, &my) < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
420 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
421
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
422 s->mv_dir = MV_DIR_FORWARD;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
423 s->mv_type = MV_TYPE_16X16;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
424 s->mv[0][0][0] = mx;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
425 s->mv[0][0][1] = my;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
426
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
427 for (i = 0; i < 6; i++) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
428 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
429 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
430 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
431 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
432 }
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 } else {
6481
493dc59d469a add FF_ prefix to all (frame)_TYPE usage
aurel
parents: 6176
diff changeset
435 //if(s->pict_type==FF_P_TYPE)
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
436 // printf("%d%d ", s->inter_intra_pred, cbp);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
437 //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
438 s->ac_pred = get_bits1(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
439 if(s->inter_intra_pred){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
440 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
441 // 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
442 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
443 if(s->per_mb_rl_table && cbp){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
444 s->rl_table_index = decode012(&s->gb);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
445 s->rl_chroma_table_index = s->rl_table_index;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
446 }
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 s->dsp.clear_blocks(s->block[0]);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
449 for (i = 0; i < 6; i++) {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
450 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
451 {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
452 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
453 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
454 }
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 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
459 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
460
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6481
diff changeset
461 static av_cold int wmv2_decode_init(AVCodecContext *avctx){
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
462 Wmv2Context * const w= avctx->priv_data;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
463
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
464 if(avctx->idct_algo==FF_IDCT_AUTO){
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
465 avctx->idct_algo=FF_IDCT_WMV2;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
466 }
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 if(ff_h263_decode_init(avctx) < 0)
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
469 return -1;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
470
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
471 ff_wmv2_common_init(w);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
472
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
473 ff_intrax8_common_init(&w->x8,&w->s);
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
474
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
475 return 0;
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
476 }
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
477
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6481
diff changeset
478 static av_cold int wmv2_decode_end(AVCodecContext *avctx)
6176
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
479 {
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
480 Wmv2Context *w = avctx->priv_data;
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
481
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
482 ff_intrax8_common_end(&w->x8);
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
483 return ff_h263_decode_end(avctx);
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
484 }
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
485
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
486 AVCodec wmv2_decoder = {
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
487 "wmv2",
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
488 CODEC_TYPE_VIDEO,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
489 CODEC_ID_WMV2,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
490 sizeof(Wmv2Context),
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
491 wmv2_decode_init,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
492 NULL,
6176
1d735690e172 Correctly clean up IntraX8Context upon codec close.
andoma
parents: 6149
diff changeset
493 wmv2_decode_end,
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
494 ff_h263_decode_frame,
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
495 CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6710
diff changeset
496 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
9028
0f95e4f0a3f5 Add and use ff_pixfmt_list_420.
michael
parents: 8629
diff changeset
497 .pix_fmts= ff_pixfmt_list_420,
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents:
diff changeset
498 };