2 * Copyright (c) 2002 The FFmpeg Project.
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "mpegvideo.h"
23 #include "msmpeg4data.h"
24 #include "simple_idct.h"
28 av_cold
void ff_wmv2_common_init(Wmv2Context
* w
){
29 MpegEncContext
* const s
= &w
->s
;
31 ff_init_scantable(s
->dsp
.idct_permutation
, &w
->abt_scantable
[0], wmv2_scantableA
);
32 ff_init_scantable(s
->dsp
.idct_permutation
, &w
->abt_scantable
[1], wmv2_scantableB
);
35 static void wmv2_add_block(Wmv2Context
*w
, DCTELEM
*block1
, uint8_t *dst
, int stride
, int n
){
36 MpegEncContext
* const s
= &w
->s
;
38 if (s
->block_last_index
[n
] >= 0) {
39 switch(w
->abt_type_table
[n
]){
41 s
->dsp
.idct_add (dst
, stride
, block1
);
44 ff_simple_idct84_add(dst
, stride
, block1
);
45 ff_simple_idct84_add(dst
+ 4*stride
, stride
, w
->abt_block2
[n
]);
46 memset(w
->abt_block2
[n
], 0, 64*sizeof(DCTELEM
));
49 ff_simple_idct48_add(dst
, stride
, block1
);
50 ff_simple_idct48_add(dst
+ 4 , stride
, w
->abt_block2
[n
]);
51 memset(w
->abt_block2
[n
], 0, 64*sizeof(DCTELEM
));
54 av_log(s
->avctx
, AV_LOG_ERROR
, "internal error in WMV2 abt\n");
59 void ff_wmv2_add_mb(MpegEncContext
*s
, DCTELEM block1
[6][64], uint8_t *dest_y
, uint8_t *dest_cb
, uint8_t *dest_cr
){
60 Wmv2Context
* const w
= (Wmv2Context
*)s
;
62 wmv2_add_block(w
, block1
[0], dest_y
, s
->linesize
, 0);
63 wmv2_add_block(w
, block1
[1], dest_y
+ 8 , s
->linesize
, 1);
64 wmv2_add_block(w
, block1
[2], dest_y
+ 8*s
->linesize
, s
->linesize
, 2);
65 wmv2_add_block(w
, block1
[3], dest_y
+ 8 + 8*s
->linesize
, s
->linesize
, 3);
67 if(s
->flags
&CODEC_FLAG_GRAY
) return;
69 wmv2_add_block(w
, block1
[4], dest_cb
, s
->uvlinesize
, 4);
70 wmv2_add_block(w
, block1
[5], dest_cr
, s
->uvlinesize
, 5);
73 void ff_mspel_motion(MpegEncContext
*s
,
74 uint8_t *dest_y
, uint8_t *dest_cb
, uint8_t *dest_cr
,
75 uint8_t **ref_picture
, op_pixels_func (*pix_op
)[4],
76 int motion_x
, int motion_y
, int h
)
78 Wmv2Context
* const w
= (Wmv2Context
*)s
;
80 int dxy
, offset
, mx
, my
, src_x
, src_y
, v_edge_pos
, linesize
, uvlinesize
;
83 dxy
= ((motion_y
& 1) << 1) | (motion_x
& 1);
84 dxy
= 2*dxy
+ w
->hshift
;
85 src_x
= s
->mb_x
* 16 + (motion_x
>> 1);
86 src_y
= s
->mb_y
* 16 + (motion_y
>> 1);
88 /* WARNING: do no forget half pels */
89 v_edge_pos
= s
->v_edge_pos
;
90 src_x
= av_clip(src_x
, -16, s
->width
);
91 src_y
= av_clip(src_y
, -16, s
->height
);
93 if(src_x
<=-16 || src_x
>= s
->width
)
95 if(src_y
<=-16 || src_y
>= s
->height
)
98 linesize
= s
->linesize
;
99 uvlinesize
= s
->uvlinesize
;
100 ptr
= ref_picture
[0] + (src_y
* linesize
) + src_x
;
102 if(s
->flags
&CODEC_FLAG_EMU_EDGE
){
103 if(src_x
<1 || src_y
<1 || src_x
+ 17 >= s
->h_edge_pos
104 || src_y
+ h
+1 >= v_edge_pos
){
105 ff_emulated_edge_mc(s
->edge_emu_buffer
, ptr
- 1 - s
->linesize
, s
->linesize
, 19, 19,
106 src_x
-1, src_y
-1, s
->h_edge_pos
, s
->v_edge_pos
);
107 ptr
= s
->edge_emu_buffer
+ 1 + s
->linesize
;
112 s
->dsp
.put_mspel_pixels_tab
[dxy
](dest_y
, ptr
, linesize
);
113 s
->dsp
.put_mspel_pixels_tab
[dxy
](dest_y
+8 , ptr
+8 , linesize
);
114 s
->dsp
.put_mspel_pixels_tab
[dxy
](dest_y
+8*linesize
, ptr
+8*linesize
, linesize
);
115 s
->dsp
.put_mspel_pixels_tab
[dxy
](dest_y
+8+8*linesize
, ptr
+8+8*linesize
, linesize
);
117 if(s
->flags
&CODEC_FLAG_GRAY
) return;
119 if (s
->out_format
== FMT_H263
) {
121 if ((motion_x
& 3) != 0)
123 if ((motion_y
& 3) != 0)
130 dxy
= ((my
& 1) << 1) | (mx
& 1);
135 src_x
= s
->mb_x
* 8 + mx
;
136 src_y
= s
->mb_y
* 8 + my
;
137 src_x
= av_clip(src_x
, -8, s
->width
>> 1);
138 if (src_x
== (s
->width
>> 1))
140 src_y
= av_clip(src_y
, -8, s
->height
>> 1);
141 if (src_y
== (s
->height
>> 1))
143 offset
= (src_y
* uvlinesize
) + src_x
;
144 ptr
= ref_picture
[1] + offset
;
146 ff_emulated_edge_mc(s
->edge_emu_buffer
, ptr
, s
->uvlinesize
, 9, 9,
147 src_x
, src_y
, s
->h_edge_pos
>>1, s
->v_edge_pos
>>1);
148 ptr
= s
->edge_emu_buffer
;
150 pix_op
[1][dxy
](dest_cb
, ptr
, uvlinesize
, h
>> 1);
152 ptr
= ref_picture
[2] + offset
;
154 ff_emulated_edge_mc(s
->edge_emu_buffer
, ptr
, s
->uvlinesize
, 9, 9,
155 src_x
, src_y
, s
->h_edge_pos
>>1, s
->v_edge_pos
>>1);
156 ptr
= s
->edge_emu_buffer
;
158 pix_op
[1][dxy
](dest_cr
, ptr
, uvlinesize
, h
>> 1);