1 /*
2  * motionvector.c --
3  *
4  *       Procedures to compute motion vectors.
5  *
6  */
7 
8 /*
9  * Copyright (c) 1995 The Regents of the University of California.
10  * All rights reserved.
11  *
12  * Permission to use, copy, modify, and distribute this software and its
13  * documentation for any purpose, without fee, and without written agreement is
14  * hereby granted, provided that the above copyright notice and the following
15  * two paragraphs appear in all copies of this software.
16  *
17  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
18  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
19  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
20  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21  *
22  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
23  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
25  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
26  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
27  */
28 
29 /*
30  * Portions of this software Copyright (c) 1995 Brown University.
31  * All rights reserved.
32  *
33  * Permission to use, copy, modify, and distribute this software and its
34  * documentation for any purpose, without fee, and without written agreement
35  * is hereby granted, provided that the above copyright notice and the
36  * following two paragraphs appear in all copies of this software.
37  *
38  * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
39  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
40  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
41  * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
45  * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
46  * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
47  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
48  */
49 
50 #include "video.h"
51 #include "proto.h"
52 #include "util.h"
53 
54 /*
55    Changes to make the code reentrant:
56       deglobalize curVidStream
57    Additional changes:
58       none
59    -lsh@cs.brown.edu (Loring Holden)
60 */
61 
62 
63 /*
64  *--------------------------------------------------------------
65  *
66  * ComputeVector --
67  *
68  *	Computes motion vector given parameters previously parsed
69  *      and reconstructed.
70  *
71  * Results:
72  *      Reconstructed motion vector info is put into recon_* parameters
73  *      passed to this function. Also updated previous motion vector
74  *      information.
75  *
76  * Side effects:
77  *      None.
78  *
79  *--------------------------------------------------------------
80  */
81 
82 #define ComputeVector(recon_right_ptr, recon_down_ptr, recon_right_prev, recon_down_prev, f, full_pel_vector, motion_h_code, motion_v_code, motion_h_r, motion_v_r)				\
83 									\
84 {									\
85   int comp_h_r, comp_v_r;						\
86   int right_little, right_big, down_little, down_big;			\
87   int max, min, new_vector;						\
88 									\
89   /* The following procedure for the reconstruction of motion vectors 	\
90      is a direct and simple implementation of the instructions given	\
91      in the mpeg December 1991 standard draft. 				\
92   */									\
93 									\
94   if (f == 1 || motion_h_code == 0)					\
95     comp_h_r = 0;							\
96   else 									\
97     comp_h_r = f - 1 - motion_h_r;					\
98 									\
99   if (f == 1 || motion_v_code == 0)					\
100     comp_v_r = 0;							\
101   else 									\
102     comp_v_r = f - 1 - motion_v_r;					\
103 									\
104   right_little = motion_h_code * f;					\
105   if (right_little == 0)						\
106     right_big = 0;							\
107   else {								\
108     if (right_little > 0) {						\
109       right_little = right_little - comp_h_r;				\
110       right_big = right_little - 32 * f;				\
111     }									\
112     else {								\
113       right_little = right_little + comp_h_r;				\
114       right_big = right_little + 32 * f;				\
115     }									\
116   }									\
117 									\
118   down_little = motion_v_code * f;					\
119   if (down_little == 0)							\
120     down_big = 0;							\
121   else {								\
122     if (down_little > 0) {						\
123       down_little = down_little - comp_v_r;				\
124       down_big = down_little - 32 * f;					\
125     }									\
126     else {								\
127       down_little = down_little + comp_v_r;				\
128       down_big = down_little + 32 * f;					\
129     }									\
130   }									\
131   									\
132   max = 16 * f - 1;							\
133   min = -16 * f;							\
134 									\
135   new_vector = recon_right_prev + right_little;				\
136 									\
137   if (new_vector <= max && new_vector >= min)				\
138     *recon_right_ptr = recon_right_prev + right_little;			\
139                       /* just new_vector */				\
140   else									\
141     *recon_right_ptr = recon_right_prev + right_big;			\
142   recon_right_prev = *recon_right_ptr;					\
143   if (full_pel_vector)							\
144     *recon_right_ptr = *recon_right_ptr << 1;				\
145 									\
146   new_vector = recon_down_prev + down_little;				\
147   if (new_vector <= max && new_vector >= min)				\
148     *recon_down_ptr = recon_down_prev + down_little;			\
149                       /* just new_vector */				\
150   else									\
151     *recon_down_ptr = recon_down_prev + down_big;			\
152   recon_down_prev = *recon_down_ptr;					\
153   if (full_pel_vector)							\
154     *recon_down_ptr = *recon_down_ptr << 1;				\
155 }
156 
157 
158 /*
159  *--------------------------------------------------------------
160  *
161  * ComputeForwVector --
162  *
163  *	Computes forward motion vector by calling ComputeVector
164  *      with appropriate parameters.
165  *
166  * Results:
167  *	Reconstructed motion vector placed in recon_right_for_ptr and
168  *      recon_down_for_ptr.
169  *
170  * Side effects:
171  *      None.
172  *
173  *--------------------------------------------------------------
174  */
175 
176 void
ComputeForwVector(recon_right_for_ptr,recon_down_for_ptr,the_stream)177 ComputeForwVector(recon_right_for_ptr, recon_down_for_ptr, the_stream)
178      int *recon_right_for_ptr;
179      int *recon_down_for_ptr;
180      VidStream *the_stream;
181 {
182 
183   Pict *picture;
184   Macroblock *mblock;
185 
186   picture = &(the_stream->picture);
187   mblock = &(the_stream->mblock);
188 
189   ComputeVector(recon_right_for_ptr, recon_down_for_ptr,
190 		mblock->recon_right_for_prev,
191 		mblock->recon_down_for_prev,
192 		(int) picture->forw_f,
193 		picture->full_pel_forw_vector,
194 		mblock->motion_h_forw_code, mblock->motion_v_forw_code,
195 		mblock->motion_h_forw_r, mblock->motion_v_forw_r);
196 }
197 
198 
199 /*
200  *--------------------------------------------------------------
201  *
202  * ComputeBackVector --
203  *
204  *	Computes backward motion vector by calling ComputeVector
205  *      with appropriate parameters.
206  *
207  * Results:
208  *	Reconstructed motion vector placed in recon_right_back_ptr and
209  *      recon_down_back_ptr.
210  *
211  * Side effects:
212  *      None.
213  *
214  *--------------------------------------------------------------
215  */
216 
217 void
ComputeBackVector(recon_right_back_ptr,recon_down_back_ptr,the_stream)218 ComputeBackVector(recon_right_back_ptr, recon_down_back_ptr, the_stream)
219      int *recon_right_back_ptr;
220      int *recon_down_back_ptr;
221      VidStream *the_stream;
222 {
223   Pict *picture;
224   Macroblock *mblock;
225 
226   picture = &(the_stream->picture);
227   mblock = &(the_stream->mblock);
228 
229   ComputeVector(recon_right_back_ptr, recon_down_back_ptr,
230 		mblock->recon_right_back_prev,
231 		mblock->recon_down_back_prev,
232 		(int) picture->back_f,
233 		picture->full_pel_back_vector,
234 		mblock->motion_h_back_code, mblock->motion_v_back_code,
235 		mblock->motion_h_back_r, mblock->motion_v_back_r);
236 
237 }
238