1 /* motion.c, motion vector decoding */
2
3 /* Copyright (C) 1994, MPEG Software Simulation Group. All Rights Reserved. */
4
5 /*
6 * Disclaimer of Warranty
7 *
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
15 *
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
18 *
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
21 * patents.
22 *
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
26 * design.
27 *
28 */
29
30 #include <stdio.h>
31
32 #include "config.h"
33 #include "global.h"
34
35 /* private prototypes */
36 static void calcMV _ANSI_ARGS_((int *pred, int r_size, int motion_code,
37 int motion_r, int full_pel_vector));
38
motion_vectors(PMV,dmvector,mv_field_sel,s,mv_count,mv_format,h_r_size,v_r_size,dmv,mvscale)39 void motion_vectors(PMV,dmvector,
40 mv_field_sel,s,mv_count,mv_format,h_r_size,v_r_size,dmv,mvscale)
41 int PMV[2][2][2];
42 int dmvector[2];
43 int mv_field_sel[2][2];
44 int s, mv_count, mv_format, h_r_size, v_r_size, dmv, mvscale;
45 {
46 if (mv_count==1)
47 {
48 if (mv_format==MV_FIELD && !dmv)
49 {
50 mv_field_sel[1][s] = mv_field_sel[0][s] = getbits(1);
51 #ifdef TRACE
52 if (trace)
53 {
54 printf("motion_vertical_field_select[][%d] (%d): %d\n",s,
55 mv_field_sel[0][s],mv_field_sel[0][s]);
56 }
57 #endif
58 }
59
60 motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
61
62 /* update other motion vector predictors */
63 PMV[1][s][0] = PMV[0][s][0];
64 PMV[1][s][1] = PMV[0][s][1];
65 }
66 else
67 {
68 mv_field_sel[0][s] = getbits(1);
69 #ifdef TRACE
70 if (trace)
71 {
72 printf("motion_vertical_field_select[0][%d] (%d): %d\n",s,
73 mv_field_sel[0][s],mv_field_sel[0][s]);
74 }
75 #endif
76 motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
77
78 mv_field_sel[1][s] = getbits(1);
79 #ifdef TRACE
80 if (trace)
81 {
82 printf("motion_vertical_field_select[1][%d] (%d): %d\n",s,
83 mv_field_sel[1][s],mv_field_sel[1][s]);
84 }
85 #endif
86 motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
87 }
88 }
89
90 /* get and decode motion vector and differential motion vector */
motion_vector(PMV,dmvector,h_r_size,v_r_size,dmv,mvscale,full_pel_vector)91 void motion_vector(PMV,dmvector,
92 h_r_size,v_r_size,dmv,mvscale,full_pel_vector)
93 int *PMV;
94 int *dmvector;
95 int h_r_size;
96 int v_r_size;
97 int dmv; /* MPEG-2 only: get differential motion vectors */
98 int mvscale; /* MPEG-2 only: field vector in frame pic */
99 int full_pel_vector; /* MPEG-1 only */
100 {
101 int motion_code,motion_r;
102
103 motion_code = getMV();
104 motion_r = (h_r_size!=0 && motion_code!=0) ? getbits(h_r_size) : 0;
105
106 #ifdef TRACE
107 if (trace)
108 {
109 if (h_r_size!=0 && motion_code!=0)
110 {
111 printf("motion_residual (");
112 printbits(motion_r,h_r_size,h_r_size);
113 printf("): %d\n",motion_r);
114 }
115 }
116 #endif
117
118 calcMV(&PMV[0],h_r_size,motion_code,motion_r,full_pel_vector);
119
120 if (dmv)
121 dmvector[0] = getDMV();
122
123 motion_code = getMV();
124 motion_r = (v_r_size!=0 && motion_code!=0) ? getbits(v_r_size) : 0;
125
126 #ifdef TRACE
127 if (trace)
128 {
129 if (v_r_size!=0 && motion_code!=0)
130 {
131 printf("motion_residual (");
132 printbits(motion_r,v_r_size,v_r_size);
133 printf("): %d\n",motion_r);
134 }
135 }
136 #endif
137
138 if (mvscale)
139 PMV[1] >>= 1; /* DIV 2 */
140
141 calcMV(&PMV[1],v_r_size,motion_code,motion_r,full_pel_vector);
142
143 if (mvscale)
144 PMV[1] <<= 1;
145
146 if (dmv)
147 dmvector[1] = getDMV();
148
149 #ifdef TRACE
150 if (trace)
151 printf("PMV = %d,%d\n",PMV[0],PMV[1]);
152 #endif
153 }
154
155 /* calculate motion vector component */
calcMV(pred,r_size,motion_code,motion_r,full_pel_vector)156 static void calcMV(pred,r_size,motion_code,motion_r,full_pel_vector)
157 int *pred;
158 int r_size, motion_code, motion_r, full_pel_vector;
159 {
160 int lim, vec;
161
162 lim = 16<<r_size;
163 vec = full_pel_vector ? (*pred >> 1) : (*pred);
164
165 if (motion_code>0)
166 {
167 vec+= ((motion_code-1)<<r_size) + motion_r + 1;
168 if (vec>=lim)
169 vec-= lim + lim;
170 }
171 else if (motion_code<0)
172 {
173 vec-= ((-motion_code-1)<<r_size) + motion_r + 1;
174 if (vec<-lim)
175 vec+= lim + lim;
176 }
177 *pred = full_pel_vector ? (vec<<1) : vec;
178 }
179
calc_DMV(DMV,dmvector,mvx,mvy)180 void calc_DMV(DMV,dmvector,mvx,mvy)
181 int DMV[][2];
182 int *dmvector; /* differential motion vector */
183 int mvx, mvy; /* decoded mv components (always in field format) */
184 {
185 if (pict_struct==FRAME_PICTURE)
186 {
187 if (topfirst)
188 {
189 /* vector for prediction of top field from bottom field */
190 DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
191 DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1;
192
193 /* vector for prediction of bottom field from top field */
194 DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
195 DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
196 }
197 else
198 {
199 /* vector for prediction of top field from bottom field */
200 DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
201 DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
202
203 /* vector for prediction of bottom field from top field */
204 DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0];
205 DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1;
206 }
207 }
208 else
209 {
210 /* vector for prediction from field of opposite 'parity' */
211 DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
212 DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
213
214 /* correct for vertical field shift */
215 if (pict_struct==TOP_FIELD)
216 DMV[0][1]--;
217 else
218 DMV[0][1]++;
219 }
220 }
221
222