1 |
14 |
jamey.hick |
|
2 |
|
|
/*!
|
3 |
|
|
***********************************************************************
|
4 |
|
|
* \file
|
5 |
|
|
* mbuffer.c
|
6 |
|
|
*
|
7 |
|
|
* \brief
|
8 |
|
|
* Frame buffer functions
|
9 |
|
|
*
|
10 |
|
|
* \author
|
11 |
|
|
* Main contributors (see contributors.h for copyright, address and affiliation details)
|
12 |
|
|
* - Karsten Sühring <suehring@hhi.de>
|
13 |
|
|
* - Alexis Tourapis <alexismt@ieee.org>
|
14 |
|
|
* - Jill Boyce <jill.boyce@thomson.net>
|
15 |
|
|
* - Saurav K Bandyopadhyay <saurav@ieee.org>
|
16 |
|
|
* - Zhenyu Wu <Zhenyu.Wu@thomson.net
|
17 |
|
|
* - Purvin Pandit <Purvin.Pandit@thomson.net>
|
18 |
|
|
*
|
19 |
|
|
***********************************************************************
|
20 |
|
|
*/
|
21 |
|
|
|
22 |
|
|
#include <stdlib.h>
|
23 |
|
|
#include <assert.h>
|
24 |
|
|
#include <limits.h>
|
25 |
|
|
#include <string.h>
|
26 |
|
|
|
27 |
|
|
#include "global.h"
|
28 |
|
|
#include "mbuffer.h"
|
29 |
|
|
#include "memalloc.h"
|
30 |
|
|
#include "output.h"
|
31 |
|
|
#include "image.h"
|
32 |
|
|
#include "header.h"
|
33 |
|
|
|
34 |
|
|
// picture error concealment
|
35 |
|
|
#include "erc_api.h"
|
36 |
|
|
|
37 |
|
|
static void insert_picture_in_dpb(FrameStore* fs, StorablePicture* p);
|
38 |
|
|
static void output_one_frame_from_dpb();
|
39 |
|
|
static int is_used_for_reference(FrameStore* fs);
|
40 |
|
|
static void get_smallest_poc(int *poc,int * pos);
|
41 |
|
|
static int remove_unused_frame_from_dpb();
|
42 |
|
|
static int is_short_term_reference(FrameStore* fs);
|
43 |
|
|
static int is_long_term_reference(FrameStore* fs);
|
44 |
|
|
void gen_field_ref_ids(StorablePicture *p);
|
45 |
|
|
|
46 |
|
|
DecodedPictureBuffer dpb;
|
47 |
|
|
|
48 |
|
|
StorablePicture **listX[6];
|
49 |
|
|
|
50 |
|
|
StorablePicture *no_reference_picture; //!< dummy storable picture for recovery point
|
51 |
|
|
|
52 |
|
|
ColocatedParams *Co_located = NULL;
|
53 |
|
|
|
54 |
|
|
extern StorablePicture *dec_picture;
|
55 |
|
|
|
56 |
|
|
int listXsize[6];
|
57 |
|
|
|
58 |
|
|
#define MAX_LIST_SIZE 33
|
59 |
|
|
|
60 |
|
|
/*!
|
61 |
|
|
************************************************************************
|
62 |
|
|
* \brief
|
63 |
|
|
* Print out list of pictures in DPB. Used for debug purposes.
|
64 |
|
|
************************************************************************
|
65 |
|
|
*/
|
66 |
|
|
void dump_dpb()
|
67 |
|
|
{
|
68 |
|
|
#if DUMP_DPB
|
69 |
|
|
unsigned i;
|
70 |
|
|
for (i=0; i<dpb.used_size;i++)
|
71 |
|
|
{
|
72 |
|
|
printf("(");
|
73 |
|
|
printf("fn=%d ", dpb.fs[i]->frame_num);
|
74 |
|
|
if (dpb.fs[i]->is_used & 1)
|
75 |
|
|
{
|
76 |
|
|
if (dpb.fs[i]->top_field)
|
77 |
|
|
printf("T: poc=%d ", dpb.fs[i]->top_field->poc);
|
78 |
|
|
else
|
79 |
|
|
printf("T: poc=%d ", dpb.fs[i]->frame->top_poc);
|
80 |
|
|
}
|
81 |
|
|
if (dpb.fs[i]->is_used & 2)
|
82 |
|
|
{
|
83 |
|
|
if (dpb.fs[i]->bottom_field)
|
84 |
|
|
printf("B: poc=%d ", dpb.fs[i]->bottom_field->poc);
|
85 |
|
|
else
|
86 |
|
|
printf("B: poc=%d ", dpb.fs[i]->frame->bottom_poc);
|
87 |
|
|
}
|
88 |
|
|
if (dpb.fs[i]->is_used == 3)
|
89 |
|
|
printf("F: poc=%d ", dpb.fs[i]->frame->poc);
|
90 |
|
|
printf("G: poc=%d) ", dpb.fs[i]->poc);
|
91 |
|
|
if (dpb.fs[i]->is_reference) printf ("ref (%d) ", dpb.fs[i]->is_reference);
|
92 |
|
|
if (dpb.fs[i]->is_long_term) printf ("lt_ref (%d) ", dpb.fs[i]->is_reference);
|
93 |
|
|
if (dpb.fs[i]->is_output) printf ("out ");
|
94 |
|
|
if (dpb.fs[i]->is_used == 3)
|
95 |
|
|
{
|
96 |
|
|
if (dpb.fs[i]->frame->non_existing) printf ("ne ");
|
97 |
|
|
}
|
98 |
|
|
printf ("\n");
|
99 |
|
|
}
|
100 |
|
|
#endif
|
101 |
|
|
}
|
102 |
|
|
|
103 |
|
|
/*!
|
104 |
|
|
************************************************************************
|
105 |
|
|
* \brief
|
106 |
|
|
* Returns the size of the dpb depending on level and picture size
|
107 |
|
|
*
|
108 |
|
|
*
|
109 |
|
|
************************************************************************
|
110 |
|
|
*/
|
111 |
|
|
int getDpbSize()
|
112 |
|
|
{
|
113 |
|
|
int pic_size = (active_sps->pic_width_in_mbs_minus1 + 1) * (active_sps->pic_height_in_map_units_minus1 + 1) * (active_sps->frame_mbs_only_flag?1:2) * 384;
|
114 |
|
|
|
115 |
|
|
int size = 0;
|
116 |
|
|
|
117 |
|
|
switch (active_sps->level_idc)
|
118 |
|
|
{
|
119 |
|
|
case 9:
|
120 |
|
|
size = 152064;
|
121 |
|
|
break;
|
122 |
|
|
case 10:
|
123 |
|
|
size = 152064;
|
124 |
|
|
break;
|
125 |
|
|
case 11:
|
126 |
|
|
if ((active_sps->profile_idc < FREXT_HP)&&(active_sps->constrained_set3_flag == 0))
|
127 |
|
|
size = 345600;
|
128 |
|
|
else
|
129 |
|
|
size = 152064;
|
130 |
|
|
break;
|
131 |
|
|
case 12:
|
132 |
|
|
size = 912384;
|
133 |
|
|
break;
|
134 |
|
|
case 13:
|
135 |
|
|
size = 912384;
|
136 |
|
|
break;
|
137 |
|
|
case 20:
|
138 |
|
|
size = 912384;
|
139 |
|
|
break;
|
140 |
|
|
case 21:
|
141 |
|
|
size = 1824768;
|
142 |
|
|
break;
|
143 |
|
|
case 22:
|
144 |
|
|
size = 3110400;
|
145 |
|
|
break;
|
146 |
|
|
case 30:
|
147 |
|
|
size = 3110400;
|
148 |
|
|
break;
|
149 |
|
|
case 31:
|
150 |
|
|
size = 6912000;
|
151 |
|
|
break;
|
152 |
|
|
case 32:
|
153 |
|
|
size = 7864320;
|
154 |
|
|
break;
|
155 |
|
|
case 40:
|
156 |
|
|
size = 12582912;
|
157 |
|
|
break;
|
158 |
|
|
case 41:
|
159 |
|
|
size = 12582912;
|
160 |
|
|
break;
|
161 |
|
|
case 42:
|
162 |
|
|
if( (active_sps->profile_idc==FREXT_HP ) || (active_sps->profile_idc==FREXT_Hi10P)
|
163 |
|
|
|| (active_sps->profile_idc==FREXT_Hi422) || (active_sps->profile_idc==FREXT_Hi444))
|
164 |
|
|
size = 13369344;
|
165 |
|
|
else
|
166 |
|
|
size = 12582912;
|
167 |
|
|
break;
|
168 |
|
|
case 50:
|
169 |
|
|
size = 42393600;
|
170 |
|
|
break;
|
171 |
|
|
case 51:
|
172 |
|
|
size = 70778880;
|
173 |
|
|
break;
|
174 |
|
|
default:
|
175 |
|
|
error ("undefined level", 500);
|
176 |
|
|
break;
|
177 |
|
|
}
|
178 |
|
|
|
179 |
|
|
size /= pic_size;
|
180 |
|
|
size = imin( size, 16);
|
181 |
|
|
|
182 |
|
|
if (active_sps->vui_parameters_present_flag && active_sps->vui_seq_parameters.bitstream_restriction_flag)
|
183 |
|
|
{
|
184 |
|
|
if ((int)active_sps->vui_seq_parameters.max_dec_frame_buffering > size)
|
185 |
|
|
{
|
186 |
|
|
error ("max_dec_frame_buffering larger than MaxDpbSize", 500);
|
187 |
|
|
}
|
188 |
|
|
size = imax (1, active_sps->vui_seq_parameters.max_dec_frame_buffering);
|
189 |
|
|
}
|
190 |
|
|
|
191 |
|
|
return size;
|
192 |
|
|
}
|
193 |
|
|
|
194 |
|
|
/*!
|
195 |
|
|
************************************************************************
|
196 |
|
|
* \brief
|
197 |
|
|
* Check then number of frames marked "used for reference" and break
|
198 |
|
|
* if maximum is exceeded
|
199 |
|
|
*
|
200 |
|
|
************************************************************************
|
201 |
|
|
*/
|
202 |
|
|
void check_num_ref()
|
203 |
|
|
{
|
204 |
|
|
if ((int)(dpb.ltref_frames_in_buffer + dpb.ref_frames_in_buffer ) > (imax(1,dpb.num_ref_frames)))
|
205 |
|
|
{
|
206 |
|
|
error ("Max. number of reference frames exceeded. Invalid stream.", 500);
|
207 |
|
|
}
|
208 |
|
|
}
|
209 |
|
|
|
210 |
|
|
|
211 |
|
|
/*!
|
212 |
|
|
************************************************************************
|
213 |
|
|
* \brief
|
214 |
|
|
* Allocate memory for decoded picture buffer and initialize with sane values.
|
215 |
|
|
*
|
216 |
|
|
************************************************************************
|
217 |
|
|
*/
|
218 |
|
|
void init_dpb()
|
219 |
|
|
{
|
220 |
|
|
unsigned i,j;
|
221 |
|
|
|
222 |
|
|
if (dpb.init_done)
|
223 |
|
|
{
|
224 |
|
|
free_dpb();
|
225 |
|
|
}
|
226 |
|
|
|
227 |
|
|
dpb.size = getDpbSize();
|
228 |
|
|
|
229 |
|
|
dpb.num_ref_frames = active_sps->num_ref_frames;
|
230 |
|
|
|
231 |
|
|
if (dpb.size < active_sps->num_ref_frames)
|
232 |
|
|
{
|
233 |
|
|
error ("DPB size at specified level is smaller than the specified number of reference frames. This is not allowed.\n", 1000);
|
234 |
|
|
}
|
235 |
|
|
|
236 |
|
|
dpb.used_size = 0;
|
237 |
|
|
dpb.last_picture = NULL;
|
238 |
|
|
|
239 |
|
|
dpb.ref_frames_in_buffer = 0;
|
240 |
|
|
dpb.ltref_frames_in_buffer = 0;
|
241 |
|
|
|
242 |
|
|
dpb.fs = calloc(dpb.size, sizeof (FrameStore*));
|
243 |
|
|
if (NULL==dpb.fs)
|
244 |
|
|
no_mem_exit("init_dpb: dpb->fs");
|
245 |
|
|
|
246 |
|
|
dpb.fs_ref = calloc(dpb.size, sizeof (FrameStore*));
|
247 |
|
|
if (NULL==dpb.fs_ref)
|
248 |
|
|
no_mem_exit("init_dpb: dpb->fs_ref");
|
249 |
|
|
|
250 |
|
|
dpb.fs_ltref = calloc(dpb.size, sizeof (FrameStore*));
|
251 |
|
|
if (NULL==dpb.fs_ltref)
|
252 |
|
|
no_mem_exit("init_dpb: dpb->fs_ltref");
|
253 |
|
|
|
254 |
|
|
for (i=0; i<dpb.size; i++)
|
255 |
|
|
{
|
256 |
|
|
dpb.fs[i] = alloc_frame_store();
|
257 |
|
|
dpb.fs_ref[i] = NULL;
|
258 |
|
|
dpb.fs_ltref[i] = NULL;
|
259 |
|
|
}
|
260 |
|
|
|
261 |
|
|
for (i=0; i<6; i++)
|
262 |
|
|
{
|
263 |
|
|
listX[i] = calloc(MAX_LIST_SIZE, sizeof (StorablePicture*)); // +1 for reordering
|
264 |
|
|
if (NULL==listX[i])
|
265 |
|
|
no_mem_exit("init_dpb: listX[i]");
|
266 |
|
|
}
|
267 |
|
|
|
268 |
|
|
/* allocate a dummy storable picture */
|
269 |
|
|
no_reference_picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
|
270 |
|
|
no_reference_picture->top_field = no_reference_picture;
|
271 |
|
|
no_reference_picture->bottom_field = no_reference_picture;
|
272 |
|
|
no_reference_picture->frame = no_reference_picture;
|
273 |
|
|
|
274 |
|
|
|
275 |
|
|
for (j=0;j<6;j++)
|
276 |
|
|
{
|
277 |
|
|
for (i=0; i<MAX_LIST_SIZE; i++)
|
278 |
|
|
{
|
279 |
|
|
listX[j][i] = NULL;
|
280 |
|
|
}
|
281 |
|
|
listXsize[j]=0;
|
282 |
|
|
}
|
283 |
|
|
|
284 |
|
|
dpb.last_output_poc = INT_MIN;
|
285 |
|
|
|
286 |
|
|
img->last_has_mmco_5 = 0;
|
287 |
|
|
|
288 |
|
|
dpb.init_done = 1;
|
289 |
|
|
|
290 |
|
|
// picture error concealment
|
291 |
|
|
if(img->conceal_mode !=0)
|
292 |
|
|
last_out_fs = alloc_frame_store();
|
293 |
|
|
}
|
294 |
|
|
/*!
|
295 |
|
|
************************************************************************
|
296 |
|
|
* \brief
|
297 |
|
|
* Free memory for decoded picture buffer.
|
298 |
|
|
************************************************************************
|
299 |
|
|
*/
|
300 |
|
|
void free_dpb()
|
301 |
|
|
{
|
302 |
|
|
unsigned i;
|
303 |
|
|
if (dpb.fs)
|
304 |
|
|
{
|
305 |
|
|
for (i=0; i<dpb.size; i++)
|
306 |
|
|
{
|
307 |
|
|
free_frame_store(dpb.fs[i]);
|
308 |
|
|
}
|
309 |
|
|
free (dpb.fs);
|
310 |
|
|
dpb.fs=NULL;
|
311 |
|
|
}
|
312 |
|
|
if (dpb.fs_ref)
|
313 |
|
|
{
|
314 |
|
|
free (dpb.fs_ref);
|
315 |
|
|
}
|
316 |
|
|
if (dpb.fs_ltref)
|
317 |
|
|
{
|
318 |
|
|
free (dpb.fs_ltref);
|
319 |
|
|
}
|
320 |
|
|
dpb.last_output_poc = INT_MIN;
|
321 |
|
|
|
322 |
|
|
for (i=0; i<6; i++)
|
323 |
|
|
if (listX[i])
|
324 |
|
|
{
|
325 |
|
|
free (listX[i]);
|
326 |
|
|
listX[i] = NULL;
|
327 |
|
|
}
|
328 |
|
|
|
329 |
|
|
dpb.init_done = 0;
|
330 |
|
|
|
331 |
|
|
// picture error concealment
|
332 |
|
|
if(img->conceal_mode != 0)
|
333 |
|
|
free_frame_store(last_out_fs);
|
334 |
|
|
|
335 |
|
|
free_storable_picture(no_reference_picture);
|
336 |
|
|
}
|
337 |
|
|
|
338 |
|
|
|
339 |
|
|
/*!
|
340 |
|
|
************************************************************************
|
341 |
|
|
* \brief
|
342 |
|
|
* Allocate memory for decoded picture buffer frame stores an initialize with sane values.
|
343 |
|
|
*
|
344 |
|
|
* \return
|
345 |
|
|
* the allocated FrameStore structure
|
346 |
|
|
************************************************************************
|
347 |
|
|
*/
|
348 |
|
|
FrameStore* alloc_frame_store()
|
349 |
|
|
{
|
350 |
|
|
FrameStore *f;
|
351 |
|
|
|
352 |
|
|
f = calloc (1, sizeof(FrameStore));
|
353 |
|
|
if (NULL==f)
|
354 |
|
|
no_mem_exit("alloc_frame_store: f");
|
355 |
|
|
|
356 |
|
|
f->is_used = 0;
|
357 |
|
|
f->is_reference = 0;
|
358 |
|
|
f->is_long_term = 0;
|
359 |
|
|
f->is_orig_reference = 0;
|
360 |
|
|
|
361 |
|
|
f->is_output = 0;
|
362 |
|
|
|
363 |
|
|
f->frame = NULL;;
|
364 |
|
|
f->top_field = NULL;
|
365 |
|
|
f->bottom_field = NULL;
|
366 |
|
|
|
367 |
|
|
return f;
|
368 |
|
|
}
|
369 |
|
|
|
370 |
|
|
/*!
|
371 |
|
|
************************************************************************
|
372 |
|
|
* \brief
|
373 |
|
|
* Allocate memory for a stored picture.
|
374 |
|
|
*
|
375 |
|
|
* \param structure
|
376 |
|
|
* picture structure
|
377 |
|
|
* \param size_x
|
378 |
|
|
* horizontal luma size
|
379 |
|
|
* \param size_y
|
380 |
|
|
* vertical luma size
|
381 |
|
|
* \param size_x_cr
|
382 |
|
|
* horizontal chroma size
|
383 |
|
|
* \param size_y_cr
|
384 |
|
|
* vertical chroma size
|
385 |
|
|
*
|
386 |
|
|
* \return
|
387 |
|
|
* the allocated StorablePicture structure
|
388 |
|
|
************************************************************************
|
389 |
|
|
*/
|
390 |
|
|
StorablePicture* alloc_storable_picture(PictureStructure structure, int size_x, int size_y, int size_x_cr, int size_y_cr)
|
391 |
|
|
{
|
392 |
|
|
StorablePicture *s;
|
393 |
|
|
|
394 |
|
|
//printf ("Allocating (%s) picture (x=%d, y=%d, x_cr=%d, y_cr=%d)\n", (type == FRAME)?"FRAME":(type == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", size_x, size_y, size_x_cr, size_y_cr);
|
395 |
|
|
|
396 |
|
|
s = calloc (1, sizeof(StorablePicture));
|
397 |
|
|
if (NULL==s)
|
398 |
|
|
no_mem_exit("alloc_storable_picture: s");
|
399 |
|
|
|
400 |
|
|
if (structure!=FRAME)
|
401 |
|
|
{
|
402 |
|
|
size_y /= 2;
|
403 |
|
|
size_y_cr /= 2;
|
404 |
|
|
}
|
405 |
|
|
|
406 |
|
|
s->PicSizeInMbs = (size_x*size_y)/256;
|
407 |
|
|
s->imgUV = NULL;
|
408 |
|
|
|
409 |
|
|
get_mem2Dpel (&(s->imgY), size_y, size_x);
|
410 |
|
|
if (active_sps->chroma_format_idc != YUV400)
|
411 |
|
|
get_mem3Dpel (&(s->imgUV), 2, size_y_cr, size_x_cr);
|
412 |
|
|
|
413 |
|
|
s->mb_field = calloc (s->PicSizeInMbs, sizeof(int));
|
414 |
|
|
if (NULL==s->mb_field)
|
415 |
|
|
no_mem_exit("alloc_storable_picture: s->mb_field");
|
416 |
|
|
|
417 |
|
|
get_mem2Dshort (&(s->slice_id), size_y / MB_BLOCK_SIZE, size_x / MB_BLOCK_SIZE);
|
418 |
|
|
|
419 |
|
|
get_mem3D ((byte****)(&(s->ref_idx)) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
420 |
|
|
get_mem3Dint64 (&(s->ref_pic_id), 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
421 |
|
|
get_mem3Dint64 (&(s->ref_id) , 6, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
422 |
|
|
get_mem4Dshort (&(s->mv) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE, 2);
|
423 |
|
|
|
424 |
|
|
get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
425 |
|
|
get_mem2D (&(s->field_frame) , size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
426 |
|
|
|
427 |
|
|
s->pic_num=0;
|
428 |
|
|
s->frame_num=0;
|
429 |
|
|
s->long_term_frame_idx=0;
|
430 |
|
|
s->long_term_pic_num=0;
|
431 |
|
|
s->used_for_reference=0;
|
432 |
|
|
s->is_long_term=0;
|
433 |
|
|
s->non_existing=0;
|
434 |
|
|
s->is_output = 0;
|
435 |
|
|
s->max_slice_id = 0;
|
436 |
|
|
|
437 |
|
|
s->structure=structure;
|
438 |
|
|
|
439 |
|
|
s->size_x = size_x;
|
440 |
|
|
s->size_y = size_y;
|
441 |
|
|
s->size_x_cr = size_x_cr;
|
442 |
|
|
s->size_y_cr = size_y_cr;
|
443 |
|
|
s->size_x_m1 = size_x - 1;
|
444 |
|
|
s->size_y_m1 = size_y - 1;
|
445 |
|
|
s->size_x_cr_m1 = size_x_cr - 1;
|
446 |
|
|
s->size_y_cr_m1 = size_y_cr - 1;
|
447 |
|
|
|
448 |
|
|
// s->top_field = NULL;
|
449 |
|
|
// s->bottom_field = NULL;
|
450 |
|
|
// s->frame = NULL;
|
451 |
|
|
s->top_field = no_reference_picture;
|
452 |
|
|
s->bottom_field = no_reference_picture;
|
453 |
|
|
s->frame = no_reference_picture;
|
454 |
|
|
|
455 |
|
|
s->dec_ref_pic_marking_buffer = NULL;
|
456 |
|
|
|
457 |
|
|
s->coded_frame = 0;
|
458 |
|
|
s->MbaffFrameFlag = 0;
|
459 |
|
|
|
460 |
|
|
s->top_poc = s->bottom_poc = s->poc = 0;
|
461 |
|
|
|
462 |
|
|
return s;
|
463 |
|
|
}
|
464 |
|
|
|
465 |
|
|
/*!
|
466 |
|
|
************************************************************************
|
467 |
|
|
* \brief
|
468 |
|
|
* Free frame store memory.
|
469 |
|
|
*
|
470 |
|
|
* \param f
|
471 |
|
|
* FrameStore to be freed
|
472 |
|
|
*
|
473 |
|
|
************************************************************************
|
474 |
|
|
*/
|
475 |
|
|
void free_frame_store(FrameStore* f)
|
476 |
|
|
{
|
477 |
|
|
if (f)
|
478 |
|
|
{
|
479 |
|
|
if (f->frame)
|
480 |
|
|
{
|
481 |
|
|
free_storable_picture(f->frame);
|
482 |
|
|
f->frame=NULL;
|
483 |
|
|
}
|
484 |
|
|
if (f->top_field)
|
485 |
|
|
{
|
486 |
|
|
free_storable_picture(f->top_field);
|
487 |
|
|
f->top_field=NULL;
|
488 |
|
|
}
|
489 |
|
|
if (f->bottom_field)
|
490 |
|
|
{
|
491 |
|
|
free_storable_picture(f->bottom_field);
|
492 |
|
|
f->bottom_field=NULL;
|
493 |
|
|
}
|
494 |
|
|
free(f);
|
495 |
|
|
}
|
496 |
|
|
}
|
497 |
|
|
|
498 |
|
|
/*!
|
499 |
|
|
************************************************************************
|
500 |
|
|
* \brief
|
501 |
|
|
* Free picture memory.
|
502 |
|
|
*
|
503 |
|
|
* \param p
|
504 |
|
|
* Picture to be freed
|
505 |
|
|
*
|
506 |
|
|
************************************************************************
|
507 |
|
|
*/
|
508 |
|
|
void free_storable_picture(StorablePicture* p)
|
509 |
|
|
{
|
510 |
|
|
if (p)
|
511 |
|
|
{
|
512 |
|
|
if (p->ref_idx)
|
513 |
|
|
{
|
514 |
|
|
free_mem3D ((byte***)p->ref_idx, 2);
|
515 |
|
|
p->ref_idx = NULL;
|
516 |
|
|
}
|
517 |
|
|
|
518 |
|
|
if (p->ref_pic_id)
|
519 |
|
|
{
|
520 |
|
|
free_mem3Dint64 (p->ref_pic_id, 6);
|
521 |
|
|
p->ref_pic_id = NULL;
|
522 |
|
|
}
|
523 |
|
|
if (p->ref_id)
|
524 |
|
|
{
|
525 |
|
|
free_mem3Dint64 (p->ref_id, 6);
|
526 |
|
|
p->ref_id = NULL;
|
527 |
|
|
}
|
528 |
|
|
if (p->mv)
|
529 |
|
|
{
|
530 |
|
|
free_mem4Dshort (p->mv, 2, p->size_y / BLOCK_SIZE);
|
531 |
|
|
p->mv = NULL;
|
532 |
|
|
}
|
533 |
|
|
|
534 |
|
|
if (p->moving_block)
|
535 |
|
|
{
|
536 |
|
|
free_mem2D (p->moving_block);
|
537 |
|
|
p->moving_block=NULL;
|
538 |
|
|
}
|
539 |
|
|
|
540 |
|
|
if (p->field_frame)
|
541 |
|
|
{
|
542 |
|
|
free_mem2D (p->field_frame);
|
543 |
|
|
p->field_frame=NULL;
|
544 |
|
|
}
|
545 |
|
|
|
546 |
|
|
|
547 |
|
|
if (p->imgY)
|
548 |
|
|
{
|
549 |
|
|
free_mem2Dpel (p->imgY);
|
550 |
|
|
p->imgY=NULL;
|
551 |
|
|
}
|
552 |
|
|
if (p->imgUV)
|
553 |
|
|
{
|
554 |
|
|
free_mem3Dpel (p->imgUV, 2);
|
555 |
|
|
p->imgUV=NULL;
|
556 |
|
|
}
|
557 |
|
|
|
558 |
|
|
if (p->mb_field)
|
559 |
|
|
{
|
560 |
|
|
free(p->mb_field);
|
561 |
|
|
p->mb_field=NULL;
|
562 |
|
|
}
|
563 |
|
|
|
564 |
|
|
if (p->slice_id)
|
565 |
|
|
{
|
566 |
|
|
free_mem2Dshort(p->slice_id);
|
567 |
|
|
p->slice_id=NULL;
|
568 |
|
|
}
|
569 |
|
|
|
570 |
|
|
free(p);
|
571 |
|
|
p = NULL;
|
572 |
|
|
}
|
573 |
|
|
}
|
574 |
|
|
|
575 |
|
|
/*!
|
576 |
|
|
************************************************************************
|
577 |
|
|
* \brief
|
578 |
|
|
* mark FrameStore unused for reference
|
579 |
|
|
*
|
580 |
|
|
************************************************************************
|
581 |
|
|
*/
|
582 |
|
|
static void unmark_for_reference(FrameStore* fs)
|
583 |
|
|
{
|
584 |
|
|
|
585 |
|
|
if (fs->is_used & 1)
|
586 |
|
|
{
|
587 |
|
|
if (fs->top_field)
|
588 |
|
|
{
|
589 |
|
|
fs->top_field->used_for_reference = 0;
|
590 |
|
|
}
|
591 |
|
|
}
|
592 |
|
|
if (fs->is_used & 2)
|
593 |
|
|
{
|
594 |
|
|
if (fs->bottom_field)
|
595 |
|
|
{
|
596 |
|
|
fs->bottom_field->used_for_reference = 0;
|
597 |
|
|
}
|
598 |
|
|
}
|
599 |
|
|
if (fs->is_used == 3)
|
600 |
|
|
{
|
601 |
|
|
if (fs->top_field && fs->bottom_field)
|
602 |
|
|
{
|
603 |
|
|
fs->top_field->used_for_reference = 0;
|
604 |
|
|
fs->bottom_field->used_for_reference = 0;
|
605 |
|
|
}
|
606 |
|
|
fs->frame->used_for_reference = 0;
|
607 |
|
|
}
|
608 |
|
|
|
609 |
|
|
fs->is_reference = 0;
|
610 |
|
|
|
611 |
|
|
if(fs->frame)
|
612 |
|
|
{
|
613 |
|
|
if (fs->frame->ref_pic_id)
|
614 |
|
|
{
|
615 |
|
|
free_mem3Dint64 (fs->frame->ref_pic_id, 6);
|
616 |
|
|
fs->frame->ref_pic_id = NULL;
|
617 |
|
|
}
|
618 |
|
|
if (fs->frame->ref_id)
|
619 |
|
|
{
|
620 |
|
|
free_mem3Dint64 (fs->frame->ref_id, 6);
|
621 |
|
|
fs->frame->ref_id = NULL;
|
622 |
|
|
}
|
623 |
|
|
}
|
624 |
|
|
|
625 |
|
|
if (fs->top_field)
|
626 |
|
|
{
|
627 |
|
|
if (fs->top_field->ref_pic_id)
|
628 |
|
|
{
|
629 |
|
|
free_mem3Dint64 (fs->top_field->ref_pic_id, 6);
|
630 |
|
|
fs->top_field->ref_pic_id = NULL;
|
631 |
|
|
}
|
632 |
|
|
if (fs->top_field->ref_id)
|
633 |
|
|
{
|
634 |
|
|
free_mem3Dint64 (fs->top_field->ref_id, 6);
|
635 |
|
|
fs->top_field->ref_id = NULL;
|
636 |
|
|
}
|
637 |
|
|
|
638 |
|
|
}
|
639 |
|
|
if (fs->bottom_field)
|
640 |
|
|
{
|
641 |
|
|
if (fs->bottom_field->ref_pic_id)
|
642 |
|
|
{
|
643 |
|
|
free_mem3Dint64 (fs->bottom_field->ref_pic_id, 6);
|
644 |
|
|
fs->bottom_field->ref_pic_id = NULL;
|
645 |
|
|
}
|
646 |
|
|
if (fs->bottom_field->ref_id)
|
647 |
|
|
{
|
648 |
|
|
free_mem3Dint64 (fs->bottom_field->ref_id, 6);
|
649 |
|
|
fs->bottom_field->ref_id = NULL;
|
650 |
|
|
}
|
651 |
|
|
}
|
652 |
|
|
|
653 |
|
|
}
|
654 |
|
|
|
655 |
|
|
|
656 |
|
|
/*!
|
657 |
|
|
************************************************************************
|
658 |
|
|
* \brief
|
659 |
|
|
* mark FrameStore unused for reference and reset long term flags
|
660 |
|
|
*
|
661 |
|
|
************************************************************************
|
662 |
|
|
*/
|
663 |
|
|
static void unmark_for_long_term_reference(FrameStore* fs)
|
664 |
|
|
{
|
665 |
|
|
|
666 |
|
|
if (fs->is_used & 1)
|
667 |
|
|
{
|
668 |
|
|
if (fs->top_field)
|
669 |
|
|
{
|
670 |
|
|
fs->top_field->used_for_reference = 0;
|
671 |
|
|
fs->top_field->is_long_term = 0;
|
672 |
|
|
}
|
673 |
|
|
}
|
674 |
|
|
if (fs->is_used & 2)
|
675 |
|
|
{
|
676 |
|
|
if (fs->bottom_field)
|
677 |
|
|
{
|
678 |
|
|
fs->bottom_field->used_for_reference = 0;
|
679 |
|
|
fs->bottom_field->is_long_term = 0;
|
680 |
|
|
}
|
681 |
|
|
}
|
682 |
|
|
if (fs->is_used == 3)
|
683 |
|
|
{
|
684 |
|
|
if (fs->top_field && fs->bottom_field)
|
685 |
|
|
{
|
686 |
|
|
fs->top_field->used_for_reference = 0;
|
687 |
|
|
fs->top_field->is_long_term = 0;
|
688 |
|
|
fs->bottom_field->used_for_reference = 0;
|
689 |
|
|
fs->bottom_field->is_long_term = 0;
|
690 |
|
|
}
|
691 |
|
|
fs->frame->used_for_reference = 0;
|
692 |
|
|
fs->frame->is_long_term = 0;
|
693 |
|
|
}
|
694 |
|
|
|
695 |
|
|
fs->is_reference = 0;
|
696 |
|
|
fs->is_long_term = 0;
|
697 |
|
|
}
|
698 |
|
|
|
699 |
|
|
|
700 |
|
|
/*!
|
701 |
|
|
************************************************************************
|
702 |
|
|
* \brief
|
703 |
|
|
* compares two stored pictures by picture number for qsort in descending order
|
704 |
|
|
*
|
705 |
|
|
************************************************************************
|
706 |
|
|
*/
|
707 |
|
|
static int compare_pic_by_pic_num_desc( const void *arg1, const void *arg2 )
|
708 |
|
|
{
|
709 |
|
|
if ( (*(StorablePicture**)arg1)->pic_num < (*(StorablePicture**)arg2)->pic_num)
|
710 |
|
|
return 1;
|
711 |
|
|
if ( (*(StorablePicture**)arg1)->pic_num > (*(StorablePicture**)arg2)->pic_num)
|
712 |
|
|
return -1;
|
713 |
|
|
else
|
714 |
|
|
return 0;
|
715 |
|
|
}
|
716 |
|
|
|
717 |
|
|
/*!
|
718 |
|
|
************************************************************************
|
719 |
|
|
* \brief
|
720 |
|
|
* compares two stored pictures by picture number for qsort in descending order
|
721 |
|
|
*
|
722 |
|
|
************************************************************************
|
723 |
|
|
*/
|
724 |
|
|
static int compare_pic_by_lt_pic_num_asc( const void *arg1, const void *arg2 )
|
725 |
|
|
{
|
726 |
|
|
if ( (*(StorablePicture**)arg1)->long_term_pic_num < (*(StorablePicture**)arg2)->long_term_pic_num)
|
727 |
|
|
return -1;
|
728 |
|
|
if ( (*(StorablePicture**)arg1)->long_term_pic_num > (*(StorablePicture**)arg2)->long_term_pic_num)
|
729 |
|
|
return 1;
|
730 |
|
|
else
|
731 |
|
|
return 0;
|
732 |
|
|
}
|
733 |
|
|
|
734 |
|
|
/*!
|
735 |
|
|
************************************************************************
|
736 |
|
|
* \brief
|
737 |
|
|
* compares two frame stores by pic_num for qsort in descending order
|
738 |
|
|
*
|
739 |
|
|
************************************************************************
|
740 |
|
|
*/
|
741 |
|
|
static int compare_fs_by_frame_num_desc( const void *arg1, const void *arg2 )
|
742 |
|
|
{
|
743 |
|
|
if ( (*(FrameStore**)arg1)->frame_num_wrap < (*(FrameStore**)arg2)->frame_num_wrap)
|
744 |
|
|
return 1;
|
745 |
|
|
if ( (*(FrameStore**)arg1)->frame_num_wrap > (*(FrameStore**)arg2)->frame_num_wrap)
|
746 |
|
|
return -1;
|
747 |
|
|
else
|
748 |
|
|
return 0;
|
749 |
|
|
}
|
750 |
|
|
|
751 |
|
|
|
752 |
|
|
/*!
|
753 |
|
|
************************************************************************
|
754 |
|
|
* \brief
|
755 |
|
|
* compares two frame stores by lt_pic_num for qsort in descending order
|
756 |
|
|
*
|
757 |
|
|
************************************************************************
|
758 |
|
|
*/
|
759 |
|
|
static int compare_fs_by_lt_pic_idx_asc( const void *arg1, const void *arg2 )
|
760 |
|
|
{
|
761 |
|
|
if ( (*(FrameStore**)arg1)->long_term_frame_idx < (*(FrameStore**)arg2)->long_term_frame_idx)
|
762 |
|
|
return -1;
|
763 |
|
|
if ( (*(FrameStore**)arg1)->long_term_frame_idx > (*(FrameStore**)arg2)->long_term_frame_idx)
|
764 |
|
|
return 1;
|
765 |
|
|
else
|
766 |
|
|
return 0;
|
767 |
|
|
}
|
768 |
|
|
|
769 |
|
|
|
770 |
|
|
/*!
|
771 |
|
|
************************************************************************
|
772 |
|
|
* \brief
|
773 |
|
|
* compares two stored pictures by poc for qsort in ascending order
|
774 |
|
|
*
|
775 |
|
|
************************************************************************
|
776 |
|
|
*/
|
777 |
|
|
static int compare_pic_by_poc_asc( const void *arg1, const void *arg2 )
|
778 |
|
|
{
|
779 |
|
|
if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
|
780 |
|
|
return -1;
|
781 |
|
|
if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
|
782 |
|
|
return 1;
|
783 |
|
|
else
|
784 |
|
|
return 0;
|
785 |
|
|
}
|
786 |
|
|
|
787 |
|
|
|
788 |
|
|
/*!
|
789 |
|
|
************************************************************************
|
790 |
|
|
* \brief
|
791 |
|
|
* compares two stored pictures by poc for qsort in descending order
|
792 |
|
|
*
|
793 |
|
|
************************************************************************
|
794 |
|
|
*/
|
795 |
|
|
static int compare_pic_by_poc_desc( const void *arg1, const void *arg2 )
|
796 |
|
|
{
|
797 |
|
|
if ( (*(StorablePicture**)arg1)->poc < (*(StorablePicture**)arg2)->poc)
|
798 |
|
|
return 1;
|
799 |
|
|
if ( (*(StorablePicture**)arg1)->poc > (*(StorablePicture**)arg2)->poc)
|
800 |
|
|
return -1;
|
801 |
|
|
else
|
802 |
|
|
return 0;
|
803 |
|
|
}
|
804 |
|
|
|
805 |
|
|
|
806 |
|
|
/*!
|
807 |
|
|
************************************************************************
|
808 |
|
|
* \brief
|
809 |
|
|
* compares two frame stores by poc for qsort in ascending order
|
810 |
|
|
*
|
811 |
|
|
************************************************************************
|
812 |
|
|
*/
|
813 |
|
|
static int compare_fs_by_poc_asc( const void *arg1, const void *arg2 )
|
814 |
|
|
{
|
815 |
|
|
if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
|
816 |
|
|
return -1;
|
817 |
|
|
if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
|
818 |
|
|
return 1;
|
819 |
|
|
else
|
820 |
|
|
return 0;
|
821 |
|
|
}
|
822 |
|
|
|
823 |
|
|
|
824 |
|
|
/*!
|
825 |
|
|
************************************************************************
|
826 |
|
|
* \brief
|
827 |
|
|
* compares two frame stores by poc for qsort in descending order
|
828 |
|
|
*
|
829 |
|
|
************************************************************************
|
830 |
|
|
*/
|
831 |
|
|
static int compare_fs_by_poc_desc( const void *arg1, const void *arg2 )
|
832 |
|
|
{
|
833 |
|
|
if ( (*(FrameStore**)arg1)->poc < (*(FrameStore**)arg2)->poc)
|
834 |
|
|
return 1;
|
835 |
|
|
if ( (*(FrameStore**)arg1)->poc > (*(FrameStore**)arg2)->poc)
|
836 |
|
|
return -1;
|
837 |
|
|
else
|
838 |
|
|
return 0;
|
839 |
|
|
}
|
840 |
|
|
|
841 |
|
|
|
842 |
|
|
/*!
|
843 |
|
|
************************************************************************
|
844 |
|
|
* \brief
|
845 |
|
|
* returns true, if picture is short term reference picture
|
846 |
|
|
*
|
847 |
|
|
************************************************************************
|
848 |
|
|
*/
|
849 |
|
|
int is_short_ref(StorablePicture *s)
|
850 |
|
|
{
|
851 |
|
|
return ((s->used_for_reference) && (!(s->is_long_term)));
|
852 |
|
|
}
|
853 |
|
|
|
854 |
|
|
|
855 |
|
|
/*!
|
856 |
|
|
************************************************************************
|
857 |
|
|
* \brief
|
858 |
|
|
* returns true, if picture is long term reference picture
|
859 |
|
|
*
|
860 |
|
|
************************************************************************
|
861 |
|
|
*/
|
862 |
|
|
int is_long_ref(StorablePicture *s)
|
863 |
|
|
{
|
864 |
|
|
return ((s->used_for_reference) && (s->is_long_term));
|
865 |
|
|
}
|
866 |
|
|
|
867 |
|
|
|
868 |
|
|
/*!
|
869 |
|
|
************************************************************************
|
870 |
|
|
* \brief
|
871 |
|
|
* Generates a alternating field list from a given FrameStore list
|
872 |
|
|
*
|
873 |
|
|
************************************************************************
|
874 |
|
|
*/
|
875 |
|
|
static void gen_pic_list_from_frame_list(PictureStructure currStrcture, FrameStore **fs_list, int list_idx, StorablePicture **list, int *list_size, int long_term)
|
876 |
|
|
{
|
877 |
|
|
int top_idx = 0;
|
878 |
|
|
int bot_idx = 0;
|
879 |
|
|
|
880 |
|
|
int (*is_ref)(StorablePicture *s);
|
881 |
|
|
|
882 |
|
|
if (long_term)
|
883 |
|
|
is_ref=is_long_ref;
|
884 |
|
|
else
|
885 |
|
|
is_ref=is_short_ref;
|
886 |
|
|
|
887 |
|
|
if (currStrcture == TOP_FIELD)
|
888 |
|
|
{
|
889 |
|
|
while ((top_idx<list_idx)||(bot_idx<list_idx))
|
890 |
|
|
{
|
891 |
|
|
for ( ; top_idx<list_idx; top_idx++)
|
892 |
|
|
{
|
893 |
|
|
if(fs_list[top_idx]->is_used & 1)
|
894 |
|
|
{
|
895 |
|
|
if(is_ref(fs_list[top_idx]->top_field))
|
896 |
|
|
{
|
897 |
|
|
// short term ref pic
|
898 |
|
|
list[*list_size] = fs_list[top_idx]->top_field;
|
899 |
|
|
(*list_size)++;
|
900 |
|
|
top_idx++;
|
901 |
|
|
break;
|
902 |
|
|
}
|
903 |
|
|
}
|
904 |
|
|
}
|
905 |
|
|
for ( ; bot_idx<list_idx; bot_idx++)
|
906 |
|
|
{
|
907 |
|
|
if(fs_list[bot_idx]->is_used & 2)
|
908 |
|
|
{
|
909 |
|
|
if(is_ref(fs_list[bot_idx]->bottom_field))
|
910 |
|
|
{
|
911 |
|
|
// short term ref pic
|
912 |
|
|
list[*list_size] = fs_list[bot_idx]->bottom_field;
|
913 |
|
|
(*list_size)++;
|
914 |
|
|
bot_idx++;
|
915 |
|
|
break;
|
916 |
|
|
}
|
917 |
|
|
}
|
918 |
|
|
}
|
919 |
|
|
}
|
920 |
|
|
}
|
921 |
|
|
if (currStrcture == BOTTOM_FIELD)
|
922 |
|
|
{
|
923 |
|
|
while ((top_idx<list_idx)||(bot_idx<list_idx))
|
924 |
|
|
{
|
925 |
|
|
for ( ; bot_idx<list_idx; bot_idx++)
|
926 |
|
|
{
|
927 |
|
|
if(fs_list[bot_idx]->is_used & 2)
|
928 |
|
|
{
|
929 |
|
|
if(is_ref(fs_list[bot_idx]->bottom_field))
|
930 |
|
|
{
|
931 |
|
|
// short term ref pic
|
932 |
|
|
list[*list_size] = fs_list[bot_idx]->bottom_field;
|
933 |
|
|
(*list_size)++;
|
934 |
|
|
bot_idx++;
|
935 |
|
|
break;
|
936 |
|
|
}
|
937 |
|
|
}
|
938 |
|
|
}
|
939 |
|
|
for ( ; top_idx<list_idx; top_idx++)
|
940 |
|
|
{
|
941 |
|
|
if(fs_list[top_idx]->is_used & 1)
|
942 |
|
|
{
|
943 |
|
|
if(is_ref(fs_list[top_idx]->top_field))
|
944 |
|
|
{
|
945 |
|
|
// short term ref pic
|
946 |
|
|
list[*list_size] = fs_list[top_idx]->top_field;
|
947 |
|
|
(*list_size)++;
|
948 |
|
|
top_idx++;
|
949 |
|
|
break;
|
950 |
|
|
}
|
951 |
|
|
}
|
952 |
|
|
}
|
953 |
|
|
}
|
954 |
|
|
}
|
955 |
|
|
}
|
956 |
|
|
|
957 |
|
|
|
958 |
|
|
/*!
|
959 |
|
|
************************************************************************
|
960 |
|
|
* \brief
|
961 |
|
|
* Initialize listX[0] and list 1 depending on current picture type
|
962 |
|
|
*
|
963 |
|
|
************************************************************************
|
964 |
|
|
*/
|
965 |
|
|
void init_lists(int currSliceType, PictureStructure currPicStructure)
|
966 |
|
|
{
|
967 |
|
|
int add_top = 0, add_bottom = 0;
|
968 |
|
|
unsigned i;
|
969 |
|
|
int j;
|
970 |
|
|
int MaxFrameNum = 1 << (active_sps->log2_max_frame_num_minus4 + 4);
|
971 |
|
|
int diff;
|
972 |
|
|
|
973 |
|
|
int list0idx = 0;
|
974 |
|
|
int list0idx_1 = 0;
|
975 |
|
|
int listltidx = 0;
|
976 |
|
|
|
977 |
|
|
FrameStore **fs_list0;
|
978 |
|
|
FrameStore **fs_list1;
|
979 |
|
|
FrameStore **fs_listlt;
|
980 |
|
|
|
981 |
|
|
StorablePicture *tmp_s;
|
982 |
|
|
|
983 |
|
|
if (currPicStructure == FRAME)
|
984 |
|
|
{
|
985 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
986 |
|
|
{
|
987 |
|
|
if (dpb.fs_ref[i]->is_used==3)
|
988 |
|
|
{
|
989 |
|
|
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
|
990 |
|
|
{
|
991 |
|
|
if( dpb.fs_ref[i]->frame_num > img->frame_num )
|
992 |
|
|
{
|
993 |
|
|
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - MaxFrameNum;
|
994 |
|
|
}
|
995 |
|
|
else
|
996 |
|
|
{
|
997 |
|
|
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
|
998 |
|
|
}
|
999 |
|
|
dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
|
1000 |
|
|
}
|
1001 |
|
|
}
|
1002 |
|
|
}
|
1003 |
|
|
// update long_term_pic_num
|
1004 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1005 |
|
|
{
|
1006 |
|
|
if (dpb.fs_ltref[i]->is_used==3)
|
1007 |
|
|
{
|
1008 |
|
|
if (dpb.fs_ltref[i]->frame->is_long_term)
|
1009 |
|
|
{
|
1010 |
|
|
dpb.fs_ltref[i]->frame->long_term_pic_num = dpb.fs_ltref[i]->frame->long_term_frame_idx;
|
1011 |
|
|
}
|
1012 |
|
|
}
|
1013 |
|
|
}
|
1014 |
|
|
}
|
1015 |
|
|
else
|
1016 |
|
|
{
|
1017 |
|
|
if (currPicStructure == TOP_FIELD)
|
1018 |
|
|
{
|
1019 |
|
|
add_top = 1;
|
1020 |
|
|
add_bottom = 0;
|
1021 |
|
|
}
|
1022 |
|
|
else
|
1023 |
|
|
{
|
1024 |
|
|
add_top = 0;
|
1025 |
|
|
add_bottom = 1;
|
1026 |
|
|
}
|
1027 |
|
|
|
1028 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1029 |
|
|
{
|
1030 |
|
|
if (dpb.fs_ref[i]->is_reference)
|
1031 |
|
|
{
|
1032 |
|
|
if( dpb.fs_ref[i]->frame_num > img->frame_num )
|
1033 |
|
|
{
|
1034 |
|
|
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - MaxFrameNum;
|
1035 |
|
|
}
|
1036 |
|
|
else
|
1037 |
|
|
{
|
1038 |
|
|
dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
|
1039 |
|
|
}
|
1040 |
|
|
if (dpb.fs_ref[i]->is_reference & 1)
|
1041 |
|
|
{
|
1042 |
|
|
dpb.fs_ref[i]->top_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_top;
|
1043 |
|
|
}
|
1044 |
|
|
if (dpb.fs_ref[i]->is_reference & 2)
|
1045 |
|
|
{
|
1046 |
|
|
dpb.fs_ref[i]->bottom_field->pic_num = (2 * dpb.fs_ref[i]->frame_num_wrap) + add_bottom;
|
1047 |
|
|
}
|
1048 |
|
|
}
|
1049 |
|
|
}
|
1050 |
|
|
// update long_term_pic_num
|
1051 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1052 |
|
|
{
|
1053 |
|
|
if (dpb.fs_ltref[i]->is_long_term & 1)
|
1054 |
|
|
{
|
1055 |
|
|
dpb.fs_ltref[i]->top_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->top_field->long_term_frame_idx + add_top;
|
1056 |
|
|
}
|
1057 |
|
|
if (dpb.fs_ltref[i]->is_long_term & 2)
|
1058 |
|
|
{
|
1059 |
|
|
dpb.fs_ltref[i]->bottom_field->long_term_pic_num = 2 * dpb.fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom;
|
1060 |
|
|
}
|
1061 |
|
|
}
|
1062 |
|
|
}
|
1063 |
|
|
|
1064 |
|
|
|
1065 |
|
|
|
1066 |
|
|
if ((currSliceType == I_SLICE)||(currSliceType == SI_SLICE))
|
1067 |
|
|
{
|
1068 |
|
|
listXsize[0] = 0;
|
1069 |
|
|
listXsize[1] = 0;
|
1070 |
|
|
return;
|
1071 |
|
|
}
|
1072 |
|
|
|
1073 |
|
|
if ((currSliceType == P_SLICE)||(currSliceType == SP_SLICE))
|
1074 |
|
|
{
|
1075 |
|
|
// Calculate FrameNumWrap and PicNum
|
1076 |
|
|
if (currPicStructure == FRAME)
|
1077 |
|
|
{
|
1078 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1079 |
|
|
{
|
1080 |
|
|
if (dpb.fs_ref[i]->is_used==3)
|
1081 |
|
|
{
|
1082 |
|
|
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
|
1083 |
|
|
{
|
1084 |
|
|
listX[0][list0idx++] = dpb.fs_ref[i]->frame;
|
1085 |
|
|
}
|
1086 |
|
|
}
|
1087 |
|
|
}
|
1088 |
|
|
// order list 0 by PicNum
|
1089 |
|
|
qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_pic_num_desc);
|
1090 |
|
|
listXsize[0] = list0idx;
|
1091 |
|
|
// printf("listX[0] (PicNum): "); for (i=0; i<list0idx; i++){printf ("%d ", listX[0][i]->pic_num);} printf("\n");
|
1092 |
|
|
|
1093 |
|
|
// long term handling
|
1094 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1095 |
|
|
{
|
1096 |
|
|
if (dpb.fs_ltref[i]->is_used==3)
|
1097 |
|
|
{
|
1098 |
|
|
if (dpb.fs_ltref[i]->frame->is_long_term)
|
1099 |
|
|
{
|
1100 |
|
|
listX[0][list0idx++]=dpb.fs_ltref[i]->frame;
|
1101 |
|
|
}
|
1102 |
|
|
}
|
1103 |
|
|
}
|
1104 |
|
|
qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
|
1105 |
|
|
listXsize[0] = list0idx;
|
1106 |
|
|
}
|
1107 |
|
|
else
|
1108 |
|
|
{
|
1109 |
|
|
fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
|
1110 |
|
|
if (NULL==fs_list0)
|
1111 |
|
|
no_mem_exit("init_lists: fs_list0");
|
1112 |
|
|
fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
|
1113 |
|
|
if (NULL==fs_listlt)
|
1114 |
|
|
no_mem_exit("init_lists: fs_listlt");
|
1115 |
|
|
|
1116 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1117 |
|
|
{
|
1118 |
|
|
if (dpb.fs_ref[i]->is_reference)
|
1119 |
|
|
{
|
1120 |
|
|
fs_list0[list0idx++] = dpb.fs_ref[i];
|
1121 |
|
|
}
|
1122 |
|
|
}
|
1123 |
|
|
|
1124 |
|
|
qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_frame_num_desc);
|
1125 |
|
|
|
1126 |
|
|
// printf("fs_list0 (FrameNum): "); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->frame_num_wrap);} printf("\n");
|
1127 |
|
|
|
1128 |
|
|
listXsize[0] = 0;
|
1129 |
|
|
gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
|
1130 |
|
|
|
1131 |
|
|
// printf("listX[0] (PicNum): "); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->pic_num);} printf("\n");
|
1132 |
|
|
|
1133 |
|
|
// long term handling
|
1134 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1135 |
|
|
{
|
1136 |
|
|
fs_listlt[listltidx++]=dpb.fs_ltref[i];
|
1137 |
|
|
}
|
1138 |
|
|
|
1139 |
|
|
qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);
|
1140 |
|
|
|
1141 |
|
|
gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[0], &listXsize[0], 1);
|
1142 |
|
|
|
1143 |
|
|
free(fs_list0);
|
1144 |
|
|
free(fs_listlt);
|
1145 |
|
|
}
|
1146 |
|
|
listXsize[1] = 0;
|
1147 |
|
|
}
|
1148 |
|
|
else
|
1149 |
|
|
{
|
1150 |
|
|
// B-Slice
|
1151 |
|
|
if (currPicStructure == FRAME)
|
1152 |
|
|
{
|
1153 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1154 |
|
|
{
|
1155 |
|
|
if (dpb.fs_ref[i]->is_used==3)
|
1156 |
|
|
{
|
1157 |
|
|
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
|
1158 |
|
|
{
|
1159 |
|
|
if (img->framepoc >= dpb.fs_ref[i]->frame->poc) //!KS use >= for error concealment
|
1160 |
|
|
// if (img->framepoc > dpb.fs_ref[i]->frame->poc)
|
1161 |
|
|
{
|
1162 |
|
|
listX[0][list0idx++] = dpb.fs_ref[i]->frame;
|
1163 |
|
|
}
|
1164 |
|
|
}
|
1165 |
|
|
}
|
1166 |
|
|
}
|
1167 |
|
|
qsort((void *)listX[0], list0idx, sizeof(StorablePicture*), compare_pic_by_poc_desc);
|
1168 |
|
|
list0idx_1 = list0idx;
|
1169 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1170 |
|
|
{
|
1171 |
|
|
if (dpb.fs_ref[i]->is_used==3)
|
1172 |
|
|
{
|
1173 |
|
|
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
|
1174 |
|
|
{
|
1175 |
|
|
if (img->framepoc < dpb.fs_ref[i]->frame->poc)
|
1176 |
|
|
{
|
1177 |
|
|
listX[0][list0idx++] = dpb.fs_ref[i]->frame;
|
1178 |
|
|
}
|
1179 |
|
|
}
|
1180 |
|
|
}
|
1181 |
|
|
}
|
1182 |
|
|
qsort((void *)&listX[0][list0idx_1], list0idx-list0idx_1, sizeof(StorablePicture*), compare_pic_by_poc_asc);
|
1183 |
|
|
|
1184 |
|
|
for (j=0; j<list0idx_1; j++)
|
1185 |
|
|
{
|
1186 |
|
|
listX[1][list0idx-list0idx_1+j]=listX[0][j];
|
1187 |
|
|
}
|
1188 |
|
|
for (j=list0idx_1; j<list0idx; j++)
|
1189 |
|
|
{
|
1190 |
|
|
listX[1][j-list0idx_1]=listX[0][j];
|
1191 |
|
|
}
|
1192 |
|
|
|
1193 |
|
|
listXsize[0] = listXsize[1] = list0idx;
|
1194 |
|
|
|
1195 |
|
|
// printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("\n");
|
1196 |
|
|
// printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} printf("\n");
|
1197 |
|
|
|
1198 |
|
|
// long term handling
|
1199 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1200 |
|
|
{
|
1201 |
|
|
if (dpb.fs_ltref[i]->is_used==3)
|
1202 |
|
|
{
|
1203 |
|
|
if (dpb.fs_ltref[i]->frame->is_long_term)
|
1204 |
|
|
{
|
1205 |
|
|
listX[0][list0idx] =dpb.fs_ltref[i]->frame;
|
1206 |
|
|
listX[1][list0idx++]=dpb.fs_ltref[i]->frame;
|
1207 |
|
|
}
|
1208 |
|
|
}
|
1209 |
|
|
}
|
1210 |
|
|
qsort((void *)&listX[0][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
|
1211 |
|
|
qsort((void *)&listX[1][listXsize[0]], list0idx-listXsize[0], sizeof(StorablePicture*), compare_pic_by_lt_pic_num_asc);
|
1212 |
|
|
listXsize[0] = listXsize[1] = list0idx;
|
1213 |
|
|
}
|
1214 |
|
|
else
|
1215 |
|
|
{
|
1216 |
|
|
fs_list0 = calloc(dpb.size, sizeof (FrameStore*));
|
1217 |
|
|
if (NULL==fs_list0)
|
1218 |
|
|
no_mem_exit("init_lists: fs_list0");
|
1219 |
|
|
fs_list1 = calloc(dpb.size, sizeof (FrameStore*));
|
1220 |
|
|
if (NULL==fs_list1)
|
1221 |
|
|
no_mem_exit("init_lists: fs_list1");
|
1222 |
|
|
fs_listlt = calloc(dpb.size, sizeof (FrameStore*));
|
1223 |
|
|
if (NULL==fs_listlt)
|
1224 |
|
|
no_mem_exit("init_lists: fs_listlt");
|
1225 |
|
|
|
1226 |
|
|
listXsize[0] = 0;
|
1227 |
|
|
listXsize[1] = 1;
|
1228 |
|
|
|
1229 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1230 |
|
|
{
|
1231 |
|
|
if (dpb.fs_ref[i]->is_used)
|
1232 |
|
|
{
|
1233 |
|
|
if (img->ThisPOC >= dpb.fs_ref[i]->poc)
|
1234 |
|
|
{
|
1235 |
|
|
fs_list0[list0idx++] = dpb.fs_ref[i];
|
1236 |
|
|
}
|
1237 |
|
|
}
|
1238 |
|
|
}
|
1239 |
|
|
qsort((void *)fs_list0, list0idx, sizeof(FrameStore*), compare_fs_by_poc_desc);
|
1240 |
|
|
list0idx_1 = list0idx;
|
1241 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1242 |
|
|
{
|
1243 |
|
|
if (dpb.fs_ref[i]->is_used)
|
1244 |
|
|
{
|
1245 |
|
|
if (img->ThisPOC < dpb.fs_ref[i]->poc)
|
1246 |
|
|
{
|
1247 |
|
|
fs_list0[list0idx++] = dpb.fs_ref[i];
|
1248 |
|
|
}
|
1249 |
|
|
}
|
1250 |
|
|
}
|
1251 |
|
|
qsort((void *)&fs_list0[list0idx_1], list0idx-list0idx_1, sizeof(FrameStore*), compare_fs_by_poc_asc);
|
1252 |
|
|
|
1253 |
|
|
for (j=0; j<list0idx_1; j++)
|
1254 |
|
|
{
|
1255 |
|
|
fs_list1[list0idx-list0idx_1+j]=fs_list0[j];
|
1256 |
|
|
}
|
1257 |
|
|
for (j=list0idx_1; j<list0idx; j++)
|
1258 |
|
|
{
|
1259 |
|
|
fs_list1[j-list0idx_1]=fs_list0[j];
|
1260 |
|
|
}
|
1261 |
|
|
|
1262 |
|
|
// printf("fs_list0 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list0[i]->poc);} printf("\n");
|
1263 |
|
|
// printf("fs_list1 currPoc=%d (Poc): ", img->ThisPOC); for (i=0; i<list0idx; i++){printf ("%d ", fs_list1[i]->poc);} printf("\n");
|
1264 |
|
|
|
1265 |
|
|
listXsize[0] = 0;
|
1266 |
|
|
listXsize[1] = 0;
|
1267 |
|
|
gen_pic_list_from_frame_list(currPicStructure, fs_list0, list0idx, listX[0], &listXsize[0], 0);
|
1268 |
|
|
gen_pic_list_from_frame_list(currPicStructure, fs_list1, list0idx, listX[1], &listXsize[1], 0);
|
1269 |
|
|
|
1270 |
|
|
// printf("listX[0] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[0]; i++){printf ("%d ", listX[0][i]->poc);} printf("\n");
|
1271 |
|
|
// printf("listX[1] currPoc=%d (Poc): ", img->framepoc); for (i=0; i<listXsize[1]; i++){printf ("%d ", listX[1][i]->poc);} printf("\n");
|
1272 |
|
|
|
1273 |
|
|
// long term handling
|
1274 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1275 |
|
|
{
|
1276 |
|
|
fs_listlt[listltidx++]=dpb.fs_ltref[i];
|
1277 |
|
|
}
|
1278 |
|
|
|
1279 |
|
|
qsort((void *)fs_listlt, listltidx, sizeof(FrameStore*), compare_fs_by_lt_pic_idx_asc);
|
1280 |
|
|
|
1281 |
|
|
gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[0], &listXsize[0], 1);
|
1282 |
|
|
gen_pic_list_from_frame_list(currPicStructure, fs_listlt, listltidx, listX[1], &listXsize[1], 1);
|
1283 |
|
|
|
1284 |
|
|
free(fs_list0);
|
1285 |
|
|
free(fs_list1);
|
1286 |
|
|
free(fs_listlt);
|
1287 |
|
|
}
|
1288 |
|
|
}
|
1289 |
|
|
|
1290 |
|
|
if ((listXsize[0] == listXsize[1]) && (listXsize[0] > 1))
|
1291 |
|
|
{
|
1292 |
|
|
// check if lists are identical, if yes swap first two elements of listX[1]
|
1293 |
|
|
diff=0;
|
1294 |
|
|
for (j = 0; j< listXsize[0]; j++)
|
1295 |
|
|
{
|
1296 |
|
|
if (listX[0][j]!=listX[1][j])
|
1297 |
|
|
diff=1;
|
1298 |
|
|
}
|
1299 |
|
|
if (!diff)
|
1300 |
|
|
{
|
1301 |
|
|
tmp_s = listX[1][0];
|
1302 |
|
|
listX[1][0]=listX[1][1];
|
1303 |
|
|
listX[1][1]=tmp_s;
|
1304 |
|
|
}
|
1305 |
|
|
}
|
1306 |
|
|
// set max size
|
1307 |
|
|
listXsize[0] = imin (listXsize[0], img->num_ref_idx_l0_active);
|
1308 |
|
|
listXsize[1] = imin (listXsize[1], img->num_ref_idx_l1_active);
|
1309 |
|
|
|
1310 |
|
|
// set the unused list entries to NULL
|
1311 |
|
|
for (i=listXsize[0]; i< (MAX_LIST_SIZE) ; i++)
|
1312 |
|
|
{
|
1313 |
|
|
// listX[0][i] = NULL;
|
1314 |
|
|
listX[0][i] = no_reference_picture;
|
1315 |
|
|
|
1316 |
|
|
}
|
1317 |
|
|
for (i=listXsize[1]; i< (MAX_LIST_SIZE) ; i++)
|
1318 |
|
|
{
|
1319 |
|
|
// listX[1][i] = NULL;
|
1320 |
|
|
listX[1][i] = no_reference_picture;
|
1321 |
|
|
}
|
1322 |
|
|
}
|
1323 |
|
|
|
1324 |
|
|
/*!
|
1325 |
|
|
************************************************************************
|
1326 |
|
|
* \brief
|
1327 |
|
|
* Initialize listX[2..5] from lists 0 and 1
|
1328 |
|
|
* listX[2]: list0 for current_field==top
|
1329 |
|
|
* listX[3]: list1 for current_field==top
|
1330 |
|
|
* listX[4]: list0 for current_field==bottom
|
1331 |
|
|
* listX[5]: list1 for current_field==bottom
|
1332 |
|
|
*
|
1333 |
|
|
************************************************************************
|
1334 |
|
|
*/
|
1335 |
|
|
void init_mbaff_lists()
|
1336 |
|
|
{
|
1337 |
|
|
unsigned j;
|
1338 |
|
|
int i;
|
1339 |
|
|
|
1340 |
|
|
for (i=2;i<6;i++)
|
1341 |
|
|
{
|
1342 |
|
|
for (j=0; j<MAX_LIST_SIZE; j++)
|
1343 |
|
|
{
|
1344 |
|
|
// listX[i][j] = NULL;
|
1345 |
|
|
listX[i][j] = no_reference_picture;
|
1346 |
|
|
}
|
1347 |
|
|
listXsize[i]=0;
|
1348 |
|
|
}
|
1349 |
|
|
|
1350 |
|
|
for (i=0; i<listXsize[0]; i++)
|
1351 |
|
|
{
|
1352 |
|
|
listX[2][2*i] =listX[0][i]->top_field;
|
1353 |
|
|
listX[2][2*i+1]=listX[0][i]->bottom_field;
|
1354 |
|
|
listX[4][2*i] =listX[0][i]->bottom_field;
|
1355 |
|
|
listX[4][2*i+1]=listX[0][i]->top_field;
|
1356 |
|
|
}
|
1357 |
|
|
listXsize[2]=listXsize[4]=listXsize[0] * 2;
|
1358 |
|
|
|
1359 |
|
|
for (i=0; i<listXsize[1]; i++)
|
1360 |
|
|
{
|
1361 |
|
|
listX[3][2*i] =listX[1][i]->top_field;
|
1362 |
|
|
listX[3][2*i+1]=listX[1][i]->bottom_field;
|
1363 |
|
|
listX[5][2*i] =listX[1][i]->bottom_field;
|
1364 |
|
|
listX[5][2*i+1]=listX[1][i]->top_field;
|
1365 |
|
|
}
|
1366 |
|
|
listXsize[3]=listXsize[5]=listXsize[1] * 2;
|
1367 |
|
|
}
|
1368 |
|
|
|
1369 |
|
|
/*!
|
1370 |
|
|
************************************************************************
|
1371 |
|
|
* \brief
|
1372 |
|
|
* Returns short term pic with given picNum
|
1373 |
|
|
*
|
1374 |
|
|
************************************************************************
|
1375 |
|
|
*/
|
1376 |
|
|
static StorablePicture* get_short_term_pic(int picNum)
|
1377 |
|
|
{
|
1378 |
|
|
unsigned i;
|
1379 |
|
|
|
1380 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1381 |
|
|
{
|
1382 |
|
|
if (img->structure==FRAME)
|
1383 |
|
|
{
|
1384 |
|
|
if (dpb.fs_ref[i]->is_reference == 3)
|
1385 |
|
|
if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNum))
|
1386 |
|
|
return dpb.fs_ref[i]->frame;
|
1387 |
|
|
}
|
1388 |
|
|
else
|
1389 |
|
|
{
|
1390 |
|
|
if (dpb.fs_ref[i]->is_reference & 1)
|
1391 |
|
|
if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNum))
|
1392 |
|
|
return dpb.fs_ref[i]->top_field;
|
1393 |
|
|
if (dpb.fs_ref[i]->is_reference & 2)
|
1394 |
|
|
if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNum))
|
1395 |
|
|
return dpb.fs_ref[i]->bottom_field;
|
1396 |
|
|
}
|
1397 |
|
|
}
|
1398 |
|
|
// return NULL;
|
1399 |
|
|
return no_reference_picture;
|
1400 |
|
|
}
|
1401 |
|
|
|
1402 |
|
|
/*!
|
1403 |
|
|
************************************************************************
|
1404 |
|
|
* \brief
|
1405 |
|
|
* Returns short term pic with given LongtermPicNum
|
1406 |
|
|
*
|
1407 |
|
|
************************************************************************
|
1408 |
|
|
*/
|
1409 |
|
|
static StorablePicture* get_long_term_pic(int LongtermPicNum)
|
1410 |
|
|
{
|
1411 |
|
|
unsigned i;
|
1412 |
|
|
|
1413 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1414 |
|
|
{
|
1415 |
|
|
if (img->structure==FRAME)
|
1416 |
|
|
{
|
1417 |
|
|
if (dpb.fs_ltref[i]->is_reference == 3)
|
1418 |
|
|
if ((dpb.fs_ltref[i]->frame->is_long_term)&&(dpb.fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum))
|
1419 |
|
|
return dpb.fs_ltref[i]->frame;
|
1420 |
|
|
}
|
1421 |
|
|
else
|
1422 |
|
|
{
|
1423 |
|
|
if (dpb.fs_ltref[i]->is_reference & 1)
|
1424 |
|
|
if ((dpb.fs_ltref[i]->top_field->is_long_term)&&(dpb.fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum))
|
1425 |
|
|
return dpb.fs_ltref[i]->top_field;
|
1426 |
|
|
if (dpb.fs_ltref[i]->is_reference & 2)
|
1427 |
|
|
if ((dpb.fs_ltref[i]->bottom_field->is_long_term)&&(dpb.fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum))
|
1428 |
|
|
return dpb.fs_ltref[i]->bottom_field;
|
1429 |
|
|
}
|
1430 |
|
|
}
|
1431 |
|
|
return NULL;
|
1432 |
|
|
}
|
1433 |
|
|
|
1434 |
|
|
/*!
|
1435 |
|
|
************************************************************************
|
1436 |
|
|
* \brief
|
1437 |
|
|
* Reordering process for short-term reference pictures
|
1438 |
|
|
*
|
1439 |
|
|
************************************************************************
|
1440 |
|
|
*/
|
1441 |
|
|
static void reorder_short_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int picNumLX, int *refIdxLX)
|
1442 |
|
|
{
|
1443 |
|
|
int cIdx, nIdx;
|
1444 |
|
|
|
1445 |
|
|
StorablePicture *picLX;
|
1446 |
|
|
|
1447 |
|
|
picLX = get_short_term_pic(picNumLX);
|
1448 |
|
|
|
1449 |
|
|
for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
|
1450 |
|
|
RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
|
1451 |
|
|
|
1452 |
|
|
RefPicListX[ (*refIdxLX)++ ] = picLX;
|
1453 |
|
|
|
1454 |
|
|
nIdx = *refIdxLX;
|
1455 |
|
|
|
1456 |
|
|
for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
|
1457 |
|
|
if (RefPicListX[ cIdx ])
|
1458 |
|
|
if( (RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->pic_num != picNumLX ))
|
1459 |
|
|
RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
|
1460 |
|
|
|
1461 |
|
|
}
|
1462 |
|
|
|
1463 |
|
|
|
1464 |
|
|
/*!
|
1465 |
|
|
************************************************************************
|
1466 |
|
|
* \brief
|
1467 |
|
|
* Reordering process for short-term reference pictures
|
1468 |
|
|
*
|
1469 |
|
|
************************************************************************
|
1470 |
|
|
*/
|
1471 |
|
|
static void reorder_long_term(StorablePicture **RefPicListX, int num_ref_idx_lX_active_minus1, int LongTermPicNum, int *refIdxLX)
|
1472 |
|
|
{
|
1473 |
|
|
int cIdx, nIdx;
|
1474 |
|
|
|
1475 |
|
|
StorablePicture *picLX;
|
1476 |
|
|
|
1477 |
|
|
picLX = get_long_term_pic(LongTermPicNum);
|
1478 |
|
|
|
1479 |
|
|
for( cIdx = num_ref_idx_lX_active_minus1+1; cIdx > *refIdxLX; cIdx-- )
|
1480 |
|
|
RefPicListX[ cIdx ] = RefPicListX[ cIdx - 1];
|
1481 |
|
|
|
1482 |
|
|
RefPicListX[ (*refIdxLX)++ ] = picLX;
|
1483 |
|
|
|
1484 |
|
|
nIdx = *refIdxLX;
|
1485 |
|
|
|
1486 |
|
|
for( cIdx = *refIdxLX; cIdx <= num_ref_idx_lX_active_minus1+1; cIdx++ )
|
1487 |
|
|
if (RefPicListX[ cIdx ])
|
1488 |
|
|
if( (!RefPicListX[ cIdx ]->is_long_term ) || (RefPicListX[ cIdx ]->long_term_pic_num != LongTermPicNum ))
|
1489 |
|
|
RefPicListX[ nIdx++ ] = RefPicListX[ cIdx ];
|
1490 |
|
|
}
|
1491 |
|
|
|
1492 |
|
|
|
1493 |
|
|
/*!
|
1494 |
|
|
************************************************************************
|
1495 |
|
|
* \brief
|
1496 |
|
|
* Reordering process for reference picture lists
|
1497 |
|
|
*
|
1498 |
|
|
************************************************************************
|
1499 |
|
|
*/
|
1500 |
|
|
void reorder_ref_pic_list(StorablePicture **list, int *list_size, int num_ref_idx_lX_active_minus1, int *reordering_of_pic_nums_idc, int *abs_diff_pic_num_minus1, int *long_term_pic_idx)
|
1501 |
|
|
{
|
1502 |
|
|
int i;
|
1503 |
|
|
|
1504 |
|
|
int maxPicNum, currPicNum, picNumLXNoWrap, picNumLXPred, picNumLX;
|
1505 |
|
|
int refIdxLX = 0;
|
1506 |
|
|
|
1507 |
|
|
if (img->structure==FRAME)
|
1508 |
|
|
{
|
1509 |
|
|
maxPicNum = img->MaxFrameNum;
|
1510 |
|
|
currPicNum = img->frame_num;
|
1511 |
|
|
}
|
1512 |
|
|
else
|
1513 |
|
|
{
|
1514 |
|
|
maxPicNum = 2 * img->MaxFrameNum;
|
1515 |
|
|
currPicNum = 2 * img->frame_num + 1;
|
1516 |
|
|
}
|
1517 |
|
|
|
1518 |
|
|
picNumLXPred = currPicNum;
|
1519 |
|
|
|
1520 |
|
|
for (i=0; reordering_of_pic_nums_idc[i]!=3; i++)
|
1521 |
|
|
{
|
1522 |
|
|
if (reordering_of_pic_nums_idc[i]>3)
|
1523 |
|
|
error ("Invalid remapping_of_pic_nums_idc command", 500);
|
1524 |
|
|
|
1525 |
|
|
if (reordering_of_pic_nums_idc[i] < 2)
|
1526 |
|
|
{
|
1527 |
|
|
if (reordering_of_pic_nums_idc[i] == 0)
|
1528 |
|
|
{
|
1529 |
|
|
if( picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) < 0 )
|
1530 |
|
|
picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 ) + maxPicNum;
|
1531 |
|
|
else
|
1532 |
|
|
picNumLXNoWrap = picNumLXPred - ( abs_diff_pic_num_minus1[i] + 1 );
|
1533 |
|
|
}
|
1534 |
|
|
else // (remapping_of_pic_nums_idc[i] == 1)
|
1535 |
|
|
{
|
1536 |
|
|
if( picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) >= maxPicNum )
|
1537 |
|
|
picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 ) - maxPicNum;
|
1538 |
|
|
else
|
1539 |
|
|
picNumLXNoWrap = picNumLXPred + ( abs_diff_pic_num_minus1[i] + 1 );
|
1540 |
|
|
}
|
1541 |
|
|
picNumLXPred = picNumLXNoWrap;
|
1542 |
|
|
|
1543 |
|
|
if( picNumLXNoWrap > currPicNum )
|
1544 |
|
|
picNumLX = picNumLXNoWrap - maxPicNum;
|
1545 |
|
|
else
|
1546 |
|
|
picNumLX = picNumLXNoWrap;
|
1547 |
|
|
|
1548 |
|
|
reorder_short_term(list, num_ref_idx_lX_active_minus1, picNumLX, &refIdxLX);
|
1549 |
|
|
}
|
1550 |
|
|
else //(remapping_of_pic_nums_idc[i] == 2)
|
1551 |
|
|
{
|
1552 |
|
|
reorder_long_term(list, num_ref_idx_lX_active_minus1, long_term_pic_idx[i], &refIdxLX);
|
1553 |
|
|
}
|
1554 |
|
|
|
1555 |
|
|
}
|
1556 |
|
|
// that's a definition
|
1557 |
|
|
*list_size = num_ref_idx_lX_active_minus1 + 1;
|
1558 |
|
|
}
|
1559 |
|
|
|
1560 |
|
|
|
1561 |
|
|
|
1562 |
|
|
/*!
|
1563 |
|
|
************************************************************************
|
1564 |
|
|
* \brief
|
1565 |
|
|
* Update the list of frame stores that contain reference frames/fields
|
1566 |
|
|
*
|
1567 |
|
|
************************************************************************
|
1568 |
|
|
*/
|
1569 |
|
|
void update_ref_list()
|
1570 |
|
|
{
|
1571 |
|
|
unsigned i, j;
|
1572 |
|
|
for (i=0, j=0; i<dpb.used_size; i++)
|
1573 |
|
|
{
|
1574 |
|
|
if (is_short_term_reference(dpb.fs[i]))
|
1575 |
|
|
{
|
1576 |
|
|
dpb.fs_ref[j++]=dpb.fs[i];
|
1577 |
|
|
}
|
1578 |
|
|
}
|
1579 |
|
|
|
1580 |
|
|
dpb.ref_frames_in_buffer = j;
|
1581 |
|
|
|
1582 |
|
|
while (j<dpb.size)
|
1583 |
|
|
{
|
1584 |
|
|
dpb.fs_ref[j++]=NULL;
|
1585 |
|
|
}
|
1586 |
|
|
}
|
1587 |
|
|
|
1588 |
|
|
|
1589 |
|
|
/*!
|
1590 |
|
|
************************************************************************
|
1591 |
|
|
* \brief
|
1592 |
|
|
* Update the list of frame stores that contain long-term reference
|
1593 |
|
|
* frames/fields
|
1594 |
|
|
*
|
1595 |
|
|
************************************************************************
|
1596 |
|
|
*/
|
1597 |
|
|
void update_ltref_list()
|
1598 |
|
|
{
|
1599 |
|
|
unsigned i, j;
|
1600 |
|
|
for (i=0, j=0; i<dpb.used_size; i++)
|
1601 |
|
|
{
|
1602 |
|
|
if (is_long_term_reference(dpb.fs[i]))
|
1603 |
|
|
{
|
1604 |
|
|
dpb.fs_ltref[j++]=dpb.fs[i];
|
1605 |
|
|
}
|
1606 |
|
|
}
|
1607 |
|
|
|
1608 |
|
|
dpb.ltref_frames_in_buffer=j;
|
1609 |
|
|
|
1610 |
|
|
while (j<dpb.size)
|
1611 |
|
|
{
|
1612 |
|
|
dpb.fs_ltref[j++]=NULL;
|
1613 |
|
|
}
|
1614 |
|
|
}
|
1615 |
|
|
|
1616 |
|
|
/*!
|
1617 |
|
|
************************************************************************
|
1618 |
|
|
* \brief
|
1619 |
|
|
* Perform Memory management for idr pictures
|
1620 |
|
|
*
|
1621 |
|
|
************************************************************************
|
1622 |
|
|
*/
|
1623 |
|
|
static void idr_memory_management(StorablePicture* p)
|
1624 |
|
|
{
|
1625 |
|
|
unsigned i;
|
1626 |
|
|
|
1627 |
|
|
assert (p->idr_flag);
|
1628 |
|
|
|
1629 |
|
|
if (p->no_output_of_prior_pics_flag)
|
1630 |
|
|
{
|
1631 |
|
|
// free all stored pictures
|
1632 |
|
|
for (i=0; i<dpb.used_size; i++)
|
1633 |
|
|
{
|
1634 |
|
|
// reset all reference settings
|
1635 |
|
|
free_frame_store(dpb.fs[i]);
|
1636 |
|
|
dpb.fs[i] = alloc_frame_store();
|
1637 |
|
|
}
|
1638 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1639 |
|
|
{
|
1640 |
|
|
dpb.fs_ref[i]=NULL;
|
1641 |
|
|
}
|
1642 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1643 |
|
|
{
|
1644 |
|
|
dpb.fs_ltref[i]=NULL;
|
1645 |
|
|
}
|
1646 |
|
|
dpb.used_size=0;
|
1647 |
|
|
}
|
1648 |
|
|
else
|
1649 |
|
|
{
|
1650 |
|
|
flush_dpb();
|
1651 |
|
|
}
|
1652 |
|
|
dpb.last_picture = NULL;
|
1653 |
|
|
|
1654 |
|
|
update_ref_list();
|
1655 |
|
|
update_ltref_list();
|
1656 |
|
|
dpb.last_output_poc = INT_MIN;
|
1657 |
|
|
|
1658 |
|
|
if (p->long_term_reference_flag)
|
1659 |
|
|
{
|
1660 |
|
|
dpb.max_long_term_pic_idx = 0;
|
1661 |
|
|
p->is_long_term = 1;
|
1662 |
|
|
p->long_term_frame_idx = 0;
|
1663 |
|
|
}
|
1664 |
|
|
else
|
1665 |
|
|
{
|
1666 |
|
|
dpb.max_long_term_pic_idx = -1;
|
1667 |
|
|
p->is_long_term = 0;
|
1668 |
|
|
}
|
1669 |
|
|
}
|
1670 |
|
|
|
1671 |
|
|
/*!
|
1672 |
|
|
************************************************************************
|
1673 |
|
|
* \brief
|
1674 |
|
|
* Perform Sliding window decoded reference picture marking process
|
1675 |
|
|
*
|
1676 |
|
|
************************************************************************
|
1677 |
|
|
*/
|
1678 |
|
|
static void sliding_window_memory_management(StorablePicture* p)
|
1679 |
|
|
{
|
1680 |
|
|
unsigned i;
|
1681 |
|
|
|
1682 |
|
|
assert (!p->idr_flag);
|
1683 |
|
|
// if this is a reference pic with sliding sliding window, unmark first ref frame
|
1684 |
|
|
if (dpb.ref_frames_in_buffer==dpb.num_ref_frames - dpb.ltref_frames_in_buffer)
|
1685 |
|
|
{
|
1686 |
|
|
for (i=0; i<dpb.used_size;i++)
|
1687 |
|
|
{
|
1688 |
|
|
if (dpb.fs[i]->is_reference && (!(dpb.fs[i]->is_long_term)))
|
1689 |
|
|
{
|
1690 |
|
|
unmark_for_reference(dpb.fs[i]);
|
1691 |
|
|
update_ref_list();
|
1692 |
|
|
break;
|
1693 |
|
|
}
|
1694 |
|
|
}
|
1695 |
|
|
}
|
1696 |
|
|
|
1697 |
|
|
p->is_long_term = 0;
|
1698 |
|
|
}
|
1699 |
|
|
|
1700 |
|
|
/*!
|
1701 |
|
|
************************************************************************
|
1702 |
|
|
* \brief
|
1703 |
|
|
* Calculate picNumX
|
1704 |
|
|
************************************************************************
|
1705 |
|
|
*/
|
1706 |
|
|
static int get_pic_num_x (StorablePicture *p, int difference_of_pic_nums_minus1)
|
1707 |
|
|
{
|
1708 |
|
|
int currPicNum;
|
1709 |
|
|
|
1710 |
|
|
if (p->structure == FRAME)
|
1711 |
|
|
currPicNum = p->frame_num;
|
1712 |
|
|
else
|
1713 |
|
|
currPicNum = 2 * p->frame_num + 1;
|
1714 |
|
|
|
1715 |
|
|
return currPicNum - (difference_of_pic_nums_minus1 + 1);
|
1716 |
|
|
}
|
1717 |
|
|
|
1718 |
|
|
|
1719 |
|
|
/*!
|
1720 |
|
|
************************************************************************
|
1721 |
|
|
* \brief
|
1722 |
|
|
* Adaptive Memory Management: Mark short term picture unused
|
1723 |
|
|
************************************************************************
|
1724 |
|
|
*/
|
1725 |
|
|
static void mm_unmark_short_term_for_reference(StorablePicture *p, int difference_of_pic_nums_minus1)
|
1726 |
|
|
{
|
1727 |
|
|
int picNumX;
|
1728 |
|
|
|
1729 |
|
|
unsigned i;
|
1730 |
|
|
|
1731 |
|
|
picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
|
1732 |
|
|
|
1733 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1734 |
|
|
{
|
1735 |
|
|
if (p->structure == FRAME)
|
1736 |
|
|
{
|
1737 |
|
|
if ((dpb.fs_ref[i]->is_reference==3) && (dpb.fs_ref[i]->is_long_term==0))
|
1738 |
|
|
{
|
1739 |
|
|
if (dpb.fs_ref[i]->frame->pic_num == picNumX)
|
1740 |
|
|
{
|
1741 |
|
|
unmark_for_reference(dpb.fs_ref[i]);
|
1742 |
|
|
return;
|
1743 |
|
|
}
|
1744 |
|
|
}
|
1745 |
|
|
}
|
1746 |
|
|
else
|
1747 |
|
|
{
|
1748 |
|
|
if ((dpb.fs_ref[i]->is_reference & 1) && (!(dpb.fs_ref[i]->is_long_term & 1)))
|
1749 |
|
|
{
|
1750 |
|
|
if (dpb.fs_ref[i]->top_field->pic_num == picNumX)
|
1751 |
|
|
{
|
1752 |
|
|
dpb.fs_ref[i]->top_field->used_for_reference = 0;
|
1753 |
|
|
dpb.fs_ref[i]->is_reference &= 2;
|
1754 |
|
|
if (dpb.fs_ref[i]->is_used == 3)
|
1755 |
|
|
{
|
1756 |
|
|
dpb.fs_ref[i]->frame->used_for_reference = 0;
|
1757 |
|
|
}
|
1758 |
|
|
return;
|
1759 |
|
|
}
|
1760 |
|
|
}
|
1761 |
|
|
if ((dpb.fs_ref[i]->is_reference & 2) && (!(dpb.fs_ref[i]->is_long_term & 2)))
|
1762 |
|
|
{
|
1763 |
|
|
if (dpb.fs_ref[i]->bottom_field->pic_num == picNumX)
|
1764 |
|
|
{
|
1765 |
|
|
dpb.fs_ref[i]->bottom_field->used_for_reference = 0;
|
1766 |
|
|
dpb.fs_ref[i]->is_reference &= 1;
|
1767 |
|
|
if (dpb.fs_ref[i]->is_used == 3)
|
1768 |
|
|
{
|
1769 |
|
|
dpb.fs_ref[i]->frame->used_for_reference = 0;
|
1770 |
|
|
}
|
1771 |
|
|
return;
|
1772 |
|
|
}
|
1773 |
|
|
}
|
1774 |
|
|
}
|
1775 |
|
|
}
|
1776 |
|
|
}
|
1777 |
|
|
|
1778 |
|
|
|
1779 |
|
|
/*!
|
1780 |
|
|
************************************************************************
|
1781 |
|
|
* \brief
|
1782 |
|
|
* Adaptive Memory Management: Mark long term picture unused
|
1783 |
|
|
************************************************************************
|
1784 |
|
|
*/
|
1785 |
|
|
static void mm_unmark_long_term_for_reference(StorablePicture *p, int long_term_pic_num)
|
1786 |
|
|
{
|
1787 |
|
|
unsigned i;
|
1788 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1789 |
|
|
{
|
1790 |
|
|
if (p->structure == FRAME)
|
1791 |
|
|
{
|
1792 |
|
|
if ((dpb.fs_ltref[i]->is_reference==3) && (dpb.fs_ltref[i]->is_long_term==3))
|
1793 |
|
|
{
|
1794 |
|
|
if (dpb.fs_ltref[i]->frame->long_term_pic_num == long_term_pic_num)
|
1795 |
|
|
{
|
1796 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1797 |
|
|
}
|
1798 |
|
|
}
|
1799 |
|
|
}
|
1800 |
|
|
else
|
1801 |
|
|
{
|
1802 |
|
|
if ((dpb.fs_ltref[i]->is_reference & 1) && ((dpb.fs_ltref[i]->is_long_term & 1)))
|
1803 |
|
|
{
|
1804 |
|
|
if (dpb.fs_ltref[i]->top_field->long_term_pic_num == long_term_pic_num)
|
1805 |
|
|
{
|
1806 |
|
|
dpb.fs_ltref[i]->top_field->used_for_reference = 0;
|
1807 |
|
|
dpb.fs_ltref[i]->top_field->is_long_term = 0;
|
1808 |
|
|
dpb.fs_ltref[i]->is_reference &= 2;
|
1809 |
|
|
dpb.fs_ltref[i]->is_long_term &= 2;
|
1810 |
|
|
if (dpb.fs_ltref[i]->is_used == 3)
|
1811 |
|
|
{
|
1812 |
|
|
dpb.fs_ltref[i]->frame->used_for_reference = 0;
|
1813 |
|
|
dpb.fs_ltref[i]->frame->is_long_term = 0;
|
1814 |
|
|
}
|
1815 |
|
|
return;
|
1816 |
|
|
}
|
1817 |
|
|
}
|
1818 |
|
|
if ((dpb.fs_ltref[i]->is_reference & 2) && ((dpb.fs_ltref[i]->is_long_term & 2)))
|
1819 |
|
|
{
|
1820 |
|
|
if (dpb.fs_ltref[i]->bottom_field->long_term_pic_num == long_term_pic_num)
|
1821 |
|
|
{
|
1822 |
|
|
dpb.fs_ltref[i]->bottom_field->used_for_reference = 0;
|
1823 |
|
|
dpb.fs_ltref[i]->bottom_field->is_long_term = 0;
|
1824 |
|
|
dpb.fs_ltref[i]->is_reference &= 1;
|
1825 |
|
|
dpb.fs_ltref[i]->is_long_term &= 1;
|
1826 |
|
|
if (dpb.fs_ltref[i]->is_used == 3)
|
1827 |
|
|
{
|
1828 |
|
|
dpb.fs_ltref[i]->frame->used_for_reference = 0;
|
1829 |
|
|
dpb.fs_ltref[i]->frame->is_long_term = 0;
|
1830 |
|
|
}
|
1831 |
|
|
return;
|
1832 |
|
|
}
|
1833 |
|
|
}
|
1834 |
|
|
}
|
1835 |
|
|
}
|
1836 |
|
|
}
|
1837 |
|
|
|
1838 |
|
|
|
1839 |
|
|
/*!
|
1840 |
|
|
************************************************************************
|
1841 |
|
|
* \brief
|
1842 |
|
|
* Mark a long-term reference frame or complementary field pair unused for referemce
|
1843 |
|
|
************************************************************************
|
1844 |
|
|
*/
|
1845 |
|
|
static void unmark_long_term_frame_for_reference_by_frame_idx(int long_term_frame_idx)
|
1846 |
|
|
{
|
1847 |
|
|
unsigned i;
|
1848 |
|
|
for(i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1849 |
|
|
{
|
1850 |
|
|
if (dpb.fs_ltref[i]->long_term_frame_idx == long_term_frame_idx)
|
1851 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1852 |
|
|
}
|
1853 |
|
|
}
|
1854 |
|
|
|
1855 |
|
|
/*!
|
1856 |
|
|
************************************************************************
|
1857 |
|
|
* \brief
|
1858 |
|
|
* Mark a long-term reference field unused for reference only if it's not
|
1859 |
|
|
* the complementary field of the picture indicated by picNumX
|
1860 |
|
|
************************************************************************
|
1861 |
|
|
*/
|
1862 |
|
|
static void unmark_long_term_field_for_reference_by_frame_idx(PictureStructure structure, int long_term_frame_idx, int mark_current, unsigned curr_frame_num, int curr_pic_num)
|
1863 |
|
|
{
|
1864 |
|
|
unsigned i;
|
1865 |
|
|
|
1866 |
|
|
assert(structure!=FRAME);
|
1867 |
|
|
if (curr_pic_num<0)
|
1868 |
|
|
curr_pic_num+=(2*img->MaxFrameNum);
|
1869 |
|
|
|
1870 |
|
|
for(i=0; i<dpb.ltref_frames_in_buffer; i++)
|
1871 |
|
|
{
|
1872 |
|
|
if (dpb.fs_ltref[i]->long_term_frame_idx == long_term_frame_idx)
|
1873 |
|
|
{
|
1874 |
|
|
if (structure == TOP_FIELD)
|
1875 |
|
|
{
|
1876 |
|
|
if ((dpb.fs_ltref[i]->is_long_term == 3))
|
1877 |
|
|
{
|
1878 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1879 |
|
|
}
|
1880 |
|
|
else
|
1881 |
|
|
{
|
1882 |
|
|
if ((dpb.fs_ltref[i]->is_long_term == 1))
|
1883 |
|
|
{
|
1884 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1885 |
|
|
}
|
1886 |
|
|
else
|
1887 |
|
|
{
|
1888 |
|
|
if (mark_current)
|
1889 |
|
|
{
|
1890 |
|
|
if (dpb.last_picture)
|
1891 |
|
|
{
|
1892 |
|
|
if ( ( dpb.last_picture != dpb.fs_ltref[i] )|| dpb.last_picture->frame_num != curr_frame_num)
|
1893 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1894 |
|
|
}
|
1895 |
|
|
else
|
1896 |
|
|
{
|
1897 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1898 |
|
|
}
|
1899 |
|
|
}
|
1900 |
|
|
else
|
1901 |
|
|
{
|
1902 |
|
|
if ((dpb.fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num/2))
|
1903 |
|
|
{
|
1904 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1905 |
|
|
}
|
1906 |
|
|
}
|
1907 |
|
|
}
|
1908 |
|
|
}
|
1909 |
|
|
}
|
1910 |
|
|
if (structure == BOTTOM_FIELD)
|
1911 |
|
|
{
|
1912 |
|
|
if ((dpb.fs_ltref[i]->is_long_term == 3))
|
1913 |
|
|
{
|
1914 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1915 |
|
|
}
|
1916 |
|
|
else
|
1917 |
|
|
{
|
1918 |
|
|
if ((dpb.fs_ltref[i]->is_long_term == 2))
|
1919 |
|
|
{
|
1920 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1921 |
|
|
}
|
1922 |
|
|
else
|
1923 |
|
|
{
|
1924 |
|
|
if (mark_current)
|
1925 |
|
|
{
|
1926 |
|
|
if (dpb.last_picture)
|
1927 |
|
|
{
|
1928 |
|
|
if ( ( dpb.last_picture != dpb.fs_ltref[i] )|| dpb.last_picture->frame_num != curr_frame_num)
|
1929 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1930 |
|
|
}
|
1931 |
|
|
else
|
1932 |
|
|
{
|
1933 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1934 |
|
|
}
|
1935 |
|
|
}
|
1936 |
|
|
else
|
1937 |
|
|
{
|
1938 |
|
|
if ((dpb.fs_ltref[i]->frame_num) != (unsigned)(curr_pic_num/2))
|
1939 |
|
|
{
|
1940 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
1941 |
|
|
}
|
1942 |
|
|
}
|
1943 |
|
|
}
|
1944 |
|
|
}
|
1945 |
|
|
}
|
1946 |
|
|
}
|
1947 |
|
|
}
|
1948 |
|
|
}
|
1949 |
|
|
|
1950 |
|
|
|
1951 |
|
|
/*!
|
1952 |
|
|
************************************************************************
|
1953 |
|
|
* \brief
|
1954 |
|
|
* mark a picture as long-term reference
|
1955 |
|
|
************************************************************************
|
1956 |
|
|
*/
|
1957 |
|
|
static void mark_pic_long_term(StorablePicture* p, int long_term_frame_idx, int picNumX)
|
1958 |
|
|
{
|
1959 |
|
|
unsigned i;
|
1960 |
|
|
int add_top, add_bottom;
|
1961 |
|
|
|
1962 |
|
|
if (p->structure == FRAME)
|
1963 |
|
|
{
|
1964 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
1965 |
|
|
{
|
1966 |
|
|
if (dpb.fs_ref[i]->is_reference == 3)
|
1967 |
|
|
{
|
1968 |
|
|
if ((!dpb.fs_ref[i]->frame->is_long_term)&&(dpb.fs_ref[i]->frame->pic_num == picNumX))
|
1969 |
|
|
{
|
1970 |
|
|
dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_frame_idx
|
1971 |
|
|
= long_term_frame_idx;
|
1972 |
|
|
dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
|
1973 |
|
|
dpb.fs_ref[i]->frame->is_long_term = 1;
|
1974 |
|
|
|
1975 |
|
|
if (dpb.fs_ref[i]->top_field && dpb.fs_ref[i]->bottom_field)
|
1976 |
|
|
{
|
1977 |
|
|
dpb.fs_ref[i]->top_field->long_term_frame_idx = dpb.fs_ref[i]->bottom_field->long_term_frame_idx
|
1978 |
|
|
= long_term_frame_idx;
|
1979 |
|
|
dpb.fs_ref[i]->top_field->long_term_pic_num = long_term_frame_idx;
|
1980 |
|
|
dpb.fs_ref[i]->bottom_field->long_term_pic_num = long_term_frame_idx;
|
1981 |
|
|
|
1982 |
|
|
dpb.fs_ref[i]->top_field->is_long_term = dpb.fs_ref[i]->bottom_field->is_long_term
|
1983 |
|
|
= 1;
|
1984 |
|
|
|
1985 |
|
|
}
|
1986 |
|
|
dpb.fs_ref[i]->is_long_term = 3;
|
1987 |
|
|
return;
|
1988 |
|
|
}
|
1989 |
|
|
}
|
1990 |
|
|
}
|
1991 |
|
|
printf ("Warning: reference frame for long term marking not found\n");
|
1992 |
|
|
}
|
1993 |
|
|
else
|
1994 |
|
|
{
|
1995 |
|
|
if (p->structure == TOP_FIELD)
|
1996 |
|
|
{
|
1997 |
|
|
add_top = 1;
|
1998 |
|
|
add_bottom = 0;
|
1999 |
|
|
}
|
2000 |
|
|
else
|
2001 |
|
|
{
|
2002 |
|
|
add_top = 0;
|
2003 |
|
|
add_bottom = 1;
|
2004 |
|
|
}
|
2005 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
2006 |
|
|
{
|
2007 |
|
|
if (dpb.fs_ref[i]->is_reference & 1)
|
2008 |
|
|
{
|
2009 |
|
|
if ((!dpb.fs_ref[i]->top_field->is_long_term)&&(dpb.fs_ref[i]->top_field->pic_num == picNumX))
|
2010 |
|
|
{
|
2011 |
|
|
if ((dpb.fs_ref[i]->is_long_term) && (dpb.fs_ref[i]->long_term_frame_idx != long_term_frame_idx))
|
2012 |
|
|
{
|
2013 |
|
|
printf ("Warning: assigning long_term_frame_idx different from other field\n");
|
2014 |
|
|
}
|
2015 |
|
|
|
2016 |
|
|
dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->top_field->long_term_frame_idx
|
2017 |
|
|
= long_term_frame_idx;
|
2018 |
|
|
dpb.fs_ref[i]->top_field->long_term_pic_num = 2 * long_term_frame_idx + add_top;
|
2019 |
|
|
dpb.fs_ref[i]->top_field->is_long_term = 1;
|
2020 |
|
|
dpb.fs_ref[i]->is_long_term |= 1;
|
2021 |
|
|
if (dpb.fs_ref[i]->is_long_term == 3)
|
2022 |
|
|
{
|
2023 |
|
|
dpb.fs_ref[i]->frame->is_long_term = 1;
|
2024 |
|
|
dpb.fs_ref[i]->frame->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
|
2025 |
|
|
}
|
2026 |
|
|
return;
|
2027 |
|
|
}
|
2028 |
|
|
}
|
2029 |
|
|
if (dpb.fs_ref[i]->is_reference & 2)
|
2030 |
|
|
{
|
2031 |
|
|
if ((!dpb.fs_ref[i]->bottom_field->is_long_term)&&(dpb.fs_ref[i]->bottom_field->pic_num == picNumX))
|
2032 |
|
|
{
|
2033 |
|
|
if ((dpb.fs_ref[i]->is_long_term) && (dpb.fs_ref[i]->long_term_frame_idx != long_term_frame_idx))
|
2034 |
|
|
{
|
2035 |
|
|
printf ("Warning: assigning long_term_frame_idx different from other field\n");
|
2036 |
|
|
}
|
2037 |
|
|
|
2038 |
|
|
dpb.fs_ref[i]->long_term_frame_idx = dpb.fs_ref[i]->bottom_field->long_term_frame_idx
|
2039 |
|
|
= long_term_frame_idx;
|
2040 |
|
|
dpb.fs_ref[i]->bottom_field->long_term_pic_num = 2 * long_term_frame_idx + add_top;
|
2041 |
|
|
dpb.fs_ref[i]->bottom_field->is_long_term = 1;
|
2042 |
|
|
dpb.fs_ref[i]->is_long_term |= 2;
|
2043 |
|
|
if (dpb.fs_ref[i]->is_long_term == 3)
|
2044 |
|
|
{
|
2045 |
|
|
dpb.fs_ref[i]->frame->is_long_term = 1;
|
2046 |
|
|
dpb.fs_ref[i]->frame->long_term_frame_idx = dpb.fs_ref[i]->frame->long_term_pic_num = long_term_frame_idx;
|
2047 |
|
|
}
|
2048 |
|
|
return;
|
2049 |
|
|
}
|
2050 |
|
|
}
|
2051 |
|
|
}
|
2052 |
|
|
printf ("Warning: reference field for long term marking not found\n");
|
2053 |
|
|
}
|
2054 |
|
|
}
|
2055 |
|
|
|
2056 |
|
|
|
2057 |
|
|
/*!
|
2058 |
|
|
************************************************************************
|
2059 |
|
|
* \brief
|
2060 |
|
|
* Assign a long term frame index to a short term picture
|
2061 |
|
|
************************************************************************
|
2062 |
|
|
*/
|
2063 |
|
|
static void mm_assign_long_term_frame_idx(StorablePicture* p, int difference_of_pic_nums_minus1, int long_term_frame_idx)
|
2064 |
|
|
{
|
2065 |
|
|
int picNumX;
|
2066 |
|
|
|
2067 |
|
|
picNumX = get_pic_num_x(p, difference_of_pic_nums_minus1);
|
2068 |
|
|
|
2069 |
|
|
// remove frames/fields with same long_term_frame_idx
|
2070 |
|
|
if (p->structure == FRAME)
|
2071 |
|
|
{
|
2072 |
|
|
unmark_long_term_frame_for_reference_by_frame_idx(long_term_frame_idx);
|
2073 |
|
|
}
|
2074 |
|
|
else
|
2075 |
|
|
{
|
2076 |
|
|
unsigned i;
|
2077 |
|
|
PictureStructure structure = FRAME;
|
2078 |
|
|
|
2079 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
2080 |
|
|
{
|
2081 |
|
|
if (dpb.fs_ref[i]->is_reference & 1)
|
2082 |
|
|
{
|
2083 |
|
|
if (dpb.fs_ref[i]->top_field->pic_num == picNumX)
|
2084 |
|
|
{
|
2085 |
|
|
structure = TOP_FIELD;
|
2086 |
|
|
break;
|
2087 |
|
|
}
|
2088 |
|
|
}
|
2089 |
|
|
if (dpb.fs_ref[i]->is_reference & 2)
|
2090 |
|
|
{
|
2091 |
|
|
if (dpb.fs_ref[i]->bottom_field->pic_num == picNumX)
|
2092 |
|
|
{
|
2093 |
|
|
structure = BOTTOM_FIELD;
|
2094 |
|
|
break;
|
2095 |
|
|
}
|
2096 |
|
|
}
|
2097 |
|
|
}
|
2098 |
|
|
if (structure==FRAME)
|
2099 |
|
|
{
|
2100 |
|
|
error ("field for long term marking not found",200);
|
2101 |
|
|
}
|
2102 |
|
|
|
2103 |
|
|
unmark_long_term_field_for_reference_by_frame_idx(structure, long_term_frame_idx, 0, 0, picNumX);
|
2104 |
|
|
}
|
2105 |
|
|
|
2106 |
|
|
mark_pic_long_term(p, long_term_frame_idx, picNumX);
|
2107 |
|
|
}
|
2108 |
|
|
|
2109 |
|
|
/*!
|
2110 |
|
|
************************************************************************
|
2111 |
|
|
* \brief
|
2112 |
|
|
* Set new max long_term_frame_idx
|
2113 |
|
|
************************************************************************
|
2114 |
|
|
*/
|
2115 |
|
|
void mm_update_max_long_term_frame_idx(int max_long_term_frame_idx_plus1)
|
2116 |
|
|
{
|
2117 |
|
|
unsigned i;
|
2118 |
|
|
|
2119 |
|
|
dpb.max_long_term_pic_idx = max_long_term_frame_idx_plus1 - 1;
|
2120 |
|
|
|
2121 |
|
|
// check for invalid frames
|
2122 |
|
|
for (i=0; i<dpb.ltref_frames_in_buffer; i++)
|
2123 |
|
|
{
|
2124 |
|
|
if (dpb.fs_ltref[i]->long_term_frame_idx > dpb.max_long_term_pic_idx)
|
2125 |
|
|
{
|
2126 |
|
|
unmark_for_long_term_reference(dpb.fs_ltref[i]);
|
2127 |
|
|
}
|
2128 |
|
|
}
|
2129 |
|
|
}
|
2130 |
|
|
|
2131 |
|
|
|
2132 |
|
|
/*!
|
2133 |
|
|
************************************************************************
|
2134 |
|
|
* \brief
|
2135 |
|
|
* Mark all long term reference pictures unused for reference
|
2136 |
|
|
************************************************************************
|
2137 |
|
|
*/
|
2138 |
|
|
static void mm_unmark_all_long_term_for_reference ()
|
2139 |
|
|
{
|
2140 |
|
|
mm_update_max_long_term_frame_idx(0);
|
2141 |
|
|
}
|
2142 |
|
|
|
2143 |
|
|
/*!
|
2144 |
|
|
************************************************************************
|
2145 |
|
|
* \brief
|
2146 |
|
|
* Mark all short term reference pictures unused for reference
|
2147 |
|
|
************************************************************************
|
2148 |
|
|
*/
|
2149 |
|
|
static void mm_unmark_all_short_term_for_reference ()
|
2150 |
|
|
{
|
2151 |
|
|
unsigned int i;
|
2152 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
2153 |
|
|
{
|
2154 |
|
|
unmark_for_reference(dpb.fs_ref[i]);
|
2155 |
|
|
}
|
2156 |
|
|
update_ref_list();
|
2157 |
|
|
}
|
2158 |
|
|
|
2159 |
|
|
|
2160 |
|
|
/*!
|
2161 |
|
|
************************************************************************
|
2162 |
|
|
* \brief
|
2163 |
|
|
* Mark the current picture used for long term reference
|
2164 |
|
|
************************************************************************
|
2165 |
|
|
*/
|
2166 |
|
|
static void mm_mark_current_picture_long_term(StorablePicture *p, int long_term_frame_idx)
|
2167 |
|
|
{
|
2168 |
|
|
// remove long term pictures with same long_term_frame_idx
|
2169 |
|
|
if (p->structure == FRAME)
|
2170 |
|
|
{
|
2171 |
|
|
unmark_long_term_frame_for_reference_by_frame_idx(long_term_frame_idx);
|
2172 |
|
|
}
|
2173 |
|
|
else
|
2174 |
|
|
{
|
2175 |
|
|
unmark_long_term_field_for_reference_by_frame_idx(p->structure, long_term_frame_idx, 1, p->pic_num, 0);
|
2176 |
|
|
}
|
2177 |
|
|
|
2178 |
|
|
p->is_long_term = 1;
|
2179 |
|
|
p->long_term_frame_idx = long_term_frame_idx;
|
2180 |
|
|
}
|
2181 |
|
|
|
2182 |
|
|
|
2183 |
|
|
/*!
|
2184 |
|
|
************************************************************************
|
2185 |
|
|
* \brief
|
2186 |
|
|
* Perform Adaptive memory control decoded reference picture marking process
|
2187 |
|
|
************************************************************************
|
2188 |
|
|
*/
|
2189 |
|
|
static void adaptive_memory_management(StorablePicture* p)
|
2190 |
|
|
{
|
2191 |
|
|
DecRefPicMarking_t *tmp_drpm;
|
2192 |
|
|
|
2193 |
|
|
img->last_has_mmco_5 = 0;
|
2194 |
|
|
|
2195 |
|
|
assert (!p->idr_flag);
|
2196 |
|
|
assert (p->adaptive_ref_pic_buffering_flag);
|
2197 |
|
|
|
2198 |
|
|
while (p->dec_ref_pic_marking_buffer)
|
2199 |
|
|
{
|
2200 |
|
|
tmp_drpm = p->dec_ref_pic_marking_buffer;
|
2201 |
|
|
switch (tmp_drpm->memory_management_control_operation)
|
2202 |
|
|
{
|
2203 |
|
|
case 0:
|
2204 |
|
|
if (tmp_drpm->Next != NULL)
|
2205 |
|
|
{
|
2206 |
|
|
error ("memory_management_control_operation = 0 not last operation in buffer", 500);
|
2207 |
|
|
}
|
2208 |
|
|
break;
|
2209 |
|
|
case 1:
|
2210 |
|
|
mm_unmark_short_term_for_reference(p, tmp_drpm->difference_of_pic_nums_minus1);
|
2211 |
|
|
update_ref_list();
|
2212 |
|
|
break;
|
2213 |
|
|
case 2:
|
2214 |
|
|
mm_unmark_long_term_for_reference(p, tmp_drpm->long_term_pic_num);
|
2215 |
|
|
update_ltref_list();
|
2216 |
|
|
break;
|
2217 |
|
|
case 3:
|
2218 |
|
|
mm_assign_long_term_frame_idx(p, tmp_drpm->difference_of_pic_nums_minus1, tmp_drpm->long_term_frame_idx);
|
2219 |
|
|
update_ref_list();
|
2220 |
|
|
update_ltref_list();
|
2221 |
|
|
break;
|
2222 |
|
|
case 4:
|
2223 |
|
|
mm_update_max_long_term_frame_idx (tmp_drpm->max_long_term_frame_idx_plus1);
|
2224 |
|
|
update_ltref_list();
|
2225 |
|
|
break;
|
2226 |
|
|
case 5:
|
2227 |
|
|
mm_unmark_all_short_term_for_reference();
|
2228 |
|
|
mm_unmark_all_long_term_for_reference();
|
2229 |
|
|
img->last_has_mmco_5 = 1;
|
2230 |
|
|
break;
|
2231 |
|
|
case 6:
|
2232 |
|
|
mm_mark_current_picture_long_term(p, tmp_drpm->long_term_frame_idx);
|
2233 |
|
|
check_num_ref();
|
2234 |
|
|
break;
|
2235 |
|
|
default:
|
2236 |
|
|
error ("invalid memory_management_control_operation in buffer", 500);
|
2237 |
|
|
}
|
2238 |
|
|
p->dec_ref_pic_marking_buffer = tmp_drpm->Next;
|
2239 |
|
|
free (tmp_drpm);
|
2240 |
|
|
}
|
2241 |
|
|
if ( img->last_has_mmco_5 )
|
2242 |
|
|
{
|
2243 |
|
|
p->pic_num = p->frame_num = 0;
|
2244 |
|
|
|
2245 |
|
|
switch (p->structure)
|
2246 |
|
|
{
|
2247 |
|
|
case TOP_FIELD:
|
2248 |
|
|
{
|
2249 |
|
|
p->poc = p->top_poc = img->toppoc =0;
|
2250 |
|
|
break;
|
2251 |
|
|
}
|
2252 |
|
|
case BOTTOM_FIELD:
|
2253 |
|
|
{
|
2254 |
|
|
p->poc = p->bottom_poc = img->bottompoc = 0;
|
2255 |
|
|
break;
|
2256 |
|
|
}
|
2257 |
|
|
case FRAME:
|
2258 |
|
|
{
|
2259 |
|
|
p->top_poc -= p->poc;
|
2260 |
|
|
p->bottom_poc -= p->poc;
|
2261 |
|
|
|
2262 |
|
|
img->toppoc = p->top_poc;
|
2263 |
|
|
img->bottompoc = p->bottom_poc;
|
2264 |
|
|
|
2265 |
|
|
p->poc = imin (p->top_poc, p->bottom_poc);
|
2266 |
|
|
img->framepoc = p->poc;
|
2267 |
|
|
break;
|
2268 |
|
|
}
|
2269 |
|
|
}
|
2270 |
|
|
img->ThisPOC = p->poc;
|
2271 |
|
|
flush_dpb();
|
2272 |
|
|
}
|
2273 |
|
|
}
|
2274 |
|
|
|
2275 |
|
|
|
2276 |
|
|
/*!
|
2277 |
|
|
************************************************************************
|
2278 |
|
|
* \brief
|
2279 |
|
|
* Store a picture in DPB. This includes cheking for space in DPB and
|
2280 |
|
|
* flushing frames.
|
2281 |
|
|
* If we received a frame, we need to check for a new store, if we
|
2282 |
|
|
* got a field, check if it's the second field of an already allocated
|
2283 |
|
|
* store.
|
2284 |
|
|
*
|
2285 |
|
|
* \param p
|
2286 |
|
|
* Picture to be stored
|
2287 |
|
|
*
|
2288 |
|
|
************************************************************************
|
2289 |
|
|
*/
|
2290 |
|
|
void store_picture_in_dpb(StorablePicture* p)
|
2291 |
|
|
{
|
2292 |
|
|
unsigned i;
|
2293 |
|
|
int poc, pos;
|
2294 |
|
|
// picture error concealment
|
2295 |
|
|
extern int pocs_in_dpb[100];
|
2296 |
|
|
// diagnostics
|
2297 |
|
|
//printf ("Storing (%s) non-ref pic with frame_num #%d\n", (p->type == FRAME)?"FRAME":(p->type == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", p->pic_num);
|
2298 |
|
|
// if frame, check for new store,
|
2299 |
|
|
assert (p!=NULL);
|
2300 |
|
|
|
2301 |
|
|
img->last_has_mmco_5=0;
|
2302 |
|
|
img->last_pic_bottom_field = (p->structure == BOTTOM_FIELD);
|
2303 |
|
|
|
2304 |
|
|
if (p->idr_flag)
|
2305 |
|
|
{
|
2306 |
|
|
idr_memory_management(p);
|
2307 |
|
|
// picture error concealment
|
2308 |
|
|
memset(pocs_in_dpb, 0, sizeof(int)*100);
|
2309 |
|
|
}
|
2310 |
|
|
else
|
2311 |
|
|
{
|
2312 |
|
|
// adaptive memory management
|
2313 |
|
|
if (p->used_for_reference && (p->adaptive_ref_pic_buffering_flag))
|
2314 |
|
|
adaptive_memory_management(p);
|
2315 |
|
|
}
|
2316 |
|
|
|
2317 |
|
|
if ((p->structure==TOP_FIELD)||(p->structure==BOTTOM_FIELD))
|
2318 |
|
|
{
|
2319 |
|
|
// check for frame store with same pic_number
|
2320 |
|
|
if (dpb.last_picture)
|
2321 |
|
|
{
|
2322 |
|
|
if ((int)dpb.last_picture->frame_num == p->pic_num)
|
2323 |
|
|
{
|
2324 |
|
|
if (((p->structure==TOP_FIELD)&&(dpb.last_picture->is_used==2))||((p->structure==BOTTOM_FIELD)&&(dpb.last_picture->is_used==1)))
|
2325 |
|
|
{
|
2326 |
|
|
if ((p->used_for_reference && (dpb.last_picture->is_orig_reference!=0))||
|
2327 |
|
|
(!p->used_for_reference && (dpb.last_picture->is_orig_reference==0)))
|
2328 |
|
|
{
|
2329 |
|
|
insert_picture_in_dpb(dpb.last_picture, p);
|
2330 |
|
|
update_ref_list();
|
2331 |
|
|
update_ltref_list();
|
2332 |
|
|
dump_dpb();
|
2333 |
|
|
dpb.last_picture = NULL;
|
2334 |
|
|
return;
|
2335 |
|
|
}
|
2336 |
|
|
}
|
2337 |
|
|
}
|
2338 |
|
|
}
|
2339 |
|
|
}
|
2340 |
|
|
|
2341 |
|
|
// this is a frame or a field which has no stored complementary field
|
2342 |
|
|
|
2343 |
|
|
// sliding window, if necessary
|
2344 |
|
|
if ((!p->idr_flag)&&(p->used_for_reference && (!p->adaptive_ref_pic_buffering_flag)))
|
2345 |
|
|
{
|
2346 |
|
|
sliding_window_memory_management(p);
|
2347 |
|
|
}
|
2348 |
|
|
|
2349 |
|
|
// picture error concealment
|
2350 |
|
|
if(img->conceal_mode != 0)
|
2351 |
|
|
for(i=0;i<dpb.size;i++)
|
2352 |
|
|
if(dpb.fs[i]->is_reference)
|
2353 |
|
|
dpb.fs[i]->concealment_reference = 1;
|
2354 |
|
|
|
2355 |
|
|
// first try to remove unused frames
|
2356 |
|
|
if (dpb.used_size==dpb.size)
|
2357 |
|
|
{
|
2358 |
|
|
// picture error concealment
|
2359 |
|
|
if (img->conceal_mode != 0)
|
2360 |
|
|
conceal_non_ref_pics(2);
|
2361 |
|
|
remove_unused_frame_from_dpb();
|
2362 |
|
|
|
2363 |
|
|
if(img->conceal_mode != 0)
|
2364 |
|
|
sliding_window_poc_management(p);
|
2365 |
|
|
}
|
2366 |
|
|
|
2367 |
|
|
// then output frames until one can be removed
|
2368 |
|
|
while (dpb.used_size==dpb.size)
|
2369 |
|
|
{
|
2370 |
|
|
// non-reference frames may be output directly
|
2371 |
|
|
if (!p->used_for_reference)
|
2372 |
|
|
{
|
2373 |
|
|
get_smallest_poc(&poc, &pos);
|
2374 |
|
|
if ((-1==pos) || (p->poc < poc))
|
2375 |
|
|
{
|
2376 |
|
|
direct_output(p, p_out);
|
2377 |
|
|
return;
|
2378 |
|
|
}
|
2379 |
|
|
}
|
2380 |
|
|
// flush a frame
|
2381 |
|
|
output_one_frame_from_dpb();
|
2382 |
|
|
}
|
2383 |
|
|
|
2384 |
|
|
// check for duplicate frame number in short term reference buffer
|
2385 |
|
|
if ((p->used_for_reference)&&(!p->is_long_term))
|
2386 |
|
|
{
|
2387 |
|
|
for (i=0; i<dpb.ref_frames_in_buffer; i++)
|
2388 |
|
|
{
|
2389 |
|
|
if (dpb.fs_ref[i]->frame_num == p->frame_num)
|
2390 |
|
|
{
|
2391 |
|
|
error("duplicate frame_num in short-term reference picture buffer", 500);
|
2392 |
|
|
}
|
2393 |
|
|
}
|
2394 |
|
|
|
2395 |
|
|
}
|
2396 |
|
|
// store at end of buffer
|
2397 |
|
|
// printf ("store frame/field at pos %d\n",dpb.used_size);
|
2398 |
|
|
insert_picture_in_dpb(dpb.fs[dpb.used_size],p);
|
2399 |
|
|
|
2400 |
|
|
// picture error concealment
|
2401 |
|
|
if (p->idr_flag)
|
2402 |
|
|
{
|
2403 |
|
|
img->earlier_missing_poc = 0;
|
2404 |
|
|
}
|
2405 |
|
|
|
2406 |
|
|
if (p->structure != FRAME)
|
2407 |
|
|
{
|
2408 |
|
|
dpb.last_picture = dpb.fs[dpb.used_size];
|
2409 |
|
|
}
|
2410 |
|
|
else
|
2411 |
|
|
{
|
2412 |
|
|
dpb.last_picture = NULL;
|
2413 |
|
|
}
|
2414 |
|
|
|
2415 |
|
|
dpb.used_size++;
|
2416 |
|
|
|
2417 |
|
|
if(img->conceal_mode != 0)
|
2418 |
|
|
pocs_in_dpb[dpb.used_size-1] = p->poc;
|
2419 |
|
|
|
2420 |
|
|
update_ref_list();
|
2421 |
|
|
update_ltref_list();
|
2422 |
|
|
|
2423 |
|
|
check_num_ref();
|
2424 |
|
|
|
2425 |
|
|
dump_dpb();
|
2426 |
|
|
}
|
2427 |
|
|
|
2428 |
|
|
/*!
|
2429 |
|
|
************************************************************************
|
2430 |
|
|
* \brief
|
2431 |
|
|
* Insert the picture into the DPB. A free DPB position is necessary
|
2432 |
|
|
* for frames, .
|
2433 |
|
|
*
|
2434 |
|
|
* \param fs
|
2435 |
|
|
* FrameStore into which the picture will be inserted
|
2436 |
|
|
* \param p
|
2437 |
|
|
* StorablePicture to be inserted
|
2438 |
|
|
*
|
2439 |
|
|
************************************************************************
|
2440 |
|
|
*/
|
2441 |
|
|
static void insert_picture_in_dpb(FrameStore* fs, StorablePicture* p)
|
2442 |
|
|
{
|
2443 |
|
|
// printf ("insert (%s) pic with frame_num #%d, poc %d\n", (p->structure == FRAME)?"FRAME":(p->structure == TOP_FIELD)?"TOP_FIELD":"BOTTOM_FIELD", p->pic_num, p->poc);
|
2444 |
|
|
assert (p!=NULL);
|
2445 |
|
|
assert (fs!=NULL);
|
2446 |
|
|
switch (p->structure)
|
2447 |
|
|
{
|
2448 |
|
|
case FRAME:
|
2449 |
|
|
fs->frame = p;
|
2450 |
|
|
fs->is_used = 3;
|
2451 |
|
|
if (p->used_for_reference)
|
2452 |
|
|
{
|
2453 |
|
|
fs->is_reference = 3;
|
2454 |
|
|
fs->is_orig_reference = 3;
|
2455 |
|
|
if (p->is_long_term)
|
2456 |
|
|
{
|
2457 |
|
|
fs->is_long_term = 3;
|
2458 |
|
|
fs->long_term_frame_idx = p->long_term_frame_idx;
|
2459 |
|
|
}
|
2460 |
|
|
}
|
2461 |
|
|
// generate field views
|
2462 |
|
|
dpb_split_field(fs);
|
2463 |
|
|
break;
|
2464 |
|
|
case TOP_FIELD:
|
2465 |
|
|
fs->top_field = p;
|
2466 |
|
|
fs->is_used |= 1;
|
2467 |
|
|
if (p->used_for_reference)
|
2468 |
|
|
{
|
2469 |
|
|
fs->is_reference |= 1;
|
2470 |
|
|
fs->is_orig_reference |= 1;
|
2471 |
|
|
if (p->is_long_term)
|
2472 |
|
|
{
|
2473 |
|
|
fs->is_long_term |= 1;
|
2474 |
|
|
fs->long_term_frame_idx = p->long_term_frame_idx;
|
2475 |
|
|
}
|
2476 |
|
|
}
|
2477 |
|
|
if (fs->is_used == 3)
|
2478 |
|
|
{
|
2479 |
|
|
// generate frame view
|
2480 |
|
|
dpb_combine_field(fs);
|
2481 |
|
|
} else
|
2482 |
|
|
{
|
2483 |
|
|
fs->poc = p->poc;
|
2484 |
|
|
gen_field_ref_ids(p);
|
2485 |
|
|
}
|
2486 |
|
|
break;
|
2487 |
|
|
case BOTTOM_FIELD:
|
2488 |
|
|
fs->bottom_field = p;
|
2489 |
|
|
fs->is_used |= 2;
|
2490 |
|
|
if (p->used_for_reference)
|
2491 |
|
|
{
|
2492 |
|
|
fs->is_reference |= 2;
|
2493 |
|
|
fs->is_orig_reference |= 2;
|
2494 |
|
|
if (p->is_long_term)
|
2495 |
|
|
{
|
2496 |
|
|
fs->is_long_term |= 2;
|
2497 |
|
|
fs->long_term_frame_idx = p->long_term_frame_idx;
|
2498 |
|
|
}
|
2499 |
|
|
}
|
2500 |
|
|
if (fs->is_used == 3)
|
2501 |
|
|
{
|
2502 |
|
|
// generate frame view
|
2503 |
|
|
dpb_combine_field(fs);
|
2504 |
|
|
} else
|
2505 |
|
|
{
|
2506 |
|
|
fs->poc = p->poc;
|
2507 |
|
|
gen_field_ref_ids(p);
|
2508 |
|
|
}
|
2509 |
|
|
break;
|
2510 |
|
|
}
|
2511 |
|
|
fs->frame_num = p->pic_num;
|
2512 |
|
|
fs->recovery_frame = p->recovery_frame;
|
2513 |
|
|
|
2514 |
|
|
fs->is_output = p->is_output;
|
2515 |
|
|
|
2516 |
|
|
if (fs->is_used==3)
|
2517 |
|
|
{
|
2518 |
|
|
if (-1!=p_ref && !input->silent)
|
2519 |
|
|
find_snr(snr, fs->frame, p_ref);
|
2520 |
|
|
}
|
2521 |
|
|
}
|
2522 |
|
|
|
2523 |
|
|
/*!
|
2524 |
|
|
************************************************************************
|
2525 |
|
|
* \brief
|
2526 |
|
|
* Check if one of the frames/fields in frame store is used for reference
|
2527 |
|
|
************************************************************************
|
2528 |
|
|
*/
|
2529 |
|
|
static int is_used_for_reference(FrameStore* fs)
|
2530 |
|
|
{
|
2531 |
|
|
if (fs->is_reference)
|
2532 |
|
|
{
|
2533 |
|
|
return 1;
|
2534 |
|
|
}
|
2535 |
|
|
|
2536 |
|
|
if (fs->is_used == 3) // frame
|
2537 |
|
|
{
|
2538 |
|
|
if (fs->frame->used_for_reference)
|
2539 |
|
|
{
|
2540 |
|
|
return 1;
|
2541 |
|
|
}
|
2542 |
|
|
}
|
2543 |
|
|
|
2544 |
|
|
if (fs->is_used & 1) // top field
|
2545 |
|
|
{
|
2546 |
|
|
if (fs->top_field)
|
2547 |
|
|
{
|
2548 |
|
|
if (fs->top_field->used_for_reference)
|
2549 |
|
|
{
|
2550 |
|
|
return 1;
|
2551 |
|
|
}
|
2552 |
|
|
}
|
2553 |
|
|
}
|
2554 |
|
|
|
2555 |
|
|
if (fs->is_used & 2) // bottom field
|
2556 |
|
|
{
|
2557 |
|
|
if (fs->bottom_field)
|
2558 |
|
|
{
|
2559 |
|
|
if (fs->bottom_field->used_for_reference)
|
2560 |
|
|
{
|
2561 |
|
|
return 1;
|
2562 |
|
|
}
|
2563 |
|
|
}
|
2564 |
|
|
}
|
2565 |
|
|
return 0;
|
2566 |
|
|
}
|
2567 |
|
|
|
2568 |
|
|
|
2569 |
|
|
/*!
|
2570 |
|
|
************************************************************************
|
2571 |
|
|
* \brief
|
2572 |
|
|
* Check if one of the frames/fields in frame store is used for short-term reference
|
2573 |
|
|
************************************************************************
|
2574 |
|
|
*/
|
2575 |
|
|
static int is_short_term_reference(FrameStore* fs)
|
2576 |
|
|
{
|
2577 |
|
|
|
2578 |
|
|
if (fs->is_used==3) // frame
|
2579 |
|
|
{
|
2580 |
|
|
if ((fs->frame->used_for_reference)&&(!fs->frame->is_long_term))
|
2581 |
|
|
{
|
2582 |
|
|
return 1;
|
2583 |
|
|
}
|
2584 |
|
|
}
|
2585 |
|
|
|
2586 |
|
|
if (fs->is_used & 1) // top field
|
2587 |
|
|
{
|
2588 |
|
|
if (fs->top_field)
|
2589 |
|
|
{
|
2590 |
|
|
if ((fs->top_field->used_for_reference)&&(!fs->top_field->is_long_term))
|
2591 |
|
|
{
|
2592 |
|
|
return 1;
|
2593 |
|
|
}
|
2594 |
|
|
}
|
2595 |
|
|
}
|
2596 |
|
|
|
2597 |
|
|
if (fs->is_used & 2) // bottom field
|
2598 |
|
|
{
|
2599 |
|
|
if (fs->bottom_field)
|
2600 |
|
|
{
|
2601 |
|
|
if ((fs->bottom_field->used_for_reference)&&(!fs->bottom_field->is_long_term))
|
2602 |
|
|
{
|
2603 |
|
|
return 1;
|
2604 |
|
|
}
|
2605 |
|
|
}
|
2606 |
|
|
}
|
2607 |
|
|
return 0;
|
2608 |
|
|
}
|
2609 |
|
|
|
2610 |
|
|
|
2611 |
|
|
/*!
|
2612 |
|
|
************************************************************************
|
2613 |
|
|
* \brief
|
2614 |
|
|
* Check if one of the frames/fields in frame store is used for short-term reference
|
2615 |
|
|
************************************************************************
|
2616 |
|
|
*/
|
2617 |
|
|
static int is_long_term_reference(FrameStore* fs)
|
2618 |
|
|
{
|
2619 |
|
|
|
2620 |
|
|
if (fs->is_used==3) // frame
|
2621 |
|
|
{
|
2622 |
|
|
if ((fs->frame->used_for_reference)&&(fs->frame->is_long_term))
|
2623 |
|
|
{
|
2624 |
|
|
return 1;
|
2625 |
|
|
}
|
2626 |
|
|
}
|
2627 |
|
|
|
2628 |
|
|
if (fs->is_used & 1) // top field
|
2629 |
|
|
{
|
2630 |
|
|
if (fs->top_field)
|
2631 |
|
|
{
|
2632 |
|
|
if ((fs->top_field->used_for_reference)&&(fs->top_field->is_long_term))
|
2633 |
|
|
{
|
2634 |
|
|
return 1;
|
2635 |
|
|
}
|
2636 |
|
|
}
|
2637 |
|
|
}
|
2638 |
|
|
|
2639 |
|
|
if (fs->is_used & 2) // bottom field
|
2640 |
|
|
{
|
2641 |
|
|
if (fs->bottom_field)
|
2642 |
|
|
{
|
2643 |
|
|
if ((fs->bottom_field->used_for_reference)&&(fs->bottom_field->is_long_term))
|
2644 |
|
|
{
|
2645 |
|
|
return 1;
|
2646 |
|
|
}
|
2647 |
|
|
}
|
2648 |
|
|
}
|
2649 |
|
|
return 0;
|
2650 |
|
|
}
|
2651 |
|
|
|
2652 |
|
|
|
2653 |
|
|
/*!
|
2654 |
|
|
************************************************************************
|
2655 |
|
|
* \brief
|
2656 |
|
|
* remove one frame from DPB
|
2657 |
|
|
************************************************************************
|
2658 |
|
|
*/
|
2659 |
|
|
static void remove_frame_from_dpb(int pos)
|
2660 |
|
|
{
|
2661 |
|
|
FrameStore* fs = dpb.fs[pos];
|
2662 |
|
|
FrameStore* tmp;
|
2663 |
|
|
unsigned i;
|
2664 |
|
|
|
2665 |
|
|
// printf ("remove frame with frame_num #%d\n", fs->frame_num);
|
2666 |
|
|
switch (fs->is_used)
|
2667 |
|
|
{
|
2668 |
|
|
case 3:
|
2669 |
|
|
free_storable_picture(fs->frame);
|
2670 |
|
|
free_storable_picture(fs->top_field);
|
2671 |
|
|
free_storable_picture(fs->bottom_field);
|
2672 |
|
|
fs->frame=NULL;
|
2673 |
|
|
fs->top_field=NULL;
|
2674 |
|
|
fs->bottom_field=NULL;
|
2675 |
|
|
break;
|
2676 |
|
|
case 2:
|
2677 |
|
|
free_storable_picture(fs->bottom_field);
|
2678 |
|
|
fs->bottom_field=NULL;
|
2679 |
|
|
break;
|
2680 |
|
|
case 1:
|
2681 |
|
|
free_storable_picture(fs->top_field);
|
2682 |
|
|
fs->top_field=NULL;
|
2683 |
|
|
break;
|
2684 |
|
|
case 0:
|
2685 |
|
|
break;
|
2686 |
|
|
default:
|
2687 |
|
|
error("invalid frame store type",500);
|
2688 |
|
|
}
|
2689 |
|
|
fs->is_used = 0;
|
2690 |
|
|
fs->is_long_term = 0;
|
2691 |
|
|
fs->is_reference = 0;
|
2692 |
|
|
fs->is_orig_reference = 0;
|
2693 |
|
|
|
2694 |
|
|
// move empty framestore to end of buffer
|
2695 |
|
|
tmp = dpb.fs[pos];
|
2696 |
|
|
|
2697 |
|
|
for (i=pos; i<dpb.used_size-1;i++)
|
2698 |
|
|
{
|
2699 |
|
|
dpb.fs[i] = dpb.fs[i+1];
|
2700 |
|
|
}
|
2701 |
|
|
dpb.fs[dpb.used_size-1] = tmp;
|
2702 |
|
|
dpb.used_size--;
|
2703 |
|
|
}
|
2704 |
|
|
|
2705 |
|
|
/*!
|
2706 |
|
|
************************************************************************
|
2707 |
|
|
* \brief
|
2708 |
|
|
* find smallest POC in the DPB.
|
2709 |
|
|
************************************************************************
|
2710 |
|
|
*/
|
2711 |
|
|
static void get_smallest_poc(int *poc,int * pos)
|
2712 |
|
|
{
|
2713 |
|
|
unsigned i;
|
2714 |
|
|
|
2715 |
|
|
if (dpb.used_size<1)
|
2716 |
|
|
{
|
2717 |
|
|
error("Cannot determine smallest POC, DPB empty.",150);
|
2718 |
|
|
}
|
2719 |
|
|
|
2720 |
|
|
*pos=-1;
|
2721 |
|
|
*poc = INT_MAX;
|
2722 |
|
|
for (i=0; i<dpb.used_size; i++)
|
2723 |
|
|
{
|
2724 |
|
|
if ((*poc>dpb.fs[i]->poc)&&(!dpb.fs[i]->is_output))
|
2725 |
|
|
{
|
2726 |
|
|
*poc = dpb.fs[i]->poc;
|
2727 |
|
|
*pos=i;
|
2728 |
|
|
}
|
2729 |
|
|
}
|
2730 |
|
|
}
|
2731 |
|
|
|
2732 |
|
|
/*!
|
2733 |
|
|
************************************************************************
|
2734 |
|
|
* \brief
|
2735 |
|
|
* Remove a picture from DPB which is no longer needed.
|
2736 |
|
|
************************************************************************
|
2737 |
|
|
*/
|
2738 |
|
|
static int remove_unused_frame_from_dpb()
|
2739 |
|
|
{
|
2740 |
|
|
unsigned i;
|
2741 |
|
|
|
2742 |
|
|
// check for frames that were already output and no longer used for reference
|
2743 |
|
|
for (i=0; i<dpb.used_size; i++)
|
2744 |
|
|
{
|
2745 |
|
|
if (dpb.fs[i]->is_output && (!is_used_for_reference(dpb.fs[i])))
|
2746 |
|
|
{
|
2747 |
|
|
remove_frame_from_dpb(i);
|
2748 |
|
|
return 1;
|
2749 |
|
|
}
|
2750 |
|
|
}
|
2751 |
|
|
return 0;
|
2752 |
|
|
}
|
2753 |
|
|
|
2754 |
|
|
/*!
|
2755 |
|
|
************************************************************************
|
2756 |
|
|
* \brief
|
2757 |
|
|
* Output one picture stored in the DPB.
|
2758 |
|
|
************************************************************************
|
2759 |
|
|
*/
|
2760 |
|
|
static void output_one_frame_from_dpb()
|
2761 |
|
|
{
|
2762 |
|
|
int poc, pos;
|
2763 |
|
|
//diagnostics
|
2764 |
|
|
if (dpb.used_size<1)
|
2765 |
|
|
{
|
2766 |
|
|
error("Cannot output frame, DPB empty.",150);
|
2767 |
|
|
}
|
2768 |
|
|
|
2769 |
|
|
// find smallest POC
|
2770 |
|
|
get_smallest_poc(&poc, &pos);
|
2771 |
|
|
|
2772 |
|
|
if(pos==-1)
|
2773 |
|
|
{
|
2774 |
|
|
error("no frames for output available", 150);
|
2775 |
|
|
}
|
2776 |
|
|
|
2777 |
|
|
// call the output function
|
2778 |
|
|
// printf ("output frame with frame_num #%d, poc %d (dpb. dpb.size=%d, dpb.used_size=%d)\n", dpb.fs[pos]->frame_num, dpb.fs[pos]->frame->poc, dpb.size, dpb.used_size);
|
2779 |
|
|
|
2780 |
|
|
// picture error concealment
|
2781 |
|
|
if(img->conceal_mode != 0)
|
2782 |
|
|
{
|
2783 |
|
|
if(dpb.last_output_poc == 0)
|
2784 |
|
|
{
|
2785 |
|
|
write_lost_ref_after_idr(pos);
|
2786 |
|
|
}
|
2787 |
|
|
write_lost_non_ref_pic(poc, p_out);
|
2788 |
|
|
}
|
2789 |
|
|
|
2790 |
|
|
// JVT-P072 ends
|
2791 |
|
|
|
2792 |
|
|
write_stored_frame(dpb.fs[pos], p_out);
|
2793 |
|
|
|
2794 |
|
|
// picture error concealment
|
2795 |
|
|
if(img->conceal_mode == 0)
|
2796 |
|
|
if (dpb.last_output_poc >= poc)
|
2797 |
|
|
{
|
2798 |
|
|
error ("output POC must be in ascending order", 150);
|
2799 |
|
|
}
|
2800 |
|
|
dpb.last_output_poc = poc;
|
2801 |
|
|
// free frame store and move empty store to end of buffer
|
2802 |
|
|
if (!is_used_for_reference(dpb.fs[pos]))
|
2803 |
|
|
{
|
2804 |
|
|
remove_frame_from_dpb(pos);
|
2805 |
|
|
}
|
2806 |
|
|
}
|
2807 |
|
|
|
2808 |
|
|
|
2809 |
|
|
|
2810 |
|
|
/*!
|
2811 |
|
|
************************************************************************
|
2812 |
|
|
* \brief
|
2813 |
|
|
* All stored picture are output. Should be called to empty the buffer
|
2814 |
|
|
************************************************************************
|
2815 |
|
|
*/
|
2816 |
|
|
void flush_dpb()
|
2817 |
|
|
{
|
2818 |
|
|
unsigned i;
|
2819 |
|
|
|
2820 |
|
|
//diagnostics
|
2821 |
|
|
// printf("Flush remaining frames from dpb. dpb.size=%d, dpb.used_size=%d\n",dpb.size,dpb.used_size);
|
2822 |
|
|
|
2823 |
|
|
// if(img->conceal_mode == 0)
|
2824 |
|
|
if (img->conceal_mode != 0)
|
2825 |
|
|
conceal_non_ref_pics(0);
|
2826 |
|
|
|
2827 |
|
|
// mark all frames unused
|
2828 |
|
|
for (i=0; i<dpb.used_size; i++)
|
2829 |
|
|
{
|
2830 |
|
|
unmark_for_reference (dpb.fs[i]);
|
2831 |
|
|
}
|
2832 |
|
|
|
2833 |
|
|
while (remove_unused_frame_from_dpb()) ;
|
2834 |
|
|
|
2835 |
|
|
// output frames in POC order
|
2836 |
|
|
while (dpb.used_size)
|
2837 |
|
|
{
|
2838 |
|
|
output_one_frame_from_dpb();
|
2839 |
|
|
}
|
2840 |
|
|
|
2841 |
|
|
dpb.last_output_poc = INT_MIN;
|
2842 |
|
|
}
|
2843 |
|
|
|
2844 |
|
|
|
2845 |
|
|
void gen_field_ref_ids(StorablePicture *p)
|
2846 |
|
|
{
|
2847 |
|
|
int i,j, dummylist0, dummylist1;
|
2848 |
|
|
//! Generate Frame parameters from field information.
|
2849 |
|
|
for (i=0 ; i<p->size_x/4 ; i++)
|
2850 |
|
|
{
|
2851 |
|
|
for (j=0 ; j<p->size_y/4 ; j++)
|
2852 |
|
|
{
|
2853 |
|
|
dummylist0= p->ref_idx[LIST_0][j][i];
|
2854 |
|
|
dummylist1= p->ref_idx[LIST_1][j][i];
|
2855 |
|
|
//! association with id already known for fields.
|
2856 |
|
|
p->ref_id[LIST_0][j][i] = (dummylist0>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
|
2857 |
|
|
p->ref_id[LIST_1][j][i] = (dummylist1>=0)? p->ref_pic_num[p->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
|
2858 |
|
|
p->field_frame[j][i]=1;
|
2859 |
|
|
}
|
2860 |
|
|
}
|
2861 |
|
|
}
|
2862 |
|
|
|
2863 |
|
|
/*!
|
2864 |
|
|
************************************************************************
|
2865 |
|
|
* \brief
|
2866 |
|
|
* Extract top field from a frame
|
2867 |
|
|
************************************************************************
|
2868 |
|
|
*/
|
2869 |
|
|
void dpb_split_field(FrameStore *fs)
|
2870 |
|
|
{
|
2871 |
|
|
int i, j, ii, jj, jj4;
|
2872 |
|
|
int idiv,jdiv;
|
2873 |
|
|
int currentmb;
|
2874 |
|
|
int dummylist0,dummylist1;
|
2875 |
|
|
int twosz16 = 2*(fs->frame->size_x/16);
|
2876 |
|
|
|
2877 |
|
|
fs->poc = fs->frame->poc;
|
2878 |
|
|
|
2879 |
|
|
if (!fs->frame->frame_mbs_only_flag)
|
2880 |
|
|
{
|
2881 |
|
|
fs->top_field = alloc_storable_picture(TOP_FIELD, fs->frame->size_x, fs->frame->size_y, fs->frame->size_x_cr, fs->frame->size_y_cr);
|
2882 |
|
|
fs->bottom_field = alloc_storable_picture(BOTTOM_FIELD, fs->frame->size_x, fs->frame->size_y, fs->frame->size_x_cr, fs->frame->size_y_cr);
|
2883 |
|
|
|
2884 |
|
|
for (i=0; i<fs->frame->size_y/2; i++)
|
2885 |
|
|
{
|
2886 |
|
|
memcpy(fs->top_field->imgY[i], fs->frame->imgY[i*2], fs->frame->size_x*sizeof(imgpel));
|
2887 |
|
|
}
|
2888 |
|
|
|
2889 |
|
|
for (i=0; i<fs->frame->size_y_cr/2; i++)
|
2890 |
|
|
{
|
2891 |
|
|
memcpy(fs->top_field->imgUV[0][i], fs->frame->imgUV[0][i*2], fs->frame->size_x_cr*sizeof(imgpel));
|
2892 |
|
|
memcpy(fs->top_field->imgUV[1][i], fs->frame->imgUV[1][i*2], fs->frame->size_x_cr*sizeof(imgpel));
|
2893 |
|
|
}
|
2894 |
|
|
|
2895 |
|
|
for (i=0; i<fs->frame->size_y/2; i++)
|
2896 |
|
|
{
|
2897 |
|
|
memcpy(fs->bottom_field->imgY[i], fs->frame->imgY[i*2 + 1], fs->frame->size_x*sizeof(imgpel));
|
2898 |
|
|
}
|
2899 |
|
|
|
2900 |
|
|
for (i=0; i<fs->frame->size_y_cr/2; i++)
|
2901 |
|
|
{
|
2902 |
|
|
memcpy(fs->bottom_field->imgUV[0][i], fs->frame->imgUV[0][i*2 + 1], fs->frame->size_x_cr*sizeof(imgpel));
|
2903 |
|
|
memcpy(fs->bottom_field->imgUV[1][i], fs->frame->imgUV[1][i*2 + 1], fs->frame->size_x_cr*sizeof(imgpel));
|
2904 |
|
|
}
|
2905 |
|
|
|
2906 |
|
|
fs->top_field->poc = fs->frame->top_poc;
|
2907 |
|
|
fs->bottom_field->poc = fs->frame->bottom_poc;
|
2908 |
|
|
|
2909 |
|
|
fs->top_field->frame_poc = fs->frame->frame_poc;
|
2910 |
|
|
|
2911 |
|
|
fs->top_field->bottom_poc =fs->bottom_field->bottom_poc = fs->frame->bottom_poc;
|
2912 |
|
|
fs->top_field->top_poc =fs->bottom_field->top_poc = fs->frame->top_poc;
|
2913 |
|
|
fs->bottom_field->frame_poc = fs->frame->frame_poc;
|
2914 |
|
|
|
2915 |
|
|
fs->top_field->used_for_reference = fs->bottom_field->used_for_reference
|
2916 |
|
|
= fs->frame->used_for_reference;
|
2917 |
|
|
fs->top_field->is_long_term = fs->bottom_field->is_long_term
|
2918 |
|
|
= fs->frame->is_long_term;
|
2919 |
|
|
fs->long_term_frame_idx = fs->top_field->long_term_frame_idx
|
2920 |
|
|
= fs->bottom_field->long_term_frame_idx
|
2921 |
|
|
= fs->frame->long_term_frame_idx;
|
2922 |
|
|
|
2923 |
|
|
fs->top_field->coded_frame = fs->bottom_field->coded_frame = 1;
|
2924 |
|
|
fs->top_field->MbaffFrameFlag = fs->bottom_field->MbaffFrameFlag
|
2925 |
|
|
= fs->frame->MbaffFrameFlag;
|
2926 |
|
|
|
2927 |
|
|
fs->frame->top_field = fs->top_field;
|
2928 |
|
|
fs->frame->bottom_field = fs->bottom_field;
|
2929 |
|
|
|
2930 |
|
|
fs->top_field->bottom_field = fs->bottom_field;
|
2931 |
|
|
fs->top_field->frame = fs->frame;
|
2932 |
|
|
fs->bottom_field->top_field = fs->top_field;
|
2933 |
|
|
fs->bottom_field->frame = fs->frame;
|
2934 |
|
|
|
2935 |
|
|
fs->top_field->chroma_format_idc = fs->bottom_field->chroma_format_idc = fs->frame->chroma_format_idc;
|
2936 |
|
|
|
2937 |
|
|
//store reference picture index
|
2938 |
|
|
for (j=0; j<=fs->frame->max_slice_id; j++)
|
2939 |
|
|
{
|
2940 |
|
|
for (i=0;i<16;i++)
|
2941 |
|
|
{
|
2942 |
|
|
fs->top_field->ref_pic_num[j][LIST_1][2*i] =fs->frame->ref_pic_num[j][2 + LIST_1][2*i];
|
2943 |
|
|
fs->top_field->ref_pic_num[j][LIST_1][2*i + 1] =fs->frame->ref_pic_num[j][2 + LIST_1][2*i+1];
|
2944 |
|
|
fs->bottom_field->ref_pic_num[j][LIST_1][2*i] =fs->frame->ref_pic_num[j][4 + LIST_1][2*i];
|
2945 |
|
|
fs->bottom_field->ref_pic_num[j][LIST_1][2*i+1]=fs->frame->ref_pic_num[j][4 + LIST_1][2*i+1] ;
|
2946 |
|
|
|
2947 |
|
|
fs->top_field->ref_pic_num[j][LIST_0][2*i] =fs->frame->ref_pic_num[j][2 + LIST_0][2*i];
|
2948 |
|
|
fs->top_field->ref_pic_num[j][LIST_0][2*i + 1] =fs->frame->ref_pic_num[j][2 + LIST_0][2*i+1];
|
2949 |
|
|
fs->bottom_field->ref_pic_num[j][LIST_0][2*i] =fs->frame->ref_pic_num[j][4 + LIST_0][2*i];
|
2950 |
|
|
fs->bottom_field->ref_pic_num[j][LIST_0][2*i+1]=fs->frame->ref_pic_num[j][4 + LIST_0][2*i+1] ;
|
2951 |
|
|
}
|
2952 |
|
|
}
|
2953 |
|
|
}
|
2954 |
|
|
else
|
2955 |
|
|
{
|
2956 |
|
|
fs->top_field=NULL;
|
2957 |
|
|
fs->bottom_field=NULL;
|
2958 |
|
|
fs->frame->top_field=NULL;
|
2959 |
|
|
fs->frame->bottom_field=NULL;
|
2960 |
|
|
}
|
2961 |
|
|
|
2962 |
|
|
for (j=0 ; j<fs->frame->size_y/4 ; j++)
|
2963 |
|
|
{
|
2964 |
|
|
jdiv=j/4;
|
2965 |
|
|
for (i=0 ; i<fs->frame->size_x/4 ; i++)
|
2966 |
|
|
{
|
2967 |
|
|
idiv=i/4;
|
2968 |
|
|
currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2);
|
2969 |
|
|
|
2970 |
|
|
if (fs->frame->MbaffFrameFlag && fs->frame->mb_field[currentmb])
|
2971 |
|
|
{
|
2972 |
|
|
int list_offset = currentmb%2? 4: 2;
|
2973 |
|
|
dummylist0 = fs->frame->ref_idx[LIST_0][j][i];
|
2974 |
|
|
dummylist1 = fs->frame->ref_idx[LIST_1][j][i];
|
2975 |
|
|
//! association with id already known for fields.
|
2976 |
|
|
fs->frame->ref_id[LIST_0 + list_offset][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0;
|
2977 |
|
|
fs->frame->ref_id[LIST_1 + list_offset][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0;
|
2978 |
|
|
//! need to make association with frames
|
2979 |
|
|
fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0 + list_offset][dummylist0] : 0;
|
2980 |
|
|
fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->frm_ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1 + list_offset][dummylist1] : 0;
|
2981 |
|
|
|
2982 |
|
|
}
|
2983 |
|
|
else
|
2984 |
|
|
{
|
2985 |
|
|
dummylist0 = fs->frame->ref_idx[LIST_0][j][i];
|
2986 |
|
|
dummylist1 = fs->frame->ref_idx[LIST_1][j][i];
|
2987 |
|
|
fs->frame->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_0][dummylist0] : -1;
|
2988 |
|
|
fs->frame->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->ref_pic_num[fs->frame->slice_id[jdiv][idiv]][LIST_1][dummylist1] : -1;
|
2989 |
|
|
}
|
2990 |
|
|
}
|
2991 |
|
|
}
|
2992 |
|
|
|
2993 |
|
|
if (!fs->frame->frame_mbs_only_flag && fs->frame->MbaffFrameFlag)
|
2994 |
|
|
{
|
2995 |
|
|
for (j=0 ; j<fs->frame->size_y/8; j++)
|
2996 |
|
|
{
|
2997 |
|
|
jj = (j/4)*8 + j%4;
|
2998 |
|
|
jj4 = jj + 4;
|
2999 |
|
|
jdiv=j/2;
|
3000 |
|
|
for (i=0 ; i<fs->frame->size_x/4 ; i++)
|
3001 |
|
|
{
|
3002 |
|
|
idiv=i/4;
|
3003 |
|
|
|
3004 |
|
|
currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2);
|
3005 |
|
|
// Assign field mvs attached to MB-Frame buffer to the proper buffer
|
3006 |
|
|
if (fs->frame->mb_field[currentmb])
|
3007 |
|
|
{
|
3008 |
|
|
fs->bottom_field->field_frame[j][i] = fs->top_field->field_frame[j][i]=1;
|
3009 |
|
|
fs->frame->field_frame[2*j][i] = fs->frame->field_frame[2*j+1][i]=1;
|
3010 |
|
|
|
3011 |
|
|
fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj4][i][0];
|
3012 |
|
|
fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj4][i][1];
|
3013 |
|
|
fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj4][i][0];
|
3014 |
|
|
fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj4][i][1];
|
3015 |
|
|
fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj4][i];
|
3016 |
|
|
fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj4][i];
|
3017 |
|
|
fs->bottom_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+4][jj4][i];
|
3018 |
|
|
fs->bottom_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+4][jj4][i];
|
3019 |
|
|
|
3020 |
|
|
|
3021 |
|
|
fs->top_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][i][0];
|
3022 |
|
|
fs->top_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][i][1];
|
3023 |
|
|
fs->top_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][i][0];
|
3024 |
|
|
fs->top_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][i][1];
|
3025 |
|
|
fs->top_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][i];
|
3026 |
|
|
fs->top_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][i];
|
3027 |
|
|
fs->top_field->ref_id[LIST_0][j][i] = fs->frame->ref_id[LIST_0+2][jj][i];
|
3028 |
|
|
fs->top_field->ref_id[LIST_1][j][i] = fs->frame->ref_id[LIST_1+2][jj][i];
|
3029 |
|
|
}
|
3030 |
|
|
}
|
3031 |
|
|
}
|
3032 |
|
|
}
|
3033 |
|
|
|
3034 |
|
|
//! Generate field MVs from Frame MVs
|
3035 |
|
|
if (!fs->frame->frame_mbs_only_flag)
|
3036 |
|
|
{
|
3037 |
|
|
for (j=0 ; j<fs->frame->size_y/8 ; j++)
|
3038 |
|
|
{
|
3039 |
|
|
jj = 2* RSD(j);
|
3040 |
|
|
jdiv = j/2;
|
3041 |
|
|
for (i=0 ; i<fs->frame->size_x/4 ; i++)
|
3042 |
|
|
{
|
3043 |
|
|
ii = RSD(i);
|
3044 |
|
|
idiv = i/4;
|
3045 |
|
|
|
3046 |
|
|
currentmb = twosz16*(jdiv/2)+ (idiv)*2 + (jdiv%2);
|
3047 |
|
|
|
3048 |
|
|
if (!fs->frame->MbaffFrameFlag || !fs->frame->mb_field[currentmb])
|
3049 |
|
|
{
|
3050 |
|
|
fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]=0;
|
3051 |
|
|
|
3052 |
|
|
fs->top_field->field_frame[j][i] = fs->bottom_field->field_frame[j][i] = 0;
|
3053 |
|
|
|
3054 |
|
|
fs->top_field->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][j][i][0] = fs->frame->mv[LIST_0][jj][ii][0];
|
3055 |
|
|
fs->top_field->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] = fs->frame->mv[LIST_0][jj][ii][1];
|
3056 |
|
|
fs->top_field->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][j][i][0] = fs->frame->mv[LIST_1][jj][ii][0];
|
3057 |
|
|
fs->top_field->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] = fs->frame->mv[LIST_1][jj][ii][1];
|
3058 |
|
|
|
3059 |
|
|
// Scaling of references is done here since it will not affect spatial direct (2*0 =0)
|
3060 |
|
|
if (fs->frame->ref_idx[LIST_0][jj][ii] == -1)
|
3061 |
|
|
fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = - 1;
|
3062 |
|
|
else
|
3063 |
|
|
{
|
3064 |
|
|
dummylist0=fs->top_field->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][j][i] = fs->frame->ref_idx[LIST_0][jj][ii] ;
|
3065 |
|
|
fs->top_field ->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0;
|
3066 |
|
|
fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_0][dummylist0] : 0;
|
3067 |
|
|
}
|
3068 |
|
|
|
3069 |
|
|
if (fs->frame->ref_idx[LIST_1][jj][ii] == -1)
|
3070 |
|
|
fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = - 1;
|
3071 |
|
|
else
|
3072 |
|
|
{
|
3073 |
|
|
dummylist1=fs->top_field->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][j][i] = fs->frame->ref_idx[LIST_1][jj][ii];
|
3074 |
|
|
|
3075 |
|
|
fs->top_field ->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->top_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0;
|
3076 |
|
|
fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->frame->bottom_ref_pic_num[fs->frame->slice_id[jj>>2][ii>>2]][LIST_1][dummylist1] : 0;
|
3077 |
|
|
}
|
3078 |
|
|
}
|
3079 |
|
|
else
|
3080 |
|
|
{
|
3081 |
|
|
fs->frame->field_frame[2*j+1][i] = fs->frame->field_frame[2*j][i]= fs->frame->mb_field[currentmb];
|
3082 |
|
|
}
|
3083 |
|
|
}
|
3084 |
|
|
}
|
3085 |
|
|
}
|
3086 |
|
|
else
|
3087 |
|
|
{
|
3088 |
|
|
memset( &(fs->frame->field_frame[0][0]), 0, fs->frame->size_y * fs->frame->size_x /16 * sizeof(byte));
|
3089 |
|
|
}
|
3090 |
|
|
}
|
3091 |
|
|
|
3092 |
|
|
|
3093 |
|
|
/*!
|
3094 |
|
|
************************************************************************
|
3095 |
|
|
* \brief
|
3096 |
|
|
* Generate a frame from top and bottom fields,
|
3097 |
|
|
* YUV components and display information only
|
3098 |
|
|
************************************************************************
|
3099 |
|
|
*/
|
3100 |
|
|
void dpb_combine_field_yuv(FrameStore *fs)
|
3101 |
|
|
{
|
3102 |
|
|
int i;
|
3103 |
|
|
|
3104 |
|
|
fs->frame = alloc_storable_picture(FRAME, fs->top_field->size_x, fs->top_field->size_y*2, fs->top_field->size_x_cr, fs->top_field->size_y_cr*2);
|
3105 |
|
|
|
3106 |
|
|
for (i=0; i<fs->top_field->size_y; i++)
|
3107 |
|
|
{
|
3108 |
|
|
memcpy(fs->frame->imgY[i*2], fs->top_field->imgY[i] , fs->top_field->size_x*sizeof(imgpel)); // top field
|
3109 |
|
|
memcpy(fs->frame->imgY[i*2 + 1], fs->bottom_field->imgY[i], fs->bottom_field->size_x*sizeof(imgpel)); // bottom field
|
3110 |
|
|
}
|
3111 |
|
|
|
3112 |
|
|
for (i=0; i<fs->top_field->size_y_cr; i++)
|
3113 |
|
|
{
|
3114 |
|
|
memcpy(fs->frame->imgUV[0][i*2], fs->top_field->imgUV[0][i], fs->top_field->size_x_cr*sizeof(imgpel));
|
3115 |
|
|
memcpy(fs->frame->imgUV[0][i*2 + 1], fs->bottom_field->imgUV[0][i], fs->bottom_field->size_x_cr*sizeof(imgpel));
|
3116 |
|
|
memcpy(fs->frame->imgUV[1][i*2], fs->top_field->imgUV[1][i], fs->top_field->size_x_cr*sizeof(imgpel));
|
3117 |
|
|
memcpy(fs->frame->imgUV[1][i*2 + 1], fs->bottom_field->imgUV[1][i], fs->bottom_field->size_x_cr*sizeof(imgpel));
|
3118 |
|
|
}
|
3119 |
|
|
|
3120 |
|
|
fs->poc=fs->frame->poc =fs->frame->frame_poc = imin (fs->top_field->poc, fs->bottom_field->poc);
|
3121 |
|
|
|
3122 |
|
|
fs->bottom_field->frame_poc=fs->top_field->frame_poc=fs->frame->poc;
|
3123 |
|
|
|
3124 |
|
|
fs->bottom_field->top_poc=fs->frame->top_poc=fs->top_field->poc;
|
3125 |
|
|
fs->top_field->bottom_poc=fs->frame->bottom_poc=fs->bottom_field->poc;
|
3126 |
|
|
|
3127 |
|
|
fs->frame->used_for_reference = (fs->top_field->used_for_reference && fs->bottom_field->used_for_reference );
|
3128 |
|
|
fs->frame->is_long_term = (fs->top_field->is_long_term && fs->bottom_field->is_long_term );
|
3129 |
|
|
|
3130 |
|
|
if (fs->frame->is_long_term)
|
3131 |
|
|
fs->frame->long_term_frame_idx = fs->long_term_frame_idx;
|
3132 |
|
|
|
3133 |
|
|
fs->frame->top_field = fs->top_field;
|
3134 |
|
|
fs->frame->bottom_field = fs->bottom_field;
|
3135 |
|
|
|
3136 |
|
|
fs->frame->coded_frame = 0;
|
3137 |
|
|
|
3138 |
|
|
fs->frame->chroma_format_idc = fs->top_field->chroma_format_idc;
|
3139 |
|
|
fs->frame->frame_cropping_flag = fs->top_field->frame_cropping_flag;
|
3140 |
|
|
if (fs->frame->frame_cropping_flag)
|
3141 |
|
|
{
|
3142 |
|
|
fs->frame->frame_cropping_rect_top_offset = fs->top_field->frame_cropping_rect_top_offset;
|
3143 |
|
|
fs->frame->frame_cropping_rect_bottom_offset = fs->top_field->frame_cropping_rect_bottom_offset;
|
3144 |
|
|
fs->frame->frame_cropping_rect_left_offset = fs->top_field->frame_cropping_rect_left_offset;
|
3145 |
|
|
fs->frame->frame_cropping_rect_right_offset = fs->top_field->frame_cropping_rect_right_offset;
|
3146 |
|
|
}
|
3147 |
|
|
|
3148 |
|
|
fs->top_field->frame = fs->bottom_field->frame = fs->frame;
|
3149 |
|
|
}
|
3150 |
|
|
|
3151 |
|
|
|
3152 |
|
|
/*!
|
3153 |
|
|
************************************************************************
|
3154 |
|
|
* \brief
|
3155 |
|
|
* Generate a frame from top and bottom fields
|
3156 |
|
|
************************************************************************
|
3157 |
|
|
*/
|
3158 |
|
|
void dpb_combine_field(FrameStore *fs)
|
3159 |
|
|
{
|
3160 |
|
|
int i,j, jj, jj4;
|
3161 |
|
|
int dummylist0, dummylist1;
|
3162 |
|
|
|
3163 |
|
|
dpb_combine_field_yuv(fs);
|
3164 |
|
|
|
3165 |
|
|
|
3166 |
|
|
//combine field for frame
|
3167 |
|
|
for (j=0; j<=(imax(fs->top_field->max_slice_id, fs->bottom_field->max_slice_id)); j++)
|
3168 |
|
|
{
|
3169 |
|
|
for (i=0;i<16;i++)
|
3170 |
|
|
{
|
3171 |
|
|
fs->frame->ref_pic_num[j][LIST_1][i]= i64min ((fs->top_field->ref_pic_num[j][LIST_1][2*i]/2)*2, (fs->bottom_field->ref_pic_num[j][LIST_1][2*i]/2)*2);
|
3172 |
|
|
}
|
3173 |
|
|
|
3174 |
|
|
for (i=0;i<16;i++)
|
3175 |
|
|
{
|
3176 |
|
|
fs->frame->ref_pic_num[j][LIST_0][i] = i64min((fs->top_field->ref_pic_num[j][LIST_0][2*i]/2)*2, (fs->bottom_field->ref_pic_num[j][LIST_0][2*i]/2)*2);
|
3177 |
|
|
}
|
3178 |
|
|
}
|
3179 |
|
|
|
3180 |
|
|
//! Use inference flag to remap mvs/references
|
3181 |
|
|
|
3182 |
|
|
//! Generate Frame parameters from field information.
|
3183 |
|
|
for (j=0 ; j<fs->top_field->size_y/4 ; j++)
|
3184 |
|
|
{
|
3185 |
|
|
jj = 8*(j/4) + (j%4);
|
3186 |
|
|
jj4 = jj + 4;
|
3187 |
|
|
for (i=0 ; i<fs->top_field->size_x/4 ; i++)
|
3188 |
|
|
{
|
3189 |
|
|
fs->frame->field_frame[jj][i]= fs->frame->field_frame[jj4][i]=1;
|
3190 |
|
|
|
3191 |
|
|
fs->frame->mv[LIST_0][jj][i][0] = fs->top_field->mv[LIST_0][j][i][0];
|
3192 |
|
|
fs->frame->mv[LIST_0][jj][i][1] = fs->top_field->mv[LIST_0][j][i][1] ;
|
3193 |
|
|
fs->frame->mv[LIST_1][jj][i][0] = fs->top_field->mv[LIST_1][j][i][0];
|
3194 |
|
|
fs->frame->mv[LIST_1][jj][i][1] = fs->top_field->mv[LIST_1][j][i][1] ;
|
3195 |
|
|
|
3196 |
|
|
dummylist0=fs->frame->ref_idx[LIST_0][jj][i] = fs->top_field->ref_idx[LIST_0][j][i];
|
3197 |
|
|
dummylist1=fs->frame->ref_idx[LIST_1][jj][i] = fs->top_field->ref_idx[LIST_1][j][i];
|
3198 |
|
|
|
3199 |
|
|
//! association with id already known for fields.
|
3200 |
|
|
fs->top_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
|
3201 |
|
|
fs->top_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->top_field->ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
|
3202 |
|
|
|
3203 |
|
|
//! need to make association with frames
|
3204 |
|
|
fs->frame->ref_id[LIST_0][jj][i] = (dummylist0>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
|
3205 |
|
|
fs->frame->ref_id[LIST_1][jj][i] = (dummylist1>=0)? fs->top_field->frm_ref_pic_num[fs->top_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
|
3206 |
|
|
|
3207 |
|
|
fs->frame->mv[LIST_0][jj4][i][0] = fs->bottom_field->mv[LIST_0][j][i][0];
|
3208 |
|
|
fs->frame->mv[LIST_0][jj4][i][1] = fs->bottom_field->mv[LIST_0][j][i][1] ;
|
3209 |
|
|
fs->frame->mv[LIST_1][jj4][i][0] = fs->bottom_field->mv[LIST_1][j][i][0];
|
3210 |
|
|
fs->frame->mv[LIST_1][jj4][i][1] = fs->bottom_field->mv[LIST_1][j][i][1] ;
|
3211 |
|
|
|
3212 |
|
|
dummylist0=fs->frame->ref_idx[LIST_0][jj4][i] = fs->bottom_field->ref_idx[LIST_0][j][i];
|
3213 |
|
|
dummylist1=fs->frame->ref_idx[LIST_1][jj4][i] = fs->bottom_field->ref_idx[LIST_1][j][i];
|
3214 |
|
|
|
3215 |
|
|
fs->bottom_field->ref_id[LIST_0][j][i] = (dummylist0>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : 0;
|
3216 |
|
|
fs->bottom_field->ref_id[LIST_1][j][i] = (dummylist1>=0)? fs->bottom_field->ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : 0;
|
3217 |
|
|
|
3218 |
|
|
//! need to make association with frames
|
3219 |
|
|
fs->frame->ref_id[LIST_0][jj4][i] = (dummylist0>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_0][dummylist0] : -1;
|
3220 |
|
|
fs->frame->ref_id[LIST_1][jj4][i] = (dummylist1>=0)? fs->bottom_field->frm_ref_pic_num[fs->bottom_field->slice_id[j>>2][i>>2]][LIST_1][dummylist1] : -1;
|
3221 |
|
|
|
3222 |
|
|
fs->top_field->field_frame[j][i]=1;
|
3223 |
|
|
fs->bottom_field->field_frame[j][i]=1;
|
3224 |
|
|
}
|
3225 |
|
|
}
|
3226 |
|
|
}
|
3227 |
|
|
|
3228 |
|
|
|
3229 |
|
|
/*!
|
3230 |
|
|
************************************************************************
|
3231 |
|
|
* \brief
|
3232 |
|
|
* Allocate memory for buffering of reference picture reordering commands
|
3233 |
|
|
************************************************************************
|
3234 |
|
|
*/
|
3235 |
|
|
void alloc_ref_pic_list_reordering_buffer(Slice *currSlice)
|
3236 |
|
|
{
|
3237 |
|
|
int size = img->num_ref_idx_l0_active+1;
|
3238 |
|
|
|
3239 |
|
|
if (img->type!=I_SLICE && img->type!=SI_SLICE)
|
3240 |
|
|
{
|
3241 |
|
|
if ((currSlice->reordering_of_pic_nums_idc_l0 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: reordering_of_pic_nums_idc_l0");
|
3242 |
|
|
if ((currSlice->abs_diff_pic_num_minus1_l0 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: abs_diff_pic_num_minus1_l0");
|
3243 |
|
|
if ((currSlice->long_term_pic_idx_l0 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: long_term_pic_idx_l0");
|
3244 |
|
|
}
|
3245 |
|
|
else
|
3246 |
|
|
{
|
3247 |
|
|
currSlice->reordering_of_pic_nums_idc_l0 = NULL;
|
3248 |
|
|
currSlice->abs_diff_pic_num_minus1_l0 = NULL;
|
3249 |
|
|
currSlice->long_term_pic_idx_l0 = NULL;
|
3250 |
|
|
}
|
3251 |
|
|
|
3252 |
|
|
size = img->num_ref_idx_l1_active+1;
|
3253 |
|
|
|
3254 |
|
|
if (img->type==B_SLICE)
|
3255 |
|
|
{
|
3256 |
|
|
if ((currSlice->reordering_of_pic_nums_idc_l1 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: reordering_of_pic_nums_idc_l1");
|
3257 |
|
|
if ((currSlice->abs_diff_pic_num_minus1_l1 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: abs_diff_pic_num_minus1_l1");
|
3258 |
|
|
if ((currSlice->long_term_pic_idx_l1 = calloc(size,sizeof(int)))==NULL) no_mem_exit("alloc_ref_pic_list_reordering_buffer: long_term_pic_idx_l1");
|
3259 |
|
|
}
|
3260 |
|
|
else
|
3261 |
|
|
{
|
3262 |
|
|
currSlice->reordering_of_pic_nums_idc_l1 = NULL;
|
3263 |
|
|
currSlice->abs_diff_pic_num_minus1_l1 = NULL;
|
3264 |
|
|
currSlice->long_term_pic_idx_l1 = NULL;
|
3265 |
|
|
}
|
3266 |
|
|
}
|
3267 |
|
|
|
3268 |
|
|
|
3269 |
|
|
/*!
|
3270 |
|
|
************************************************************************
|
3271 |
|
|
* \brief
|
3272 |
|
|
* Free memory for buffering of reference picture reordering commands
|
3273 |
|
|
************************************************************************
|
3274 |
|
|
*/
|
3275 |
|
|
void free_ref_pic_list_reordering_buffer(Slice *currSlice)
|
3276 |
|
|
{
|
3277 |
|
|
|
3278 |
|
|
if (currSlice->reordering_of_pic_nums_idc_l0)
|
3279 |
|
|
free(currSlice->reordering_of_pic_nums_idc_l0);
|
3280 |
|
|
if (currSlice->abs_diff_pic_num_minus1_l0)
|
3281 |
|
|
free(currSlice->abs_diff_pic_num_minus1_l0);
|
3282 |
|
|
if (currSlice->long_term_pic_idx_l0)
|
3283 |
|
|
free(currSlice->long_term_pic_idx_l0);
|
3284 |
|
|
|
3285 |
|
|
currSlice->reordering_of_pic_nums_idc_l0 = NULL;
|
3286 |
|
|
currSlice->abs_diff_pic_num_minus1_l0 = NULL;
|
3287 |
|
|
currSlice->long_term_pic_idx_l0 = NULL;
|
3288 |
|
|
|
3289 |
|
|
if (currSlice->reordering_of_pic_nums_idc_l1)
|
3290 |
|
|
free(currSlice->reordering_of_pic_nums_idc_l1);
|
3291 |
|
|
if (currSlice->abs_diff_pic_num_minus1_l1)
|
3292 |
|
|
free(currSlice->abs_diff_pic_num_minus1_l1);
|
3293 |
|
|
if (currSlice->long_term_pic_idx_l1)
|
3294 |
|
|
free(currSlice->long_term_pic_idx_l1);
|
3295 |
|
|
|
3296 |
|
|
currSlice->reordering_of_pic_nums_idc_l1 = NULL;
|
3297 |
|
|
currSlice->abs_diff_pic_num_minus1_l1 = NULL;
|
3298 |
|
|
currSlice->long_term_pic_idx_l1 = NULL;
|
3299 |
|
|
}
|
3300 |
|
|
|
3301 |
|
|
/*!
|
3302 |
|
|
************************************************************************
|
3303 |
|
|
* \brief
|
3304 |
|
|
* Tian Dong
|
3305 |
|
|
* June 13, 2002, Modifed on July 30, 2003
|
3306 |
|
|
*
|
3307 |
|
|
* If a gap in frame_num is found, try to fill the gap
|
3308 |
|
|
* \param img
|
3309 |
|
|
*
|
3310 |
|
|
************************************************************************
|
3311 |
|
|
*/
|
3312 |
|
|
void fill_frame_num_gap(ImageParameters *img)
|
3313 |
|
|
{
|
3314 |
|
|
int CurrFrameNum;
|
3315 |
|
|
int UnusedShortTermFrameNum;
|
3316 |
|
|
StorablePicture *picture = NULL;
|
3317 |
|
|
int tmp1 = img->delta_pic_order_cnt[0];
|
3318 |
|
|
int tmp2 = img->delta_pic_order_cnt[1];
|
3319 |
|
|
img->delta_pic_order_cnt[0] = img->delta_pic_order_cnt[1] = 0;
|
3320 |
|
|
|
3321 |
|
|
// printf("A gap in frame number is found, try to fill it.\n");
|
3322 |
|
|
|
3323 |
|
|
|
3324 |
|
|
UnusedShortTermFrameNum = (img->pre_frame_num + 1) % img->MaxFrameNum;
|
3325 |
|
|
CurrFrameNum = img->frame_num;
|
3326 |
|
|
|
3327 |
|
|
while (CurrFrameNum != UnusedShortTermFrameNum)
|
3328 |
|
|
{
|
3329 |
|
|
picture = alloc_storable_picture (FRAME, img->width, img->height, img->width_cr, img->height_cr);
|
3330 |
|
|
picture->coded_frame = 1;
|
3331 |
|
|
picture->pic_num = UnusedShortTermFrameNum;
|
3332 |
|
|
picture->frame_num = UnusedShortTermFrameNum;
|
3333 |
|
|
picture->non_existing = 1;
|
3334 |
|
|
picture->is_output = 1;
|
3335 |
|
|
picture->used_for_reference = 1;
|
3336 |
|
|
|
3337 |
|
|
picture->adaptive_ref_pic_buffering_flag = 0;
|
3338 |
|
|
|
3339 |
|
|
img->frame_num = UnusedShortTermFrameNum;
|
3340 |
|
|
if (active_sps->pic_order_cnt_type!=0)
|
3341 |
|
|
{
|
3342 |
|
|
decode_poc(img);
|
3343 |
|
|
}
|
3344 |
|
|
picture->top_poc=img->toppoc;
|
3345 |
|
|
picture->bottom_poc=img->bottompoc;
|
3346 |
|
|
picture->frame_poc=img->framepoc;
|
3347 |
|
|
picture->poc=img->framepoc;
|
3348 |
|
|
|
3349 |
|
|
store_picture_in_dpb(picture);
|
3350 |
|
|
|
3351 |
|
|
picture=NULL;
|
3352 |
|
|
img->pre_frame_num = UnusedShortTermFrameNum;
|
3353 |
|
|
UnusedShortTermFrameNum = (UnusedShortTermFrameNum + 1) % img->MaxFrameNum;
|
3354 |
|
|
}
|
3355 |
|
|
img->delta_pic_order_cnt[0] = tmp1;
|
3356 |
|
|
img->delta_pic_order_cnt[1] = tmp2;
|
3357 |
|
|
img->frame_num = CurrFrameNum;
|
3358 |
|
|
|
3359 |
|
|
}
|
3360 |
|
|
|
3361 |
|
|
/*!
|
3362 |
|
|
************************************************************************
|
3363 |
|
|
* \brief
|
3364 |
|
|
* Allocate co-located memory
|
3365 |
|
|
*
|
3366 |
|
|
* \param size_x
|
3367 |
|
|
* horizontal luma size
|
3368 |
|
|
* \param size_y
|
3369 |
|
|
* vertical luma size
|
3370 |
|
|
* \param mb_adaptive_frame_field_flag
|
3371 |
|
|
* flag that indicates macroblock adaptive frame/field coding
|
3372 |
|
|
*
|
3373 |
|
|
* \return
|
3374 |
|
|
* the allocated StorablePicture structure
|
3375 |
|
|
************************************************************************
|
3376 |
|
|
*/
|
3377 |
|
|
ColocatedParams* alloc_colocated(int size_x, int size_y, int mb_adaptive_frame_field_flag)
|
3378 |
|
|
{
|
3379 |
|
|
ColocatedParams *s;
|
3380 |
|
|
|
3381 |
|
|
s = calloc(1, sizeof(ColocatedParams));
|
3382 |
|
|
if (NULL == s)
|
3383 |
|
|
no_mem_exit("alloc_colocated: s");
|
3384 |
|
|
|
3385 |
|
|
s->size_x = size_x;
|
3386 |
|
|
s->size_y = size_y;
|
3387 |
|
|
|
3388 |
|
|
|
3389 |
|
|
get_mem3D ((byte****)(&(s->ref_idx)) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
3390 |
|
|
get_mem3Dint64 (&(s->ref_pic_id), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
3391 |
|
|
get_mem4Dshort (&(s->mv) , 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE,2 );
|
3392 |
|
|
|
3393 |
|
|
get_mem2D (&(s->moving_block), size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
3394 |
|
|
get_mem2D (&(s->field_frame) , size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
|
3395 |
|
|
|
3396 |
|
|
if (mb_adaptive_frame_field_flag)
|
3397 |
|
|
{
|
3398 |
|
|
get_mem3D ((byte****)(&(s->top_ref_idx)) , 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
|
3399 |
|
|
get_mem3Dint64 (&(s->top_ref_pic_id), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
|
3400 |
|
|
get_mem4Dshort (&(s->top_mv), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE, 2);
|
3401 |
|
|
get_mem2D (&(s->top_moving_block), size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
|
3402 |
|
|
|
3403 |
|
|
get_mem3D ((byte****)(&(s->bottom_ref_idx)), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
|
3404 |
|
|
get_mem3Dint64 (&(s->bottom_ref_pic_id), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
|
3405 |
|
|
get_mem4Dshort (&(s->bottom_mv), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE, 2);
|
3406 |
|
|
get_mem2D (&(s->bottom_moving_block), size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
|
3407 |
|
|
}
|
3408 |
|
|
|
3409 |
|
|
s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag;
|
3410 |
|
|
|
3411 |
|
|
return s;
|
3412 |
|
|
}
|
3413 |
|
|
|
3414 |
|
|
/*!
|
3415 |
|
|
************************************************************************
|
3416 |
|
|
* \brief
|
3417 |
|
|
* Free co-located memory.
|
3418 |
|
|
*
|
3419 |
|
|
* \param p
|
3420 |
|
|
* Picture to be freed
|
3421 |
|
|
*
|
3422 |
|
|
************************************************************************
|
3423 |
|
|
*/
|
3424 |
|
|
void free_colocated(ColocatedParams* p)
|
3425 |
|
|
{
|
3426 |
|
|
if (p)
|
3427 |
|
|
{
|
3428 |
|
|
free_mem3D ((byte***)p->ref_idx, 2);
|
3429 |
|
|
free_mem3Dint64 (p->ref_pic_id, 2);
|
3430 |
|
|
free_mem4Dshort (p->mv, 2, p->size_y / BLOCK_SIZE);
|
3431 |
|
|
|
3432 |
|
|
if (p->moving_block)
|
3433 |
|
|
{
|
3434 |
|
|
free_mem2D (p->moving_block);
|
3435 |
|
|
p->moving_block=NULL;
|
3436 |
|
|
}
|
3437 |
|
|
if (p->field_frame)
|
3438 |
|
|
{
|
3439 |
|
|
free_mem2D (p->field_frame);
|
3440 |
|
|
p->field_frame=NULL;
|
3441 |
|
|
}
|
3442 |
|
|
|
3443 |
|
|
if (p->mb_adaptive_frame_field_flag)
|
3444 |
|
|
{
|
3445 |
|
|
free_mem3D ((byte***)p->top_ref_idx, 2);
|
3446 |
|
|
free_mem3Dint64 (p->top_ref_pic_id, 2);
|
3447 |
|
|
free_mem4Dshort (p->top_mv, 2, p->size_y / BLOCK_SIZE / 2);
|
3448 |
|
|
|
3449 |
|
|
|
3450 |
|
|
if (p->top_moving_block)
|
3451 |
|
|
{
|
3452 |
|
|
free_mem2D (p->top_moving_block);
|
3453 |
|
|
p->top_moving_block=NULL;
|
3454 |
|
|
}
|
3455 |
|
|
|
3456 |
|
|
free_mem3D ((byte***)p->bottom_ref_idx, 2);
|
3457 |
|
|
free_mem3Dint64 (p->bottom_ref_pic_id, 2);
|
3458 |
|
|
free_mem4Dshort (p->bottom_mv, 2, p->size_y / BLOCK_SIZE / 2);
|
3459 |
|
|
|
3460 |
|
|
|
3461 |
|
|
if (p->bottom_moving_block)
|
3462 |
|
|
{
|
3463 |
|
|
free_mem2D (p->bottom_moving_block);
|
3464 |
|
|
p->bottom_moving_block=NULL;
|
3465 |
|
|
}
|
3466 |
|
|
|
3467 |
|
|
}
|
3468 |
|
|
|
3469 |
|
|
free(p);
|
3470 |
|
|
|
3471 |
|
|
p=NULL;
|
3472 |
|
|
}
|
3473 |
|
|
}
|
3474 |
|
|
|
3475 |
|
|
/*!
|
3476 |
|
|
************************************************************************
|
3477 |
|
|
* \brief
|
3478 |
|
|
* Compute co-located motion info
|
3479 |
|
|
*
|
3480 |
|
|
************************************************************************
|
3481 |
|
|
*/
|
3482 |
|
|
|
3483 |
|
|
void compute_colocated(ColocatedParams* p, StorablePicture **listX[6])
|
3484 |
|
|
{
|
3485 |
|
|
StorablePicture *fs, *fs_top, *fs_bottom;
|
3486 |
|
|
int i,j, ii, jj, jdiv;
|
3487 |
|
|
|
3488 |
|
|
fs_top=fs_bottom=fs = listX[LIST_1 ][0];
|
3489 |
|
|
|
3490 |
|
|
if (img->MbaffFrameFlag)
|
3491 |
|
|
{
|
3492 |
|
|
fs_top= listX[LIST_1 + 2][0];
|
3493 |
|
|
fs_bottom= listX[LIST_1 + 4][0];
|
3494 |
|
|
}
|
3495 |
|
|
else
|
3496 |
|
|
{
|
3497 |
|
|
if (img->field_pic_flag)
|
3498 |
|
|
{
|
3499 |
|
|
if ((img->structure != fs->structure) && (fs->coded_frame))
|
3500 |
|
|
{
|
3501 |
|
|
if (img->structure==TOP_FIELD)
|
3502 |
|
|
{
|
3503 |
|
|
fs_top=fs_bottom=fs = listX[LIST_1 ][0]->top_field;
|
3504 |
|
|
}
|
3505 |
|
|
else
|
3506 |
|
|
{
|
3507 |
|
|
fs_top=fs_bottom=fs = listX[LIST_1 ][0]->bottom_field;
|
3508 |
|
|
}
|
3509 |
|
|
}
|
3510 |
|
|
}
|
3511 |
|
|
}
|
3512 |
|
|
|
3513 |
|
|
if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
|
3514 |
|
|
{
|
3515 |
|
|
for (j=0 ; j<fs->size_y/4 ; j++)
|
3516 |
|
|
{
|
3517 |
|
|
jdiv = j/2;
|
3518 |
|
|
jj = j/2 + 4 * (j/8);
|
3519 |
|
|
for (i=0 ; i<fs->size_x/4 ; i++)
|
3520 |
|
|
{
|
3521 |
|
|
|
3522 |
|
|
if (img->MbaffFrameFlag && fs->field_frame[j][i])
|
3523 |
|
|
{
|
3524 |
|
|
//! Assign frame buffers for field MBs
|
3525 |
|
|
//! Check whether we should use top or bottom field mvs.
|
3526 |
|
|
//! Depending on the assigned poc values.
|
3527 |
|
|
|
3528 |
|
|
if (iabs(dec_picture->poc - fs_bottom->poc)> iabs(dec_picture->poc -fs_top->poc) )
|
3529 |
|
|
{
|
3530 |
|
|
p->mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jdiv][i][0];
|
3531 |
|
|
p->mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jdiv][i][1] ;
|
3532 |
|
|
p->mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jdiv][i][0];
|
3533 |
|
|
p->mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jdiv][i][1] ;
|
3534 |
|
|
p->ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jdiv][i];
|
3535 |
|
|
p->ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jdiv][i];
|
3536 |
|
|
p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i];
|
3537 |
|
|
p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i];
|
3538 |
|
|
|
3539 |
|
|
p->is_long_term = fs_top->is_long_term;
|
3540 |
|
|
}
|
3541 |
|
|
else
|
3542 |
|
|
{
|
3543 |
|
|
p->mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jdiv][i][0];
|
3544 |
|
|
p->mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jdiv][i][1] ;
|
3545 |
|
|
p->mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jdiv][i][0];
|
3546 |
|
|
p->mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jdiv][i][1] ;
|
3547 |
|
|
p->ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jdiv][i];
|
3548 |
|
|
p->ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jdiv][i];
|
3549 |
|
|
p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i];
|
3550 |
|
|
p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i];
|
3551 |
|
|
|
3552 |
|
|
p->is_long_term = fs_bottom->is_long_term;
|
3553 |
|
|
}
|
3554 |
|
|
}
|
3555 |
|
|
else
|
3556 |
|
|
{
|
3557 |
|
|
p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][j][i][0];
|
3558 |
|
|
p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][j][i][1] ;
|
3559 |
|
|
p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][j][i][0];
|
3560 |
|
|
p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][j][i][1] ;
|
3561 |
|
|
p->ref_idx[LIST_0][j][i] = fs->ref_idx[LIST_0][j][i];
|
3562 |
|
|
p->ref_idx[LIST_1][j][i] = fs->ref_idx[LIST_1][j][i];
|
3563 |
|
|
p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][j][i];
|
3564 |
|
|
p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][j][i];
|
3565 |
|
|
|
3566 |
|
|
p->is_long_term = fs->is_long_term;
|
3567 |
|
|
}
|
3568 |
|
|
}
|
3569 |
|
|
}
|
3570 |
|
|
}
|
3571 |
|
|
|
3572 |
|
|
|
3573 |
|
|
//! Generate field MVs from Frame MVs
|
3574 |
|
|
if (img->structure || img->MbaffFrameFlag)
|
3575 |
|
|
{
|
3576 |
|
|
for (j=0 ; j<fs->size_y/8 ; j++)
|
3577 |
|
|
{
|
3578 |
|
|
jj = RSD(j);
|
3579 |
|
|
for (i=0 ; i<fs->size_x/4 ; i++)
|
3580 |
|
|
{
|
3581 |
|
|
ii = RSD(i);
|
3582 |
|
|
//! Do nothing if macroblock as field coded in MB-AFF
|
3583 |
|
|
if (!img->MbaffFrameFlag )
|
3584 |
|
|
{
|
3585 |
|
|
p->mv[LIST_0][j][i][0] = fs->mv[LIST_0][jj][ii][0];
|
3586 |
|
|
p->mv[LIST_0][j][i][1] = fs->mv[LIST_0][jj][ii][1];
|
3587 |
|
|
p->mv[LIST_1][j][i][0] = fs->mv[LIST_1][jj][ii][0];
|
3588 |
|
|
p->mv[LIST_1][j][i][1] = fs->mv[LIST_1][jj][ii][1];
|
3589 |
|
|
|
3590 |
|
|
// Scaling of references is done here since it will not affect spatial direct (2*0 =0)
|
3591 |
|
|
|
3592 |
|
|
if (fs->ref_idx[LIST_0][jj][ii] == -1)
|
3593 |
|
|
{
|
3594 |
|
|
p->ref_idx [LIST_0][j][i] = -1;
|
3595 |
|
|
p->ref_pic_id[LIST_0][j][i] = -1;
|
3596 |
|
|
}
|
3597 |
|
|
else
|
3598 |
|
|
{
|
3599 |
|
|
p->ref_idx [LIST_0][j][i] = fs->ref_idx[LIST_0][jj][ii] ;
|
3600 |
|
|
p->ref_pic_id[LIST_0][j][i] = fs->ref_id [LIST_0][jj][ii];
|
3601 |
|
|
}
|
3602 |
|
|
|
3603 |
|
|
if (fs->ref_idx[LIST_1][jj][ii] == -1)
|
3604 |
|
|
{
|
3605 |
|
|
p->ref_idx [LIST_1][j][i] = -1;
|
3606 |
|
|
p->ref_pic_id[LIST_1][j][i] = -1;
|
3607 |
|
|
}
|
3608 |
|
|
else
|
3609 |
|
|
{
|
3610 |
|
|
p->ref_idx [LIST_1][j][i] = fs->ref_idx[LIST_1][jj][ii];
|
3611 |
|
|
p->ref_pic_id[LIST_1][j][i] = fs->ref_id [LIST_1][jj][ii];
|
3612 |
|
|
}
|
3613 |
|
|
|
3614 |
|
|
p->is_long_term = fs->is_long_term;
|
3615 |
|
|
|
3616 |
|
|
if (img->direct_spatial_mv_pred_flag == 1)
|
3617 |
|
|
{
|
3618 |
|
|
p->moving_block[j][i] =
|
3619 |
|
|
!((!p->is_long_term
|
3620 |
|
|
&& ((p->ref_idx[LIST_0][j][i] == 0)
|
3621 |
|
|
&& (iabs(p->mv[LIST_0][j][i][0])>>1 == 0)
|
3622 |
|
|
&& (iabs(p->mv[LIST_0][j][i][1])>>1 == 0)))
|
3623 |
|
|
|| ((p->ref_idx[LIST_0][j][i] == -1)
|
3624 |
|
|
&& (p->ref_idx[LIST_1][j][i] == 0)
|
3625 |
|
|
&& (iabs(p->mv[LIST_1][j][i][0])>>1 == 0)
|
3626 |
|
|
&& (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)));
|
3627 |
|
|
}
|
3628 |
|
|
}
|
3629 |
|
|
else
|
3630 |
|
|
{
|
3631 |
|
|
p->bottom_mv[LIST_0][j][i][0] = fs_bottom->mv[LIST_0][jj][ii][0];
|
3632 |
|
|
p->bottom_mv[LIST_0][j][i][1] = fs_bottom->mv[LIST_0][jj][ii][1];
|
3633 |
|
|
p->bottom_mv[LIST_1][j][i][0] = fs_bottom->mv[LIST_1][jj][ii][0];
|
3634 |
|
|
p->bottom_mv[LIST_1][j][i][1] = fs_bottom->mv[LIST_1][jj][ii][1];
|
3635 |
|
|
p->bottom_ref_idx[LIST_0][j][i] = fs_bottom->ref_idx[LIST_0][jj][ii];
|
3636 |
|
|
p->bottom_ref_idx[LIST_1][j][i] = fs_bottom->ref_idx[LIST_1][jj][ii];
|
3637 |
|
|
p->bottom_ref_pic_id[LIST_0][j][i] = fs_bottom->ref_id[LIST_0][jj][ii];
|
3638 |
|
|
p->bottom_ref_pic_id[LIST_1][j][i] = fs_bottom->ref_id[LIST_1][jj][ii];
|
3639 |
|
|
|
3640 |
|
|
if (img->direct_spatial_mv_pred_flag == 1)
|
3641 |
|
|
{
|
3642 |
|
|
p->bottom_moving_block[j][i] =
|
3643 |
|
|
!((!fs_bottom->is_long_term
|
3644 |
|
|
&& ((p->bottom_ref_idx[LIST_0][j][i] == 0)
|
3645 |
|
|
&& (iabs(p->bottom_mv[LIST_0][j][i][0])>>1 == 0)
|
3646 |
|
|
&& (iabs(p->bottom_mv[LIST_0][j][i][1])>>1 == 0)))
|
3647 |
|
|
|| ((p->bottom_ref_idx[LIST_0][j][i] == -1)
|
3648 |
|
|
&& (p->bottom_ref_idx[LIST_1][j][i] == 0)
|
3649 |
|
|
&& (iabs(p->bottom_mv[LIST_1][j][i][0])>>1 == 0)
|
3650 |
|
|
&& (iabs(p->bottom_mv[LIST_1][j][i][1])>>1 == 0)));
|
3651 |
|
|
}
|
3652 |
|
|
|
3653 |
|
|
p->top_mv[LIST_0][j][i][0] = fs_top->mv[LIST_0][jj][ii][0];
|
3654 |
|
|
p->top_mv[LIST_0][j][i][1] = fs_top->mv[LIST_0][jj][ii][1];
|
3655 |
|
|
p->top_mv[LIST_1][j][i][0] = fs_top->mv[LIST_1][jj][ii][0];
|
3656 |
|
|
p->top_mv[LIST_1][j][i][1] = fs_top->mv[LIST_1][jj][ii][1];
|
3657 |
|
|
p->top_ref_idx[LIST_0][j][i] = fs_top->ref_idx[LIST_0][jj][ii];
|
3658 |
|
|
p->top_ref_idx[LIST_1][j][i] = fs_top->ref_idx[LIST_1][jj][ii];
|
3659 |
|
|
p->top_ref_pic_id[LIST_0][j][i] = fs_top->ref_id[LIST_0][jj][ii];
|
3660 |
|
|
p->top_ref_pic_id[LIST_1][j][i] = fs_top->ref_id[LIST_1][jj][ii];
|
3661 |
|
|
|
3662 |
|
|
if (img->direct_spatial_mv_pred_flag == 1)
|
3663 |
|
|
{
|
3664 |
|
|
p->top_moving_block[j][i] =
|
3665 |
|
|
!((!fs_top->is_long_term
|
3666 |
|
|
&& ((p->top_ref_idx[LIST_0][j][i] == 0)
|
3667 |
|
|
&& (iabs(p->top_mv[LIST_0][j][i][0])>>1 == 0)
|
3668 |
|
|
&& (iabs(p->top_mv[LIST_0][j][i][1])>>1 == 0)))
|
3669 |
|
|
|| ((p->top_ref_idx[LIST_0][j][i] == -1)
|
3670 |
|
|
&& (p->top_ref_idx[LIST_1][j][i] == 0)
|
3671 |
|
|
&& (iabs(p->top_mv[LIST_1][j][i][0])>>1 == 0)
|
3672 |
|
|
&& (iabs(p->top_mv[LIST_1][j][i][1])>>1 == 0)));
|
3673 |
|
|
}
|
3674 |
|
|
|
3675 |
|
|
if ((img->direct_spatial_mv_pred_flag == 0 ) && !fs->field_frame[2*j][i])
|
3676 |
|
|
{
|
3677 |
|
|
p->top_mv[LIST_0][j][i][1] /= 2;
|
3678 |
|
|
p->top_mv[LIST_1][j][i][1] /= 2;
|
3679 |
|
|
p->bottom_mv[LIST_0][j][i][1] /= 2;
|
3680 |
|
|
p->bottom_mv[LIST_1][j][i][1] /= 2;
|
3681 |
|
|
}
|
3682 |
|
|
|
3683 |
|
|
}
|
3684 |
|
|
}
|
3685 |
|
|
}
|
3686 |
|
|
}
|
3687 |
|
|
|
3688 |
|
|
|
3689 |
|
|
if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
|
3690 |
|
|
{
|
3691 |
|
|
//! Use inference flag to remap mvs/references
|
3692 |
|
|
//! Frame with field co-located
|
3693 |
|
|
|
3694 |
|
|
if (!img->structure)
|
3695 |
|
|
{
|
3696 |
|
|
for (j=0 ; j<fs->size_y/4 ; j++)
|
3697 |
|
|
{
|
3698 |
|
|
jdiv = j/2;
|
3699 |
|
|
jj = j/2 + 4*(j/8);
|
3700 |
|
|
for (i=0 ; i<fs->size_x/4 ; i++)
|
3701 |
|
|
{
|
3702 |
|
|
|
3703 |
|
|
if (fs->field_frame[j][i])
|
3704 |
|
|
{
|
3705 |
|
|
if (iabs(dec_picture->poc - fs->bottom_field->poc) > iabs(dec_picture->poc - fs->top_field->poc))
|
3706 |
|
|
{
|
3707 |
|
|
p->mv[LIST_0][j][i][0] = fs->top_field->mv[LIST_0][jdiv][i][0];
|
3708 |
|
|
p->mv[LIST_0][j][i][1] = fs->top_field->mv[LIST_0][jdiv][i][1] ;
|
3709 |
|
|
p->mv[LIST_1][j][i][0] = fs->top_field->mv[LIST_1][jdiv][i][0];
|
3710 |
|
|
p->mv[LIST_1][j][i][1] = fs->top_field->mv[LIST_1][jdiv][i][1] ;
|
3711 |
|
|
|
3712 |
|
|
p->ref_idx[LIST_0][j][i] = fs->top_field->ref_idx[LIST_0][jdiv][i];
|
3713 |
|
|
p->ref_idx[LIST_1][j][i] = fs->top_field->ref_idx[LIST_1][jdiv][i];
|
3714 |
|
|
p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj][i];
|
3715 |
|
|
p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj][i];
|
3716 |
|
|
p->is_long_term = fs->top_field->is_long_term;
|
3717 |
|
|
}
|
3718 |
|
|
else
|
3719 |
|
|
{
|
3720 |
|
|
p->mv[LIST_0][j][i][0] = fs->bottom_field->mv[LIST_0][jdiv][i][0];
|
3721 |
|
|
p->mv[LIST_0][j][i][1] = fs->bottom_field->mv[LIST_0][jdiv][i][1] ;
|
3722 |
|
|
p->mv[LIST_1][j][i][0] = fs->bottom_field->mv[LIST_1][jdiv][i][0];
|
3723 |
|
|
p->mv[LIST_1][j][i][1] = fs->bottom_field->mv[LIST_1][jdiv][i][1] ;
|
3724 |
|
|
|
3725 |
|
|
p->ref_idx[LIST_0][j][i] = fs->bottom_field->ref_idx[LIST_0][jdiv][i];
|
3726 |
|
|
p->ref_idx[LIST_1][j][i] = fs->bottom_field->ref_idx[LIST_1][jdiv][i];
|
3727 |
|
|
p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][jj + 4][i];
|
3728 |
|
|
p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][jj + 4][i];
|
3729 |
|
|
p->is_long_term = fs->bottom_field->is_long_term;
|
3730 |
|
|
}
|
3731 |
|
|
}
|
3732 |
|
|
}
|
3733 |
|
|
}
|
3734 |
|
|
}
|
3735 |
|
|
}
|
3736 |
|
|
|
3737 |
|
|
|
3738 |
|
|
p->is_long_term = fs->is_long_term;
|
3739 |
|
|
|
3740 |
|
|
if (!active_sps->frame_mbs_only_flag || active_sps->direct_8x8_inference_flag)
|
3741 |
|
|
{
|
3742 |
|
|
for (j=0 ; j<fs->size_y/4 ; j++)
|
3743 |
|
|
{
|
3744 |
|
|
jj = RSD(j);
|
3745 |
|
|
for (i=0 ; i<fs->size_x/4 ; i++)
|
3746 |
|
|
{
|
3747 |
|
|
ii = RSD(i);
|
3748 |
|
|
|
3749 |
|
|
p->mv[LIST_0][j][i][0]=p->mv[LIST_0][jj][ii][0];
|
3750 |
|
|
p->mv[LIST_0][j][i][1]=p->mv[LIST_0][jj][ii][1];
|
3751 |
|
|
p->mv[LIST_1][j][i][0]=p->mv[LIST_1][jj][ii][0];
|
3752 |
|
|
p->mv[LIST_1][j][i][1]=p->mv[LIST_1][jj][ii][1];
|
3753 |
|
|
|
3754 |
|
|
p->ref_idx[LIST_0][j][i]=p->ref_idx[LIST_0][jj][ii];
|
3755 |
|
|
p->ref_idx[LIST_1][j][i]=p->ref_idx[LIST_1][jj][ii];
|
3756 |
|
|
p->ref_pic_id[LIST_0][j][i] = p->ref_pic_id[LIST_0][jj][ii];
|
3757 |
|
|
p->ref_pic_id[LIST_1][j][i] = p->ref_pic_id[LIST_1][jj][ii];
|
3758 |
|
|
|
3759 |
|
|
if (img->direct_spatial_mv_pred_flag == 1)
|
3760 |
|
|
{
|
3761 |
|
|
p->moving_block[j][i]=
|
3762 |
|
|
!((!p->is_long_term
|
3763 |
|
|
&& ((p->ref_idx[LIST_0][j][i] == 0)
|
3764 |
|
|
&& (iabs(p->mv[LIST_0][j][i][0])>>1 == 0)
|
3765 |
|
|
&& (iabs(p->mv[LIST_0][j][i][1])>>1 == 0)))
|
3766 |
|
|
|| ((p->ref_idx[LIST_0][j][i] == -1)
|
3767 |
|
|
&& (p->ref_idx[LIST_1][j][i] == 0)
|
3768 |
|
|
&& (iabs(p->mv[LIST_1][j][i][0])>>1 == 0)
|
3769 |
|
|
&& (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)));
|
3770 |
|
|
}
|
3771 |
|
|
}
|
3772 |
|
|
}
|
3773 |
|
|
}
|
3774 |
|
|
else
|
3775 |
|
|
{
|
3776 |
|
|
for (j=0 ; j<fs->size_y/4 ; j++)
|
3777 |
|
|
{
|
3778 |
|
|
jj = RSD(j);
|
3779 |
|
|
for (i=0 ; i<fs->size_x/4 ; i++)
|
3780 |
|
|
{
|
3781 |
|
|
ii = RSD(i);
|
3782 |
|
|
//! Use inference flag to remap mvs/references
|
3783 |
|
|
p->mv[LIST_0][j][i][0]=fs->mv[LIST_0][j][i][0];
|
3784 |
|
|
p->mv[LIST_0][j][i][1]=fs->mv[LIST_0][j][i][1];
|
3785 |
|
|
p->mv[LIST_1][j][i][0]=fs->mv[LIST_1][j][i][0];
|
3786 |
|
|
p->mv[LIST_1][j][i][1]=fs->mv[LIST_1][j][i][1];
|
3787 |
|
|
|
3788 |
|
|
p->ref_idx[LIST_0][j][i]=fs->ref_idx[LIST_0][j][i];
|
3789 |
|
|
p->ref_idx[LIST_1][j][i]=fs->ref_idx[LIST_1][j][i];
|
3790 |
|
|
p->ref_pic_id[LIST_0][j][i] = fs->ref_id[LIST_0][j][i];
|
3791 |
|
|
p->ref_pic_id[LIST_1][j][i] = fs->ref_id[LIST_1][j][i];
|
3792 |
|
|
|
3793 |
|
|
if (img->direct_spatial_mv_pred_flag == 1)
|
3794 |
|
|
{
|
3795 |
|
|
p->moving_block[j][i]=
|
3796 |
|
|
!((!p->is_long_term
|
3797 |
|
|
&& ((p->ref_idx[LIST_0][j][i] == 0)
|
3798 |
|
|
&& (iabs(p->mv[LIST_0][j][i][0])>>1 == 0)
|
3799 |
|
|
&& (iabs(p->mv[LIST_0][j][i][1])>>1 == 0)))
|
3800 |
|
|
|| ((p->ref_idx[LIST_0][j][i] == -1)
|
3801 |
|
|
&& (p->ref_idx[LIST_1][j][i] == 0)
|
3802 |
|
|
&& (iabs(p->mv[LIST_1][j][i][0])>>1 == 0)
|
3803 |
|
|
&& (iabs(p->mv[LIST_1][j][i][1])>>1 == 0)));
|
3804 |
|
|
}
|
3805 |
|
|
}
|
3806 |
|
|
}
|
3807 |
|
|
}
|
3808 |
|
|
|
3809 |
|
|
|
3810 |
|
|
if (img->direct_spatial_mv_pred_flag ==0)
|
3811 |
|
|
{
|
3812 |
|
|
for (j=0 ; j<fs->size_y/4 ; j++)
|
3813 |
|
|
{
|
3814 |
|
|
for (i=0 ; i<fs->size_x/4 ; i++)
|
3815 |
|
|
{
|
3816 |
|
|
if ((!img->MbaffFrameFlag &&!img->structure && fs->field_frame[j][i]) || (img->MbaffFrameFlag && fs->field_frame[j][i]))
|
3817 |
|
|
{
|
3818 |
|
|
p->mv[LIST_0][j][i][1] *= 2;
|
3819 |
|
|
p->mv[LIST_1][j][i][1] *= 2;
|
3820 |
|
|
}
|
3821 |
|
|
else if (img->structure && !fs->field_frame[j][i])
|
3822 |
|
|
{
|
3823 |
|
|
p->mv[LIST_0][j][i][1] /= 2;
|
3824 |
|
|
p->mv[LIST_1][j][i][1] /= 2;
|
3825 |
|
|
}
|
3826 |
|
|
|
3827 |
|
|
}
|
3828 |
|
|
}
|
3829 |
|
|
|
3830 |
|
|
for (j=0; j<2 + (img->MbaffFrameFlag * 4);j+=2)
|
3831 |
|
|
{
|
3832 |
|
|
for (i=0; i<listXsize[j];i++)
|
3833 |
|
|
{
|
3834 |
|
|
int prescale, iTRb, iTRp;
|
3835 |
|
|
|
3836 |
|
|
if (j==0)
|
3837 |
|
|
{
|
3838 |
|
|
iTRb = iClip3( -128, 127, dec_picture->poc - listX[LIST_0 + j][i]->poc );
|
3839 |
|
|
}
|
3840 |
|
|
else if (j == 2)
|
3841 |
|
|
{
|
3842 |
|
|
iTRb = iClip3( -128, 127, dec_picture->top_poc - listX[LIST_0 + j][i]->poc );
|
3843 |
|
|
}
|
3844 |
|
|
else
|
3845 |
|
|
{
|
3846 |
|
|
iTRb = iClip3( -128, 127, dec_picture->bottom_poc - listX[LIST_0 + j][i]->poc );
|
3847 |
|
|
}
|
3848 |
|
|
|
3849 |
|
|
iTRp = iClip3( -128, 127, listX[LIST_1 + j][0]->poc - listX[LIST_0 + j][i]->poc);
|
3850 |
|
|
|
3851 |
|
|
if (iTRp!=0)
|
3852 |
|
|
{
|
3853 |
|
|
prescale = ( 16384 + iabs( iTRp / 2 ) ) / iTRp;
|
3854 |
|
|
img->mvscale[j][i] = iClip3( -1024, 1023, ( iTRb * prescale + 32 ) >> 6 ) ;
|
3855 |
|
|
}
|
3856 |
|
|
else
|
3857 |
|
|
{
|
3858 |
|
|
img->mvscale[j][i] = 9999;
|
3859 |
|
|
}
|
3860 |
|
|
}
|
3861 |
|
|
}
|
3862 |
|
|
}
|
3863 |
|
|
}
|
3864 |
|
|
|