annotate wmv2.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 04423b2f6e0b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
1 /*
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 8288
diff changeset
2 * Copyright (c) 2002 The FFmpeg Project
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
3 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3741
diff changeset
4 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3741
diff changeset
5 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3741
diff changeset
6 * FFmpeg is free software; you can redistribute it and/or
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3741
diff changeset
9 * version 2.1 of the License, or (at your option) any later version.
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
10 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3741
diff changeset
11 * FFmpeg is distributed in the hope that it will be useful,
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
14 * Lesser General Public License for more details.
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
15 *
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3741
diff changeset
17 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2979
diff changeset
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
19 */
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
20
5884
02007962faf4 split wmv2 in its own file
aurel
parents: 5882
diff changeset
21 #include "avcodec.h"
02007962faf4 split wmv2 in its own file
aurel
parents: 5882
diff changeset
22 #include "mpegvideo.h"
02007962faf4 split wmv2 in its own file
aurel
parents: 5882
diff changeset
23 #include "msmpeg4data.h"
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
24 #include "simple_idct.h"
5939
b47573cb7401 split wmv2 encoder and decoder in their own files
aurel
parents: 5887
diff changeset
25 #include "wmv2.h"
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
26
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
27
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6001
diff changeset
28 av_cold void ff_wmv2_common_init(Wmv2Context * w){
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
29 MpegEncContext * const s= &w->s;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
30
1273
a979fab41ed8 ASV1 codec
michaelni
parents: 1185
diff changeset
31 ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0], wmv2_scantableA);
a979fab41ed8 ASV1 codec
michaelni
parents: 1185
diff changeset
32 ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1], wmv2_scantableB);
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
33 }
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
34
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
35 static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int stride, int n){
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
36 MpegEncContext * const s= &w->s;
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 1057
diff changeset
37
2655
ab7bd4722cef fix block corruption caused by clear_blocks() optimization
michael
parents: 2637
diff changeset
38 if (s->block_last_index[n] >= 0) {
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
39 switch(w->abt_type_table[n]){
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
40 case 0:
2655
ab7bd4722cef fix block corruption caused by clear_blocks() optimization
michael
parents: 2637
diff changeset
41 s->dsp.idct_add (dst, stride, block1);
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
42 break;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
43 case 1:
6001
f4859c13426b add ff_ prefix to all simple_idct symbols
aurel
parents: 5939
diff changeset
44 ff_simple_idct84_add(dst , stride, block1);
f4859c13426b add ff_ prefix to all simple_idct symbols
aurel
parents: 5939
diff changeset
45 ff_simple_idct84_add(dst + 4*stride, stride, w->abt_block2[n]);
8288
800444234375 clear_block mmx
lorenm
parents: 6517
diff changeset
46 s->dsp.clear_block(w->abt_block2[n]);
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
47 break;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
48 case 2:
6001
f4859c13426b add ff_ prefix to all simple_idct symbols
aurel
parents: 5939
diff changeset
49 ff_simple_idct48_add(dst , stride, block1);
f4859c13426b add ff_ prefix to all simple_idct symbols
aurel
parents: 5939
diff changeset
50 ff_simple_idct48_add(dst + 4 , stride, w->abt_block2[n]);
8288
800444234375 clear_block mmx
lorenm
parents: 6517
diff changeset
51 s->dsp.clear_block(w->abt_block2[n]);
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
52 break;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
53 default:
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1524
diff changeset
54 av_log(s->avctx, AV_LOG_ERROR, "internal error in WMV2 abt\n");
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
55 }
2655
ab7bd4722cef fix block corruption caused by clear_blocks() optimization
michael
parents: 2637
diff changeset
56 }
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
57 }
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
58
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
59 void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block1[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr){
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
60 Wmv2Context * const w= (Wmv2Context*)s;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
61
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
62 wmv2_add_block(w, block1[0], dest_y , s->linesize, 0);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
63 wmv2_add_block(w, block1[1], dest_y + 8 , s->linesize, 1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
64 wmv2_add_block(w, block1[2], dest_y + 8*s->linesize, s->linesize, 2);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
65 wmv2_add_block(w, block1[3], dest_y + 8 + 8*s->linesize, s->linesize, 3);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
66
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
67 if(s->flags&CODEC_FLAG_GRAY) return;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
68
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
69 wmv2_add_block(w, block1[4], dest_cb , s->uvlinesize, 4);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
70 wmv2_add_block(w, block1[5], dest_cr , s->uvlinesize, 5);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
71 }
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
72
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
73 void ff_mspel_motion(MpegEncContext *s,
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 1057
diff changeset
74 uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 1057
diff changeset
75 uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
76 int motion_x, int motion_y, int h)
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
77 {
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
78 Wmv2Context * const w= (Wmv2Context*)s;
1064
b32afefe7d33 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 1057
diff changeset
79 uint8_t *ptr;
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
80 int dxy, offset, mx, my, src_x, src_y, v_edge_pos, linesize, uvlinesize;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
81 int emu=0;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
82
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
83 dxy = ((motion_y & 1) << 1) | (motion_x & 1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
84 dxy = 2*dxy + w->hshift;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
85 src_x = s->mb_x * 16 + (motion_x >> 1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
86 src_y = s->mb_y * 16 + (motion_y >> 1);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
87
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
88 /* WARNING: do no forget half pels */
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
89 v_edge_pos = s->v_edge_pos;
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4333
diff changeset
90 src_x = av_clip(src_x, -16, s->width);
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4333
diff changeset
91 src_y = av_clip(src_y, -16, s->height);
4333
018b316baca7 maybe fixing a segfault
michael
parents: 4001
diff changeset
92
018b316baca7 maybe fixing a segfault
michael
parents: 4001
diff changeset
93 if(src_x<=-16 || src_x >= s->width)
018b316baca7 maybe fixing a segfault
michael
parents: 4001
diff changeset
94 dxy &= ~3;
018b316baca7 maybe fixing a segfault
michael
parents: 4001
diff changeset
95 if(src_y<=-16 || src_y >= s->height)
018b316baca7 maybe fixing a segfault
michael
parents: 4001
diff changeset
96 dxy &= ~4;
018b316baca7 maybe fixing a segfault
michael
parents: 4001
diff changeset
97
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
98 linesize = s->linesize;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
99 uvlinesize = s->uvlinesize;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
100 ptr = ref_picture[0] + (src_y * linesize) + src_x;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
101
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
102 if(s->flags&CODEC_FLAG_EMU_EDGE){
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
103 if(src_x<1 || src_y<1 || src_x + 17 >= s->h_edge_pos
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
104 || src_y + h+1 >= v_edge_pos){
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
105 ff_emulated_edge_mc(s->edge_emu_buffer, ptr - 1 - s->linesize, s->linesize, 19, 19,
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
106 src_x-1, src_y-1, s->h_edge_pos, s->v_edge_pos);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
107 ptr= s->edge_emu_buffer + 1 + s->linesize;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
108 emu=1;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
109 }
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
110 }
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
111
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
112 s->dsp.put_mspel_pixels_tab[dxy](dest_y , ptr , linesize);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
113 s->dsp.put_mspel_pixels_tab[dxy](dest_y+8 , ptr+8 , linesize);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
114 s->dsp.put_mspel_pixels_tab[dxy](dest_y +8*linesize, ptr +8*linesize, linesize);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
115 s->dsp.put_mspel_pixels_tab[dxy](dest_y+8+8*linesize, ptr+8+8*linesize, linesize);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
116
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
117 if(s->flags&CODEC_FLAG_GRAY) return;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
118
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
119 if (s->out_format == FMT_H263) {
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
120 dxy = 0;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
121 if ((motion_x & 3) != 0)
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
122 dxy |= 1;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
123 if ((motion_y & 3) != 0)
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
124 dxy |= 2;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
125 mx = motion_x >> 2;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
126 my = motion_y >> 2;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
127 } else {
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
128 mx = motion_x / 2;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
129 my = motion_y / 2;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
130 dxy = ((my & 1) << 1) | (mx & 1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
131 mx >>= 1;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
132 my >>= 1;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
133 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
134
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
135 src_x = s->mb_x * 8 + mx;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
136 src_y = s->mb_y * 8 + my;
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4333
diff changeset
137 src_x = av_clip(src_x, -8, s->width >> 1);
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
138 if (src_x == (s->width >> 1))
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
139 dxy &= ~1;
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4333
diff changeset
140 src_y = av_clip(src_y, -8, s->height >> 1);
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
141 if (src_y == (s->height >> 1))
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
142 dxy &= ~2;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
143 offset = (src_y * uvlinesize) + src_x;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
144 ptr = ref_picture[1] + offset;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
145 if(emu){
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
146 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
147 src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
148 ptr= s->edge_emu_buffer;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
149 }
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
150 pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
151
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
152 ptr = ref_picture[2] + offset;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
153 if(emu){
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2818
diff changeset
154 ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
936
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
155 src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
156 ptr= s->edge_emu_buffer;
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
157 }
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
158 pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1);
caa77cd960c0 qpel encoding
michaelni
parents:
diff changeset
159 }