Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1085 pj 1
/* motion.c, motion vector decoding                                         */
2
 
3
/* Copyright (C) 1996, 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 decode_motion_vector _ANSI_ARGS_((int *pred, int r_size, int motion_code,
37
  int motion_residualesidual, int full_pel_vector));
38
 
39
/* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */
40
void motion_vectors(PMV,dmvector,
41
  motion_vertical_field_select,s,motion_vector_count,mv_format,h_r_size,v_r_size,dmv,mvscale)
42
int PMV[2][2][2];
43
int dmvector[2];
44
int motion_vertical_field_select[2][2];
45
int s, motion_vector_count, mv_format, h_r_size, v_r_size, dmv, mvscale;
46
{
47
  if (motion_vector_count==1)
48
  {
49
    if (mv_format==MV_FIELD && !dmv)
50
    {
51
      motion_vertical_field_select[1][s] = motion_vertical_field_select[0][s] = Get_Bits(1);
52
#ifdef TRACE
53
      if (Trace_Flag)
54
      {
55
        printf("motion_vertical_field_select[][%d] (%d): %d\n",s,
56
          motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]);
57
      }
58
#endif /* TRACE */
59
    }
60
 
61
    motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
62
 
63
    /* update other motion vector predictors */
64
    PMV[1][s][0] = PMV[0][s][0];
65
    PMV[1][s][1] = PMV[0][s][1];
66
  }
67
  else
68
  {
69
    motion_vertical_field_select[0][s] = Get_Bits(1);
70
#ifdef TRACE
71
    if (Trace_Flag)
72
    {
73
      printf("motion_vertical_field_select[0][%d] (%d): %d\n",s,
74
        motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]);
75
    }
76
#endif /* TRACE */
77
    motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
78
 
79
    motion_vertical_field_select[1][s] = Get_Bits(1);
80
#ifdef TRACE
81
    if (Trace_Flag)
82
    {
83
      printf("motion_vertical_field_select[1][%d] (%d): %d\n",s,
84
        motion_vertical_field_select[1][s],motion_vertical_field_select[1][s]);
85
    }
86
#endif /* TRACE */
87
    motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
88
  }
89
}
90
 
91
/* get and decode motion vector and differential motion vector
92
   for one prediction */
93
void motion_vector(PMV,dmvector,
94
  h_r_size,v_r_size,dmv,mvscale,full_pel_vector)
95
int *PMV;
96
int *dmvector;
97
int h_r_size;
98
int v_r_size;
99
int dmv; /* MPEG-2 only: get differential motion vectors */
100
int mvscale; /* MPEG-2 only: field vector in frame pic */
101
int full_pel_vector; /* MPEG-1 only */
102
{
103
  int motion_code, motion_residual;
104
 
105
  /* horizontal component */
106
  /* ISO/IEC 13818-2 Table B-10 */
107
  motion_code = Get_motion_code();
108
 
109
  motion_residual = (h_r_size!=0 && motion_code!=0) ? Get_Bits(h_r_size) : 0;
110
 
111
#ifdef TRACE
112
  if (Trace_Flag)
113
  {
114
    if (h_r_size!=0 && motion_code!=0)
115
    {
116
      printf("motion_residual (");
117
      Print_Bits(motion_residual,h_r_size,h_r_size);
118
      printf("): %d\n",motion_residual);
119
    }
120
  }
121
#endif /* TRACE */
122
 
123
 
124
  decode_motion_vector(&PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector);
125
 
126
  if (dmv)
127
    dmvector[0] = Get_dmvector();
128
 
129
 
130
  /* vertical component */
131
  motion_code     = Get_motion_code();
132
  motion_residual = (v_r_size!=0 && motion_code!=0) ? Get_Bits(v_r_size) : 0;
133
 
134
#ifdef TRACE
135
  if (Trace_Flag)
136
  {
137
    if (v_r_size!=0 && motion_code!=0)
138
    {
139
      printf("motion_residual (");
140
      Print_Bits(motion_residual,v_r_size,v_r_size);
141
      printf("): %d\n",motion_residual);
142
    }
143
  }
144
#endif /* TRACE */
145
 
146
  if (mvscale)
147
    PMV[1] >>= 1; /* DIV 2 */
148
 
149
  decode_motion_vector(&PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector);
150
 
151
  if (mvscale)
152
    PMV[1] <<= 1;
153
 
154
  if (dmv)
155
    dmvector[1] = Get_dmvector();
156
 
157
#ifdef TRACE
158
  if (Trace_Flag)
159
    printf("PMV = %d,%d\n",PMV[0],PMV[1]);
160
#endif /* TRACE */
161
}
162
 
163
/* calculate motion vector component */
164
/* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */
165
/* Note: the arithmetic here is more elegant than that which is shown
166
   in 7.6.3.1.  The end results (PMV[][][]) should, however, be the same.  */
167
 
168
static void decode_motion_vector(pred,r_size,motion_code,motion_residual,full_pel_vector)
169
int *pred;
170
int r_size, motion_code, motion_residual;
171
int full_pel_vector; /* MPEG-1 (ISO/IEC 11172-1) support */
172
{
173
  int lim, vec;
174
 
175
  lim = 16<<r_size;
176
  vec = full_pel_vector ? (*pred >> 1) : (*pred);
177
 
178
  if (motion_code>0)
179
  {
180
    vec+= ((motion_code-1)<<r_size) + motion_residual + 1;
181
    if (vec>=lim)
182
      vec-= lim + lim;
183
  }
184
  else if (motion_code<0)
185
  {
186
    vec-= ((-motion_code-1)<<r_size) + motion_residual + 1;
187
    if (vec<-lim)
188
      vec+= lim + lim;
189
  }
190
  *pred = full_pel_vector ? (vec<<1) : vec;
191
}
192
 
193
 
194
/* ISO/IEC 13818-2 section 7.6.3.6: Dual prime additional arithmetic */
195
void Dual_Prime_Arithmetic(DMV,dmvector,mvx,mvy)
196
int DMV[][2];
197
int *dmvector; /* differential motion vector */
198
int mvx, mvy;  /* decoded mv components (always in field format) */
199
{
200
  if (picture_structure==FRAME_PICTURE)
201
  {
202
    if (top_field_first)
203
    {
204
      /* vector for prediction of top field from bottom field */
205
      DMV[0][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
206
      DMV[0][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] - 1;
207
 
208
      /* vector for prediction of bottom field from top field */
209
      DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
210
      DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1;
211
    }
212
    else
213
    {
214
      /* vector for prediction of top field from bottom field */
215
      DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0];
216
      DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1;
217
 
218
      /* vector for prediction of bottom field from top field */
219
      DMV[1][0] = ((mvx  +(mvx>0))>>1) + dmvector[0];
220
      DMV[1][1] = ((mvy  +(mvy>0))>>1) + dmvector[1] + 1;
221
    }
222
  }
223
  else
224
  {
225
    /* vector for prediction from field of opposite 'parity' */
226
    DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0];
227
    DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1];
228
 
229
    /* correct for vertical field shift */
230
    if (picture_structure==TOP_FIELD)
231
      DMV[0][1]--;
232
    else
233
      DMV[0][1]++;
234
  }
235
}
236