Subversion Repositories shark

Rev

Rev 1624 | Details | Compare with Previous | Last modification | View Log | RSS feed

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