1 |
14 |
jamey.hick |
|
2 |
|
|
/*!
|
3 |
|
|
***********************************************************************
|
4 |
|
|
* \file image.c
|
5 |
|
|
*
|
6 |
|
|
* \brief
|
7 |
|
|
* Decode a Slice
|
8 |
|
|
*
|
9 |
|
|
* \author
|
10 |
|
|
* Main contributors (see contributors.h for copyright, address and affiliation details)
|
11 |
|
|
* - Inge Lille-Langoy <inge.lille-langoy@telenor.com>
|
12 |
|
|
* - Rickard Sjoberg <rickard.sjoberg@era.ericsson.se>
|
13 |
|
|
* - Jani Lainema <jani.lainema@nokia.com>
|
14 |
|
|
* - Sebastian Purreiter <sebastian.purreiter@mch.siemens.de>
|
15 |
|
|
* - Byeong-Moon Jeon <jeonbm@lge.com>
|
16 |
|
|
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
|
17 |
|
|
* - Gabi Blaettermann <blaetter@hhi.de>
|
18 |
|
|
* - Ye-Kui Wang <wyk@ieee.org>
|
19 |
|
|
* - Antti Hallapuro <antti.hallapuro@nokia.com>
|
20 |
|
|
* - Alexis Tourapis <alexismt@ieee.org>
|
21 |
|
|
* - Jill Boyce <jill.boyce@thomson.net>
|
22 |
|
|
* - Saurav K Bandyopadhyay <saurav@ieee.org>
|
23 |
|
|
* - Zhenyu Wu <Zhenyu.Wu@thomson.net
|
24 |
|
|
* - Purvin Pandit <Purvin.Pandit@thomson.net>
|
25 |
|
|
*
|
26 |
|
|
***********************************************************************
|
27 |
|
|
*/
|
28 |
|
|
|
29 |
|
|
#include "contributors.h"
|
30 |
|
|
|
31 |
|
|
#include <math.h>
|
32 |
|
|
#include <limits.h>
|
33 |
|
|
#include <stdlib.h>
|
34 |
|
|
#include <string.h>
|
35 |
|
|
#include <assert.h>
|
36 |
|
|
|
37 |
|
|
#ifdef WIN32
|
38 |
|
|
#include <io.h>
|
39 |
|
|
#else
|
40 |
|
|
#include <unistd.h>
|
41 |
|
|
#endif
|
42 |
|
|
|
43 |
|
|
#include "global.h"
|
44 |
|
|
#include "errorconcealment.h"
|
45 |
|
|
#include "image.h"
|
46 |
|
|
#include "mbuffer.h"
|
47 |
|
|
#include "fmo.h"
|
48 |
|
|
#include "nalu.h"
|
49 |
|
|
#include "parsetcommon.h"
|
50 |
|
|
#include "parset.h"
|
51 |
|
|
#include "header.h"
|
52 |
|
|
#include "rtp.h"
|
53 |
|
|
#include "sei.h"
|
54 |
|
|
#include "output.h"
|
55 |
|
|
#include "biaridecod.h"
|
56 |
|
|
#include "mb_access.h"
|
57 |
|
|
#include "memalloc.h"
|
58 |
|
|
#include "annexb.h"
|
59 |
|
|
|
60 |
|
|
#include "context_ini.h"
|
61 |
|
|
#include "cabac.h"
|
62 |
|
|
#include "loopfilter.h"
|
63 |
|
|
|
64 |
|
|
#include "vlc.h"
|
65 |
|
|
|
66 |
|
|
#include "erc_api.h"
|
67 |
|
|
extern objectBuffer_t *erc_object_list;
|
68 |
|
|
extern ercVariables_t *erc_errorVar;
|
69 |
|
|
extern frame erc_recfr;
|
70 |
|
|
extern int erc_mvperMB;
|
71 |
|
|
extern struct img_par *erc_img;
|
72 |
|
|
|
73 |
|
|
//extern FILE *p_out2;
|
74 |
|
|
|
75 |
|
|
extern StorablePicture **listX[6];
|
76 |
|
|
extern ColocatedParams *Co_located;
|
77 |
|
|
|
78 |
|
|
extern StorablePicture *no_reference_picture;
|
79 |
|
|
int non_conforming_stream;
|
80 |
|
|
|
81 |
|
|
StorablePicture *dec_picture;
|
82 |
|
|
|
83 |
|
|
OldSliceParams old_slice;
|
84 |
|
|
|
85 |
|
|
void MbAffPostProc()
|
86 |
|
|
{
|
87 |
|
|
imgpel temp[16][32];
|
88 |
|
|
|
89 |
|
|
imgpel ** imgY = dec_picture->imgY;
|
90 |
|
|
imgpel ***imgUV = dec_picture->imgUV;
|
91 |
|
|
|
92 |
|
|
int i, x, y, x0, y0, uv;
|
93 |
|
|
for (i=0; i<(int)dec_picture->PicSizeInMbs; i+=2)
|
94 |
|
|
{
|
95 |
|
|
if (dec_picture->mb_field[i])
|
96 |
|
|
{
|
97 |
|
|
get_mb_pos(i, &x0, &y0, IS_LUMA);
|
98 |
|
|
for (y=0; y<(2*MB_BLOCK_SIZE);y++)
|
99 |
|
|
for (x=0; x<MB_BLOCK_SIZE; x++)
|
100 |
|
|
temp[x][y] = imgY[y0+y][x0+x];
|
101 |
|
|
|
102 |
|
|
for (y=0; y<MB_BLOCK_SIZE;y++)
|
103 |
|
|
for (x=0; x<MB_BLOCK_SIZE; x++)
|
104 |
|
|
{
|
105 |
|
|
imgY[y0+(2*y)][x0+x] = temp[x][y];
|
106 |
|
|
imgY[y0+(2*y+1)][x0+x] = temp[x][y+MB_BLOCK_SIZE];
|
107 |
|
|
}
|
108 |
|
|
|
109 |
|
|
if (dec_picture->chroma_format_idc != YUV400)
|
110 |
|
|
{
|
111 |
|
|
x0 = x0 / (16/img->mb_cr_size_x);
|
112 |
|
|
y0 = y0 / (16/img->mb_cr_size_y);
|
113 |
|
|
|
114 |
|
|
for (uv=0; uv<2; uv++)
|
115 |
|
|
{
|
116 |
|
|
for (y=0; y<(2*img->mb_cr_size_y);y++)
|
117 |
|
|
for (x=0; x<img->mb_cr_size_x; x++)
|
118 |
|
|
temp[x][y] = imgUV[uv][y0+y][x0+x];
|
119 |
|
|
|
120 |
|
|
for (y=0; y<img->mb_cr_size_y;y++)
|
121 |
|
|
for (x=0; x<img->mb_cr_size_x; x++)
|
122 |
|
|
{
|
123 |
|
|
imgUV[uv][y0+(2*y)][x0+x] = temp[x][y];
|
124 |
|
|
imgUV[uv][y0+(2*y+1)][x0+x] = temp[x][y+img->mb_cr_size_y];
|
125 |
|
|
}
|
126 |
|
|
}
|
127 |
|
|
}
|
128 |
|
|
}
|
129 |
|
|
}
|
130 |
|
|
}
|
131 |
|
|
|
132 |
|
|
/*!
|
133 |
|
|
***********************************************************************
|
134 |
|
|
* \brief
|
135 |
|
|
* decodes one I- or P-frame
|
136 |
|
|
*
|
137 |
|
|
***********************************************************************
|
138 |
|
|
*/
|
139 |
|
|
|
140 |
|
|
int decode_one_frame(struct img_par *img,struct inp_par *inp, struct snr_par *snr)
|
141 |
|
|
{
|
142 |
|
|
int current_header;
|
143 |
|
|
Slice *currSlice = img->currentSlice;
|
144 |
|
|
int i;
|
145 |
|
|
|
146 |
|
|
img->current_slice_nr = 0;
|
147 |
|
|
img->current_mb_nr = -4711; // initialized to an impossible value for debugging -- correct value is taken from slice header
|
148 |
|
|
currSlice->next_header = -8888; // initialized to an impossible value for debugging -- correct value is taken from slice header
|
149 |
|
|
img->num_dec_mb = 0;
|
150 |
|
|
img->newframe = 1;
|
151 |
|
|
|
152 |
|
|
while ((currSlice->next_header != EOS && currSlice->next_header != SOP))
|
153 |
|
|
{
|
154 |
|
|
current_header = read_new_slice();
|
155 |
|
|
|
156 |
|
|
// error tracking of primary and redundant slices.
|
157 |
|
|
Error_tracking();
|
158 |
|
|
|
159 |
|
|
// If primary and redundant are received and primary is correct, discard the redundant
|
160 |
|
|
// else, primary slice will be replaced with redundant slice.
|
161 |
|
|
if(img->frame_num == previous_frame_num && img->redundant_pic_cnt !=0
|
162 |
|
|
&& Is_primary_correct !=0 && current_header != EOS)
|
163 |
|
|
{
|
164 |
|
|
continue;
|
165 |
|
|
}
|
166 |
|
|
|
167 |
|
|
// update reference flags and set current ref_flag
|
168 |
|
|
if(!(img->redundant_pic_cnt != 0 && previous_frame_num == img->frame_num))
|
169 |
|
|
{
|
170 |
|
|
for(i=16;i>0;i--)
|
171 |
|
|
{
|
172 |
|
|
ref_flag[i] = ref_flag[i-1];
|
173 |
|
|
}
|
174 |
|
|
}
|
175 |
|
|
ref_flag[0] = img->redundant_pic_cnt==0 ? Is_primary_correct : Is_redundant_correct;
|
176 |
|
|
previous_frame_num = img->frame_num;
|
177 |
|
|
|
178 |
|
|
if (current_header == EOS)
|
179 |
|
|
{
|
180 |
|
|
exit_picture();
|
181 |
|
|
return EOS;
|
182 |
|
|
}
|
183 |
|
|
|
184 |
|
|
decode_slice(img, inp, current_header);
|
185 |
|
|
|
186 |
|
|
img->newframe = 0;
|
187 |
|
|
img->current_slice_nr++;
|
188 |
|
|
}
|
189 |
|
|
|
190 |
|
|
exit_picture();
|
191 |
|
|
|
192 |
|
|
return (SOP);
|
193 |
|
|
}
|
194 |
|
|
|
195 |
|
|
|
196 |
|
|
/*!
|
197 |
|
|
************************************************************************
|
198 |
|
|
* \brief
|
199 |
|
|
* Convert file read buffer to source picture structure
|
200 |
|
|
* \param imgX
|
201 |
|
|
* Pointer to image plane
|
202 |
|
|
* \param buf
|
203 |
|
|
* Buffer for file output
|
204 |
|
|
* \param size_x
|
205 |
|
|
* horizontal image size in pixel
|
206 |
|
|
* \param size_y
|
207 |
|
|
* vertical image size in pixel
|
208 |
|
|
* \param symbol_size_in_bytes
|
209 |
|
|
* number of bytes used per pel
|
210 |
|
|
************************************************************************
|
211 |
|
|
*/
|
212 |
|
|
void buf2img (imgpel** imgX, unsigned char* buf, int size_x, int size_y, int symbol_size_in_bytes)
|
213 |
|
|
{
|
214 |
|
|
int i,j;
|
215 |
|
|
|
216 |
|
|
unsigned short tmp16, ui16;
|
217 |
|
|
unsigned long tmp32, ui32;
|
218 |
|
|
|
219 |
|
|
if (symbol_size_in_bytes> sizeof(imgpel))
|
220 |
|
|
{
|
221 |
|
|
error ("Source picture has higher bit depth than imgpel data type. Please recompile with larger data type for imgpel.", 500);
|
222 |
|
|
}
|
223 |
|
|
|
224 |
|
|
if (( sizeof(char) == sizeof (imgpel)) && ( sizeof(char) == symbol_size_in_bytes))
|
225 |
|
|
{
|
226 |
|
|
// imgpel == pixel_in_file == 1 byte -> simple copy
|
227 |
|
|
for(j=0;j<size_y;j++)
|
228 |
|
|
memcpy(&imgX[j][0], buf+j*size_x, size_x);
|
229 |
|
|
}
|
230 |
|
|
else
|
231 |
|
|
{
|
232 |
|
|
// sizeof (imgpel) > sizeof(char)
|
233 |
|
|
if (testEndian())
|
234 |
|
|
{
|
235 |
|
|
// big endian
|
236 |
|
|
switch (symbol_size_in_bytes)
|
237 |
|
|
{
|
238 |
|
|
case 1:
|
239 |
|
|
{
|
240 |
|
|
for(j=0;j<size_y;j++)
|
241 |
|
|
for(i=0;i<size_x;i++)
|
242 |
|
|
{
|
243 |
|
|
imgX[j][i]= buf[i+j*size_x];
|
244 |
|
|
}
|
245 |
|
|
break;
|
246 |
|
|
}
|
247 |
|
|
case 2:
|
248 |
|
|
{
|
249 |
|
|
for(j=0;j<size_y;j++)
|
250 |
|
|
for(i=0;i<size_x;i++)
|
251 |
|
|
{
|
252 |
|
|
memcpy(&tmp16, buf+((i+j*size_x)*2), 2);
|
253 |
|
|
ui16 = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
|
254 |
|
|
imgX[j][i] = (imgpel) ui16;
|
255 |
|
|
}
|
256 |
|
|
break;
|
257 |
|
|
}
|
258 |
|
|
case 4:
|
259 |
|
|
{
|
260 |
|
|
for(j=0;j<size_y;j++)
|
261 |
|
|
for(i=0;i<size_x;i++)
|
262 |
|
|
{
|
263 |
|
|
memcpy(&tmp32, buf+((i+j*size_x)*4), 4);
|
264 |
|
|
ui32 = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
|
265 |
|
|
imgX[j][i] = (imgpel) ui32;
|
266 |
|
|
}
|
267 |
|
|
}
|
268 |
|
|
default:
|
269 |
|
|
{
|
270 |
|
|
error ("reading only from formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
|
271 |
|
|
break;
|
272 |
|
|
}
|
273 |
|
|
}
|
274 |
|
|
|
275 |
|
|
}
|
276 |
|
|
else
|
277 |
|
|
{
|
278 |
|
|
// little endian
|
279 |
|
|
if (symbol_size_in_bytes == 1)
|
280 |
|
|
{
|
281 |
|
|
for (j=0; j < size_y; j++)
|
282 |
|
|
{
|
283 |
|
|
for (i=0; i < size_x; i++)
|
284 |
|
|
{
|
285 |
|
|
imgX[j][i]=*(buf++);
|
286 |
|
|
}
|
287 |
|
|
}
|
288 |
|
|
}
|
289 |
|
|
else
|
290 |
|
|
{
|
291 |
|
|
for (j=0; j < size_y; j++)
|
292 |
|
|
{
|
293 |
|
|
int jpos = j*size_x;
|
294 |
|
|
for (i=0; i < size_x; i++)
|
295 |
|
|
{
|
296 |
|
|
imgX[j][i]=0;
|
297 |
|
|
memcpy(&(imgX[j][i]), buf +((i+jpos)*symbol_size_in_bytes), symbol_size_in_bytes);
|
298 |
|
|
}
|
299 |
|
|
}
|
300 |
|
|
}
|
301 |
|
|
|
302 |
|
|
}
|
303 |
|
|
}
|
304 |
|
|
}
|
305 |
|
|
|
306 |
|
|
|
307 |
|
|
/*!
|
308 |
|
|
************************************************************************
|
309 |
|
|
* \brief
|
310 |
|
|
* Find PSNR for all three components.Compare decoded frame with
|
311 |
|
|
* the original sequence. Read inp->jumpd frames to reflect frame skipping.
|
312 |
|
|
************************************************************************
|
313 |
|
|
*/
|
314 |
|
|
void find_snr(
|
315 |
|
|
struct snr_par *snr, //!< pointer to snr parameters
|
316 |
|
|
StorablePicture *p, //!< picture to be compared
|
317 |
|
|
int p_ref) //!< open reference YUV file
|
318 |
|
|
{
|
319 |
|
|
static const int SubWidthC [4]= { 1, 2, 2, 1};
|
320 |
|
|
static const int SubHeightC [4]= { 1, 2, 1, 1};
|
321 |
|
|
int crop_left, crop_right, crop_top, crop_bottom;
|
322 |
|
|
|
323 |
|
|
int i,j;
|
324 |
|
|
int64 diff_y,diff_u,diff_v;
|
325 |
|
|
int uv;
|
326 |
|
|
int64 status;
|
327 |
|
|
int symbol_size_in_bytes = img->pic_unit_bitsize_on_disk/8;
|
328 |
|
|
int size_x, size_y;
|
329 |
|
|
int size_x_cr, size_y_cr;
|
330 |
|
|
int64 framesize_in_bytes;
|
331 |
|
|
unsigned int max_pix_value_sqd = img->max_imgpel_value * img->max_imgpel_value;
|
332 |
|
|
unsigned int max_pix_value_sqd_uv = img->max_imgpel_value_uv * img->max_imgpel_value_uv;
|
333 |
|
|
Boolean rgb_output = (Boolean) (active_sps->vui_seq_parameters.matrix_coefficients==0);
|
334 |
|
|
unsigned char *buf;
|
335 |
|
|
|
336 |
|
|
// picture error concealment
|
337 |
|
|
char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
|
338 |
|
|
|
339 |
|
|
// calculate frame number
|
340 |
|
|
int psnrPOC = active_sps->mb_adaptive_frame_field_flag ? p->poc /(input->poc_scale) : p->poc/(input->poc_scale);
|
341 |
|
|
|
342 |
|
|
// cropping for luma
|
343 |
|
|
if (p->frame_cropping_flag)
|
344 |
|
|
{
|
345 |
|
|
crop_left = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_left_offset;
|
346 |
|
|
crop_right = SubWidthC[p->chroma_format_idc] * p->frame_cropping_rect_right_offset;
|
347 |
|
|
crop_top = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
|
348 |
|
|
crop_bottom = SubHeightC[p->chroma_format_idc]*( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
|
349 |
|
|
}
|
350 |
|
|
else
|
351 |
|
|
{
|
352 |
|
|
crop_left = crop_right = crop_top = crop_bottom = 0;
|
353 |
|
|
}
|
354 |
|
|
|
355 |
|
|
size_x = p->size_x - crop_left - crop_right;
|
356 |
|
|
size_y = p->size_y - crop_top - crop_bottom;
|
357 |
|
|
|
358 |
|
|
// cropping for chroma
|
359 |
|
|
if (p->frame_cropping_flag)
|
360 |
|
|
{
|
361 |
|
|
crop_left = p->frame_cropping_rect_left_offset;
|
362 |
|
|
crop_right = p->frame_cropping_rect_right_offset;
|
363 |
|
|
crop_top = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_top_offset;
|
364 |
|
|
crop_bottom = ( 2 - p->frame_mbs_only_flag ) * p->frame_cropping_rect_bottom_offset;
|
365 |
|
|
}
|
366 |
|
|
else
|
367 |
|
|
{
|
368 |
|
|
crop_left = crop_right = crop_top = crop_bottom = 0;
|
369 |
|
|
}
|
370 |
|
|
|
371 |
|
|
if ((p->chroma_format_idc==YUV400) && input->write_uv)
|
372 |
|
|
{
|
373 |
|
|
size_x_cr = p->size_x/2;
|
374 |
|
|
size_y_cr = p->size_y/2;
|
375 |
|
|
}
|
376 |
|
|
else
|
377 |
|
|
{
|
378 |
|
|
size_x_cr = p->size_x_cr - crop_left - crop_right;
|
379 |
|
|
size_y_cr = p->size_y_cr - crop_top - crop_bottom;
|
380 |
|
|
}
|
381 |
|
|
|
382 |
|
|
framesize_in_bytes = (((int64)size_y*size_x) + ((int64)size_y_cr*size_x_cr)*2) * symbol_size_in_bytes;
|
383 |
|
|
|
384 |
|
|
if (psnrPOC==0 && img->psnr_number)
|
385 |
|
|
img->idr_psnr_number = img->number*img->ref_poc_gap/(input->poc_scale);
|
386 |
|
|
|
387 |
|
|
img->psnr_number=imax(img->psnr_number,img->idr_psnr_number+psnrPOC);
|
388 |
|
|
|
389 |
|
|
frame_no = img->idr_psnr_number+psnrPOC;
|
390 |
|
|
|
391 |
|
|
// KS: this buffer should actually be allocated only once, but this is still much faster than the previous version
|
392 |
|
|
buf = malloc ( size_y * size_x * symbol_size_in_bytes );
|
393 |
|
|
|
394 |
|
|
if (NULL == buf)
|
395 |
|
|
{
|
396 |
|
|
no_mem_exit("find_snr: buf");
|
397 |
|
|
}
|
398 |
|
|
|
399 |
|
|
status = lseek (p_ref, framesize_in_bytes * frame_no, SEEK_SET);
|
400 |
|
|
if (status == -1)
|
401 |
|
|
{
|
402 |
|
|
fprintf(stderr, "Error in seeking frame number: %d\n", frame_no);
|
403 |
|
|
free (buf);
|
404 |
|
|
return;
|
405 |
|
|
}
|
406 |
|
|
|
407 |
|
|
if(rgb_output)
|
408 |
|
|
lseek (p_ref, framesize_in_bytes/3, SEEK_CUR);
|
409 |
|
|
|
410 |
|
|
read(p_ref, buf, size_y * size_x * symbol_size_in_bytes);
|
411 |
|
|
buf2img(imgY_ref, buf, size_x, size_y, symbol_size_in_bytes);
|
412 |
|
|
|
413 |
|
|
if (p->chroma_format_idc != YUV400)
|
414 |
|
|
{
|
415 |
|
|
for (uv=0; uv < 2; uv++)
|
416 |
|
|
{
|
417 |
|
|
if(rgb_output && uv==1)
|
418 |
|
|
lseek (p_ref, -framesize_in_bytes, SEEK_CUR);
|
419 |
|
|
|
420 |
|
|
read(p_ref, buf, size_y_cr * size_x_cr*symbol_size_in_bytes);
|
421 |
|
|
buf2img(imgUV_ref[uv], buf, size_x_cr, size_y_cr, symbol_size_in_bytes);
|
422 |
|
|
}
|
423 |
|
|
}
|
424 |
|
|
|
425 |
|
|
if(rgb_output)
|
426 |
|
|
lseek (p_ref, framesize_in_bytes*2/3, SEEK_CUR);
|
427 |
|
|
|
428 |
|
|
free (buf);
|
429 |
|
|
|
430 |
|
|
img->quad[0]=0;
|
431 |
|
|
diff_y=0;
|
432 |
|
|
for (j=0; j < size_y; ++j)
|
433 |
|
|
{
|
434 |
|
|
for (i=0; i < size_x; ++i)
|
435 |
|
|
{
|
436 |
|
|
diff_y += img->quad[p->imgY[j][i]-imgY_ref[j][i]];
|
437 |
|
|
}
|
438 |
|
|
}
|
439 |
|
|
|
440 |
|
|
// Chroma
|
441 |
|
|
diff_u=0;
|
442 |
|
|
diff_v=0;
|
443 |
|
|
|
444 |
|
|
if (p->chroma_format_idc != YUV400)
|
445 |
|
|
{
|
446 |
|
|
for (j=0; j < size_y_cr; ++j)
|
447 |
|
|
{
|
448 |
|
|
for (i=0; i < size_x_cr; ++i)
|
449 |
|
|
{
|
450 |
|
|
diff_u += img->quad[imgUV_ref[0][j][i]-p->imgUV[0][j][i]];
|
451 |
|
|
diff_v += img->quad[imgUV_ref[1][j][i]-p->imgUV[1][j][i]];
|
452 |
|
|
}
|
453 |
|
|
}
|
454 |
|
|
}
|
455 |
|
|
|
456 |
|
|
#if ZEROSNR
|
457 |
|
|
if (diff_y == 0)
|
458 |
|
|
diff_y = 1;
|
459 |
|
|
if (diff_u == 0)
|
460 |
|
|
diff_u = 1;
|
461 |
|
|
if (diff_v == 0)
|
462 |
|
|
diff_v = 1;
|
463 |
|
|
#endif
|
464 |
|
|
|
465 |
|
|
// Collecting SNR statistics
|
466 |
|
|
if (diff_y != 0)
|
467 |
|
|
snr->snr_y=(float)(10*log10(max_pix_value_sqd*(double)((double)(size_x)*(size_y) / diff_y))); // luma snr for current frame
|
468 |
|
|
else
|
469 |
|
|
snr->snr_y=0.0;
|
470 |
|
|
if (diff_u != 0)
|
471 |
|
|
snr->snr_u=(float)(10*log10(max_pix_value_sqd_uv*(double)((double)(size_x_cr)*(size_y_cr) / (diff_u)))); // chroma snr for current frame
|
472 |
|
|
else
|
473 |
|
|
snr->snr_u=0.0;
|
474 |
|
|
if (diff_v != 0)
|
475 |
|
|
snr->snr_v=(float)(10*log10(max_pix_value_sqd_uv*(double)((double)(size_x_cr)*(size_y_cr) / (diff_v)))); // chroma snr for current frame
|
476 |
|
|
else
|
477 |
|
|
snr->snr_v=0;
|
478 |
|
|
|
479 |
|
|
if (img->number == 0) // first
|
480 |
|
|
{
|
481 |
|
|
snr->snr_ya=snr->snr_y1=snr->snr_y; // keep luma snr for first frame
|
482 |
|
|
snr->snr_ua=snr->snr_u1=snr->snr_u; // keep chroma snr for first frame
|
483 |
|
|
snr->snr_va=snr->snr_v1=snr->snr_v; // keep chroma snr for first frame
|
484 |
|
|
|
485 |
|
|
}
|
486 |
|
|
else
|
487 |
|
|
{
|
488 |
|
|
snr->snr_ya=(float)(snr->snr_ya*(snr->frame_ctr)+snr->snr_y)/(snr->frame_ctr+1); // average snr chroma for all frames
|
489 |
|
|
snr->snr_ua=(float)(snr->snr_ua*(snr->frame_ctr)+snr->snr_u)/(snr->frame_ctr+1); // average snr luma for all frames
|
490 |
|
|
snr->snr_va=(float)(snr->snr_va*(snr->frame_ctr)+snr->snr_v)/(snr->frame_ctr+1); // average snr luma for all frames
|
491 |
|
|
}
|
492 |
|
|
|
493 |
|
|
// picture error concealment
|
494 |
|
|
if(p->concealed_pic)
|
495 |
|
|
{
|
496 |
|
|
fprintf(stdout,"%04d(P) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
|
497 |
|
|
frame_no, p->frame_poc, p->pic_num, p->qp,
|
498 |
|
|
snr->snr_y, snr->snr_u, snr->snr_v, yuv_types[p->chroma_format_idc], 0);
|
499 |
|
|
|
500 |
|
|
}
|
501 |
|
|
}
|
502 |
|
|
|
503 |
|
|
|
504 |
|
|
/*!
|
505 |
|
|
************************************************************************
|
506 |
|
|
* \brief
|
507 |
|
|
* Interpolation of 1/4 subpixel
|
508 |
|
|
************************************************************************
|
509 |
|
|
*/
|
510 |
|
|
void get_block(int ref_frame, StorablePicture **list, int x_pos, int y_pos, struct img_par *img, int block[BLOCK_SIZE][BLOCK_SIZE])
|
511 |
|
|
{
|
512 |
|
|
|
513 |
|
|
int dx, dy;
|
514 |
|
|
int i, j;
|
515 |
|
|
int maxold_x,maxold_y;
|
516 |
|
|
int result;
|
517 |
|
|
int pres_x, pres_y;
|
518 |
|
|
|
519 |
|
|
int tmp_res[9][9];
|
520 |
|
|
static const int COEF[6] = { 1, -5, 20, 20, -5, 1 };
|
521 |
|
|
StorablePicture *curr_ref = list[ref_frame];
|
522 |
|
|
static imgpel **cur_imgY, *cur_lineY;
|
523 |
|
|
static int jpos_m2, jpos_m1, jpos, jpos_p1, jpos_p2, jpos_p3;
|
524 |
|
|
static int ipos_m2, ipos_m1, ipos, ipos_p1, ipos_p2, ipos_p3;
|
525 |
|
|
|
526 |
|
|
if (curr_ref == no_reference_picture && img->framepoc < img->recovery_poc)
|
527 |
|
|
{
|
528 |
|
|
printf("list[ref_frame] is equal to 'no reference picture' before RAP\n");
|
529 |
|
|
|
530 |
|
|
/* fill the block with sample value 128 */
|
531 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
532 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
533 |
|
|
block[j][i] = 128;
|
534 |
|
|
return;
|
535 |
|
|
}
|
536 |
|
|
cur_imgY = curr_ref->imgY;
|
537 |
|
|
dx = x_pos&3;
|
538 |
|
|
dy = y_pos&3;
|
539 |
|
|
x_pos = (x_pos-dx)>>2;
|
540 |
|
|
y_pos = (y_pos-dy)>>2;
|
541 |
|
|
|
542 |
|
|
maxold_x = dec_picture->size_x_m1;
|
543 |
|
|
maxold_y = dec_picture->size_y_m1;
|
544 |
|
|
|
545 |
|
|
if (dec_picture->mb_field[img->current_mb_nr])
|
546 |
|
|
maxold_y = (dec_picture->size_y >> 1) - 1;
|
547 |
|
|
|
548 |
|
|
if (dx == 0 && dy == 0)
|
549 |
|
|
{ /* fullpel position */
|
550 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
551 |
|
|
{
|
552 |
|
|
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
|
553 |
|
|
|
554 |
|
|
block[j][0] = cur_lineY[iClip3(0,maxold_x,x_pos )];
|
555 |
|
|
block[j][1] = cur_lineY[iClip3(0,maxold_x,x_pos+1)];
|
556 |
|
|
block[j][2] = cur_lineY[iClip3(0,maxold_x,x_pos+2)];
|
557 |
|
|
block[j][3] = cur_lineY[iClip3(0,maxold_x,x_pos+3)];
|
558 |
|
|
}
|
559 |
|
|
}
|
560 |
|
|
else
|
561 |
|
|
{ /* other positions */
|
562 |
|
|
|
563 |
|
|
if (dy == 0)
|
564 |
|
|
{ /* No vertical interpolation */
|
565 |
|
|
|
566 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
567 |
|
|
{
|
568 |
|
|
ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
|
569 |
|
|
ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
|
570 |
|
|
ipos = iClip3(0, maxold_x, x_pos + i );
|
571 |
|
|
ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
|
572 |
|
|
ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
|
573 |
|
|
ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
|
574 |
|
|
|
575 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
576 |
|
|
{
|
577 |
|
|
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
|
578 |
|
|
|
579 |
|
|
result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
|
580 |
|
|
result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
|
581 |
|
|
result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
|
582 |
|
|
|
583 |
|
|
block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
|
584 |
|
|
}
|
585 |
|
|
}
|
586 |
|
|
|
587 |
|
|
if ((dx&1) == 1)
|
588 |
|
|
{
|
589 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
590 |
|
|
{
|
591 |
|
|
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j)];
|
592 |
|
|
block[j][0] = (block[j][0] + cur_lineY[iClip3(0,maxold_x,x_pos +(dx>>1))] + 1 )>>1;
|
593 |
|
|
block[j][1] = (block[j][1] + cur_lineY[iClip3(0,maxold_x,x_pos+1+(dx>>1))] + 1 )>>1;
|
594 |
|
|
block[j][2] = (block[j][2] + cur_lineY[iClip3(0,maxold_x,x_pos+2+(dx>>1))] + 1 )>>1;
|
595 |
|
|
block[j][3] = (block[j][3] + cur_lineY[iClip3(0,maxold_x,x_pos+3+(dx>>1))] + 1 )>>1;
|
596 |
|
|
}
|
597 |
|
|
}
|
598 |
|
|
}
|
599 |
|
|
else if (dx == 0)
|
600 |
|
|
{ /* No horizontal interpolation */
|
601 |
|
|
|
602 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
603 |
|
|
{
|
604 |
|
|
jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
|
605 |
|
|
jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
|
606 |
|
|
jpos = iClip3(0, maxold_y, y_pos + j );
|
607 |
|
|
jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
|
608 |
|
|
jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
|
609 |
|
|
jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
|
610 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
611 |
|
|
{
|
612 |
|
|
pres_x = iClip3(0,maxold_x,x_pos+i);
|
613 |
|
|
|
614 |
|
|
result = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x]) * COEF[0];
|
615 |
|
|
result += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x]) * COEF[1];
|
616 |
|
|
result += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x]) * COEF[2];
|
617 |
|
|
block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
|
618 |
|
|
}
|
619 |
|
|
}
|
620 |
|
|
|
621 |
|
|
if ((dy&1) == 1)
|
622 |
|
|
{
|
623 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
624 |
|
|
{
|
625 |
|
|
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos+j+(dy>>1))];
|
626 |
|
|
block[j][0] = (block[j][0] + cur_lineY[iClip3(0,maxold_x,x_pos )] + 1 )>>1;
|
627 |
|
|
block[j][1] = (block[j][1] + cur_lineY[iClip3(0,maxold_x,x_pos+1)] + 1 )>>1;
|
628 |
|
|
block[j][2] = (block[j][2] + cur_lineY[iClip3(0,maxold_x,x_pos+2)] + 1 )>>1;
|
629 |
|
|
block[j][3] = (block[j][3] + cur_lineY[iClip3(0,maxold_x,x_pos+3)] + 1 )>>1;
|
630 |
|
|
}
|
631 |
|
|
}
|
632 |
|
|
}
|
633 |
|
|
else if (dx == 2)
|
634 |
|
|
{ /* Vertical & horizontal interpolation */
|
635 |
|
|
|
636 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
637 |
|
|
{
|
638 |
|
|
ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
|
639 |
|
|
ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
|
640 |
|
|
ipos = iClip3(0, maxold_x, x_pos + i );
|
641 |
|
|
ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
|
642 |
|
|
ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
|
643 |
|
|
ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
|
644 |
|
|
|
645 |
|
|
for (j = 0; j < BLOCK_SIZE + 5; j++)
|
646 |
|
|
{
|
647 |
|
|
cur_lineY = cur_imgY[iClip3(0,maxold_y,y_pos + j - 2)];
|
648 |
|
|
|
649 |
|
|
tmp_res[j][i] = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
|
650 |
|
|
tmp_res[j][i] += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
|
651 |
|
|
tmp_res[j][i] += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
|
652 |
|
|
}
|
653 |
|
|
}
|
654 |
|
|
|
655 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
656 |
|
|
{
|
657 |
|
|
jpos_m2 = j ;
|
658 |
|
|
jpos_m1 = j + 1;
|
659 |
|
|
jpos = j + 2;
|
660 |
|
|
jpos_p1 = j + 3;
|
661 |
|
|
jpos_p2 = j + 4;
|
662 |
|
|
jpos_p3 = j + 5;
|
663 |
|
|
|
664 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
665 |
|
|
{
|
666 |
|
|
result = (tmp_res[jpos_m2][i] + tmp_res[jpos_p3][i]) * COEF[0];
|
667 |
|
|
result += (tmp_res[jpos_m1][i] + tmp_res[jpos_p2][i]) * COEF[1];
|
668 |
|
|
result += (tmp_res[jpos ][i] + tmp_res[jpos_p1][i]) * COEF[2];
|
669 |
|
|
|
670 |
|
|
block[j][i] = iClip1(img->max_imgpel_value, ((result+512)>>10));
|
671 |
|
|
}
|
672 |
|
|
}
|
673 |
|
|
|
674 |
|
|
if ((dy&1) == 1)
|
675 |
|
|
{
|
676 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
677 |
|
|
{
|
678 |
|
|
pres_y = j+2+(dy>>1);
|
679 |
|
|
|
680 |
|
|
block[j][0] = (block[j][0] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][0]+16)>>5)) +1 )>>1;
|
681 |
|
|
block[j][1] = (block[j][1] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][1]+16)>>5)) +1 )>>1;
|
682 |
|
|
block[j][2] = (block[j][2] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][2]+16)>>5)) +1 )>>1;
|
683 |
|
|
block[j][3] = (block[j][3] + iClip1(img->max_imgpel_value, ((tmp_res[pres_y][3]+16)>>5)) +1 )>>1;
|
684 |
|
|
}
|
685 |
|
|
}
|
686 |
|
|
}
|
687 |
|
|
else if (dy == 2)
|
688 |
|
|
{ /* Horizontal & vertical interpolation */
|
689 |
|
|
|
690 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
691 |
|
|
{
|
692 |
|
|
jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
|
693 |
|
|
jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
|
694 |
|
|
jpos = iClip3(0, maxold_y, y_pos + j );
|
695 |
|
|
jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
|
696 |
|
|
jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
|
697 |
|
|
jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
|
698 |
|
|
for (i = 0; i < BLOCK_SIZE+5; i++)
|
699 |
|
|
{
|
700 |
|
|
pres_x = iClip3(0,maxold_x,x_pos+i - 2);
|
701 |
|
|
tmp_res[j][i] = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x])*COEF[0];
|
702 |
|
|
tmp_res[j][i] += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x])*COEF[1];
|
703 |
|
|
tmp_res[j][i] += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x])*COEF[2];
|
704 |
|
|
}
|
705 |
|
|
}
|
706 |
|
|
|
707 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
708 |
|
|
{
|
709 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
710 |
|
|
{
|
711 |
|
|
result = (tmp_res[j][i ] + tmp_res[j][i + 5]) * COEF[0];
|
712 |
|
|
result += (tmp_res[j][i + 1] + tmp_res[j][i + 4]) * COEF[1];
|
713 |
|
|
result += (tmp_res[j][i + 2] + tmp_res[j][i + 3]) * COEF[2];
|
714 |
|
|
block[j][i] = iClip1(img->max_imgpel_value, ((result+512)>>10));
|
715 |
|
|
}
|
716 |
|
|
}
|
717 |
|
|
|
718 |
|
|
if ((dx&1) == 1)
|
719 |
|
|
{
|
720 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
721 |
|
|
{
|
722 |
|
|
block[j][0] = (block[j][0] + iClip1(img->max_imgpel_value, ((tmp_res[j][2+(dx>>1)]+16)>>5))+1)>>1;
|
723 |
|
|
block[j][1] = (block[j][1] + iClip1(img->max_imgpel_value, ((tmp_res[j][3+(dx>>1)]+16)>>5))+1)>>1;
|
724 |
|
|
block[j][2] = (block[j][2] + iClip1(img->max_imgpel_value, ((tmp_res[j][4+(dx>>1)]+16)>>5))+1)>>1;
|
725 |
|
|
block[j][3] = (block[j][3] + iClip1(img->max_imgpel_value, ((tmp_res[j][5+(dx>>1)]+16)>>5))+1)>>1;
|
726 |
|
|
}
|
727 |
|
|
}
|
728 |
|
|
}
|
729 |
|
|
else
|
730 |
|
|
{ /* Diagonal interpolation */
|
731 |
|
|
|
732 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
733 |
|
|
{
|
734 |
|
|
ipos_m2 = iClip3(0, maxold_x, x_pos + i - 2);
|
735 |
|
|
ipos_m1 = iClip3(0, maxold_x, x_pos + i - 1);
|
736 |
|
|
ipos = iClip3(0, maxold_x, x_pos + i );
|
737 |
|
|
ipos_p1 = iClip3(0, maxold_x, x_pos + i + 1);
|
738 |
|
|
ipos_p2 = iClip3(0, maxold_x, x_pos + i + 2);
|
739 |
|
|
ipos_p3 = iClip3(0, maxold_x, x_pos + i + 3);
|
740 |
|
|
|
741 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
742 |
|
|
{
|
743 |
|
|
cur_lineY = cur_imgY[iClip3(0,maxold_y,(dy == 1 ? y_pos+j : y_pos+j+1))];
|
744 |
|
|
|
745 |
|
|
result = (cur_lineY[ipos_m2] + cur_lineY[ipos_p3]) * COEF[0];
|
746 |
|
|
result += (cur_lineY[ipos_m1] + cur_lineY[ipos_p2]) * COEF[1];
|
747 |
|
|
result += (cur_lineY[ipos ] + cur_lineY[ipos_p1]) * COEF[2];
|
748 |
|
|
|
749 |
|
|
block[j][i] = iClip1(img->max_imgpel_value, ((result+16)>>5));
|
750 |
|
|
}
|
751 |
|
|
}
|
752 |
|
|
|
753 |
|
|
for (j = 0; j < BLOCK_SIZE; j++)
|
754 |
|
|
{
|
755 |
|
|
jpos_m2 = iClip3(0, maxold_y, y_pos + j - 2);
|
756 |
|
|
jpos_m1 = iClip3(0, maxold_y, y_pos + j - 1);
|
757 |
|
|
jpos = iClip3(0, maxold_y, y_pos + j );
|
758 |
|
|
jpos_p1 = iClip3(0, maxold_y, y_pos + j + 1);
|
759 |
|
|
jpos_p2 = iClip3(0, maxold_y, y_pos + j + 2);
|
760 |
|
|
jpos_p3 = iClip3(0, maxold_y, y_pos + j + 3);
|
761 |
|
|
for (i = 0; i < BLOCK_SIZE; i++)
|
762 |
|
|
{
|
763 |
|
|
pres_x = dx == 1 ? x_pos+i : x_pos+i+1;
|
764 |
|
|
pres_x = iClip3(0,maxold_x,pres_x);
|
765 |
|
|
|
766 |
|
|
result = (cur_imgY[jpos_m2][pres_x] + cur_imgY[jpos_p3][pres_x]) * COEF[0];
|
767 |
|
|
result += (cur_imgY[jpos_m1][pres_x] + cur_imgY[jpos_p2][pres_x]) * COEF[1];
|
768 |
|
|
result += (cur_imgY[jpos ][pres_x] + cur_imgY[jpos_p1][pres_x]) * COEF[2];
|
769 |
|
|
|
770 |
|
|
block[j][i] = (block[j][i] + iClip1(img->max_imgpel_value, ((result+16)>>5)) +1 ) >>1;
|
771 |
|
|
}
|
772 |
|
|
}
|
773 |
|
|
|
774 |
|
|
}
|
775 |
|
|
}
|
776 |
|
|
}
|
777 |
|
|
|
778 |
|
|
|
779 |
|
|
void reorder_lists(int currSliceType, Slice * currSlice)
|
780 |
|
|
{
|
781 |
|
|
|
782 |
|
|
if ((currSliceType != I_SLICE)&&(currSliceType != SI_SLICE))
|
783 |
|
|
{
|
784 |
|
|
if (currSlice->ref_pic_list_reordering_flag_l0)
|
785 |
|
|
{
|
786 |
|
|
reorder_ref_pic_list(listX[0], &listXsize[0],
|
787 |
|
|
img->num_ref_idx_l0_active - 1,
|
788 |
|
|
currSlice->reordering_of_pic_nums_idc_l0,
|
789 |
|
|
currSlice->abs_diff_pic_num_minus1_l0,
|
790 |
|
|
currSlice->long_term_pic_idx_l0);
|
791 |
|
|
}
|
792 |
|
|
if (no_reference_picture == listX[0][img->num_ref_idx_l0_active-1])
|
793 |
|
|
{
|
794 |
|
|
if (non_conforming_stream)
|
795 |
|
|
printf("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture'\n");
|
796 |
|
|
else
|
797 |
|
|
error("RefPicList0[ num_ref_idx_l0_active_minus1 ] is equal to 'no reference picture', invalid bitstream",500);
|
798 |
|
|
}
|
799 |
|
|
// that's a definition
|
800 |
|
|
listXsize[0] = img->num_ref_idx_l0_active;
|
801 |
|
|
}
|
802 |
|
|
if (currSliceType == B_SLICE)
|
803 |
|
|
{
|
804 |
|
|
if (currSlice->ref_pic_list_reordering_flag_l1)
|
805 |
|
|
{
|
806 |
|
|
reorder_ref_pic_list(listX[1], &listXsize[1],
|
807 |
|
|
img->num_ref_idx_l1_active - 1,
|
808 |
|
|
currSlice->reordering_of_pic_nums_idc_l1,
|
809 |
|
|
currSlice->abs_diff_pic_num_minus1_l1,
|
810 |
|
|
currSlice->long_term_pic_idx_l1);
|
811 |
|
|
}
|
812 |
|
|
if (no_reference_picture == listX[1][img->num_ref_idx_l1_active-1])
|
813 |
|
|
{
|
814 |
|
|
if (non_conforming_stream)
|
815 |
|
|
printf("RefPicList1[ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture'\n");
|
816 |
|
|
else
|
817 |
|
|
error("RefPicList1[ num_ref_idx_l1_active_minus1 ] is equal to 'no reference picture', invalid bitstream",500);
|
818 |
|
|
}
|
819 |
|
|
// that's a definition
|
820 |
|
|
listXsize[1] = img->num_ref_idx_l1_active;
|
821 |
|
|
}
|
822 |
|
|
|
823 |
|
|
free_ref_pic_list_reordering_buffer(currSlice);
|
824 |
|
|
}
|
825 |
|
|
|
826 |
|
|
|
827 |
|
|
/*!
|
828 |
|
|
************************************************************************
|
829 |
|
|
* \brief
|
830 |
|
|
* initialize ref_pic_num array
|
831 |
|
|
************************************************************************
|
832 |
|
|
*/
|
833 |
|
|
void set_ref_pic_num()
|
834 |
|
|
{
|
835 |
|
|
int i,j;
|
836 |
|
|
|
837 |
|
|
int slice_id=img->current_slice_nr;
|
838 |
|
|
|
839 |
|
|
for (i=0;i<listXsize[LIST_0];i++)
|
840 |
|
|
{
|
841 |
|
|
dec_picture->ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->poc * 2 + ((listX[LIST_0][i]->structure==BOTTOM_FIELD)?1:0) ;
|
842 |
|
|
dec_picture->frm_ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->frame_poc * 2;
|
843 |
|
|
dec_picture->top_ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->top_poc * 2;
|
844 |
|
|
dec_picture->bottom_ref_pic_num [slice_id][LIST_0][i]=listX[LIST_0][i]->bottom_poc * 2 + 1;
|
845 |
|
|
//printf("POCS %d %d %d %d ",listX[LIST_0][i]->frame_poc,listX[LIST_0][i]->bottom_poc,listX[LIST_0][i]->top_poc,listX[LIST_0][i]->poc);
|
846 |
|
|
//printf("refid %d %d %d %d\n",(int) dec_picture->frm_ref_pic_num[LIST_0][i],(int) dec_picture->top_ref_pic_num[LIST_0][i],(int) dec_picture->bottom_ref_pic_num[LIST_0][i],(int) dec_picture->ref_pic_num[LIST_0][i]);
|
847 |
|
|
}
|
848 |
|
|
|
849 |
|
|
for (i=0;i<listXsize[LIST_1];i++)
|
850 |
|
|
{
|
851 |
|
|
dec_picture->ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->poc *2 + ((listX[LIST_1][i]->structure==BOTTOM_FIELD)?1:0);
|
852 |
|
|
dec_picture->frm_ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->frame_poc * 2;
|
853 |
|
|
dec_picture->top_ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->top_poc * 2;
|
854 |
|
|
dec_picture->bottom_ref_pic_num [slice_id][LIST_1][i]=listX[LIST_1][i]->bottom_poc * 2 + 1;
|
855 |
|
|
}
|
856 |
|
|
|
857 |
|
|
if (!active_sps->frame_mbs_only_flag)
|
858 |
|
|
{
|
859 |
|
|
if (img->structure==FRAME)
|
860 |
|
|
for (j=2;j<6;j++)
|
861 |
|
|
for (i=0;i<listXsize[j];i++)
|
862 |
|
|
{
|
863 |
|
|
dec_picture->ref_pic_num [slice_id][j][i] = listX[j][i]->poc * 2 + ((listX[j][i]->structure==BOTTOM_FIELD)?1:0);
|
864 |
|
|
dec_picture->frm_ref_pic_num [slice_id][j][i] = listX[j][i]->frame_poc * 2 ;
|
865 |
|
|
dec_picture->top_ref_pic_num [slice_id][j][i] = listX[j][i]->top_poc * 2 ;
|
866 |
|
|
dec_picture->bottom_ref_pic_num [slice_id][j][i] = listX[j][i]->bottom_poc * 2 + 1;
|
867 |
|
|
}
|
868 |
|
|
}
|
869 |
|
|
|
870 |
|
|
}
|
871 |
|
|
|
872 |
|
|
|
873 |
|
|
/*!
|
874 |
|
|
************************************************************************
|
875 |
|
|
* \brief
|
876 |
|
|
* Reads new slice from bit_stream
|
877 |
|
|
************************************************************************
|
878 |
|
|
*/
|
879 |
|
|
int read_new_slice()
|
880 |
|
|
{
|
881 |
|
|
NALU_t *nalu = AllocNALU(MAX_CODED_FRAME_SIZE);
|
882 |
|
|
int current_header = 0;
|
883 |
|
|
int ret;
|
884 |
|
|
int BitsUsedByHeader;
|
885 |
|
|
Slice *currSlice = img->currentSlice;
|
886 |
|
|
Bitstream *currStream;
|
887 |
|
|
|
888 |
|
|
int slice_id_a, slice_id_b, slice_id_c;
|
889 |
|
|
int redundant_pic_cnt_b, redundant_pic_cnt_c;
|
890 |
|
|
long ftell_position;
|
891 |
|
|
|
892 |
|
|
while (1)
|
893 |
|
|
{
|
894 |
|
|
ftell_position = ftell(bits);
|
895 |
|
|
|
896 |
|
|
if (input->FileFormat == PAR_OF_ANNEXB)
|
897 |
|
|
ret=GetAnnexbNALU (nalu);
|
898 |
|
|
else
|
899 |
|
|
ret=GetRTPNALU (nalu);
|
900 |
|
|
|
901 |
|
|
//In some cases, zero_byte shall be present. If current NALU is a VCL NALU, we can't tell
|
902 |
|
|
//whether it is the first VCL NALU at this point, so only non-VCL NAL unit is checked here.
|
903 |
|
|
CheckZeroByteNonVCL(nalu, &ret);
|
904 |
|
|
|
905 |
|
|
NALUtoRBSP(nalu);
|
906 |
|
|
|
907 |
|
|
if (ret < 0)
|
908 |
|
|
printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
|
909 |
|
|
if (ret == 0)
|
910 |
|
|
{
|
911 |
|
|
FreeNALU(nalu);
|
912 |
|
|
return EOS;
|
913 |
|
|
}
|
914 |
|
|
|
915 |
|
|
// Got a NALU
|
916 |
|
|
if (nalu->forbidden_bit)
|
917 |
|
|
{
|
918 |
|
|
printf ("Found NALU w/ forbidden_bit set, bit error? Let's try...\n");
|
919 |
|
|
}
|
920 |
|
|
|
921 |
|
|
switch (nalu->nal_unit_type)
|
922 |
|
|
{
|
923 |
|
|
case NALU_TYPE_SLICE:
|
924 |
|
|
case NALU_TYPE_IDR:
|
925 |
|
|
|
926 |
|
|
if (img->recovery_point || nalu->nal_unit_type == NALU_TYPE_IDR)
|
927 |
|
|
{
|
928 |
|
|
if (img->recovery_point_found == 0)
|
929 |
|
|
{
|
930 |
|
|
if (nalu->nal_unit_type != NALU_TYPE_IDR)
|
931 |
|
|
{
|
932 |
|
|
printf("Warning: Decoding does not start with an IDR picture.\n");
|
933 |
|
|
non_conforming_stream = 1;
|
934 |
|
|
}
|
935 |
|
|
else
|
936 |
|
|
non_conforming_stream = 0;
|
937 |
|
|
}
|
938 |
|
|
img->recovery_point_found = 1;
|
939 |
|
|
}
|
940 |
|
|
|
941 |
|
|
if (img->recovery_point_found == 0)
|
942 |
|
|
break;
|
943 |
|
|
|
944 |
|
|
img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
|
945 |
|
|
img->nal_reference_idc = nalu->nal_reference_idc;
|
946 |
|
|
currSlice->dp_mode = PAR_DP_1;
|
947 |
|
|
currSlice->max_part_nr = 1;
|
948 |
|
|
currSlice->ei_flag = 0;
|
949 |
|
|
currStream = currSlice->partArr[0].bitstream;
|
950 |
|
|
currStream->ei_flag = 0;
|
951 |
|
|
currStream->frame_bitoffset = currStream->read_len = 0;
|
952 |
|
|
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
|
953 |
|
|
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
|
954 |
|
|
|
955 |
|
|
// Some syntax of the Slice Header depends on the parameter set, which depends on
|
956 |
|
|
// the parameter set ID of the SLice header. Hence, read the pic_parameter_set_id
|
957 |
|
|
// of the slice header first, then setup the active parameter sets, and then read
|
958 |
|
|
// the rest of the slice header
|
959 |
|
|
BitsUsedByHeader = FirstPartOfSliceHeader();
|
960 |
|
|
UseParameterSet (currSlice->pic_parameter_set_id);
|
961 |
|
|
BitsUsedByHeader+= RestOfSliceHeader ();
|
962 |
|
|
|
963 |
|
|
FmoInit (active_pps, active_sps);
|
964 |
|
|
|
965 |
|
|
AssignQuantParam (active_pps, active_sps);
|
966 |
|
|
|
967 |
|
|
// if primary slice is replaced with redundant slice, set the correct image type
|
968 |
|
|
if(img->redundant_pic_cnt && Is_primary_correct==0 && Is_redundant_correct)
|
969 |
|
|
{
|
970 |
|
|
dec_picture->slice_type=img->type;
|
971 |
|
|
}
|
972 |
|
|
|
973 |
|
|
if(is_new_picture())
|
974 |
|
|
{
|
975 |
|
|
init_picture(img, input);
|
976 |
|
|
|
977 |
|
|
current_header = SOP;
|
978 |
|
|
//check zero_byte if it is also the first NAL unit in the access unit
|
979 |
|
|
CheckZeroByteVCL(nalu, &ret);
|
980 |
|
|
}
|
981 |
|
|
else
|
982 |
|
|
current_header = SOS;
|
983 |
|
|
|
984 |
|
|
init_lists(img->type, img->currentSlice->structure);
|
985 |
|
|
reorder_lists (img->type, img->currentSlice);
|
986 |
|
|
|
987 |
|
|
if (img->structure==FRAME)
|
988 |
|
|
{
|
989 |
|
|
init_mbaff_lists();
|
990 |
|
|
}
|
991 |
|
|
|
992 |
|
|
/* if (img->frame_num==1) // write a reference list
|
993 |
|
|
{
|
994 |
|
|
count ++;
|
995 |
|
|
if (count==1)
|
996 |
|
|
for (i=0; i<listXsize[0]; i++)
|
997 |
|
|
write_picture(listX[0][i], p_out2);
|
998 |
|
|
}
|
999 |
|
|
*/
|
1000 |
|
|
|
1001 |
|
|
// From here on, active_sps, active_pps and the slice header are valid
|
1002 |
|
|
if (img->MbaffFrameFlag)
|
1003 |
|
|
img->current_mb_nr = currSlice->start_mb_nr << 1;
|
1004 |
|
|
else
|
1005 |
|
|
img->current_mb_nr = currSlice->start_mb_nr;
|
1006 |
|
|
|
1007 |
|
|
if (active_pps->entropy_coding_mode_flag)
|
1008 |
|
|
{
|
1009 |
|
|
int ByteStartPosition = currStream->frame_bitoffset/8;
|
1010 |
|
|
if (currStream->frame_bitoffset%8 != 0)
|
1011 |
|
|
{
|
1012 |
|
|
ByteStartPosition++;
|
1013 |
|
|
}
|
1014 |
|
|
arideco_start_decoding (&currSlice->partArr[0].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len, img->type);
|
1015 |
|
|
}
|
1016 |
|
|
// printf ("read_new_slice: returning %s\n", current_header == SOP?"SOP":"SOS");
|
1017 |
|
|
FreeNALU(nalu);
|
1018 |
|
|
img->recovery_point = 0;
|
1019 |
|
|
return current_header;
|
1020 |
|
|
break;
|
1021 |
|
|
case NALU_TYPE_DPA:
|
1022 |
|
|
// read DP_A
|
1023 |
|
|
img->idr_flag = (nalu->nal_unit_type == NALU_TYPE_IDR);
|
1024 |
|
|
if (img->idr_flag)
|
1025 |
|
|
{
|
1026 |
|
|
printf ("Data partiton A cannot have idr_flag set, trying anyway \n");
|
1027 |
|
|
}
|
1028 |
|
|
img->nal_reference_idc = nalu->nal_reference_idc;
|
1029 |
|
|
currSlice->dp_mode = PAR_DP_3;
|
1030 |
|
|
currSlice->max_part_nr = 3;
|
1031 |
|
|
currSlice->ei_flag = 0;
|
1032 |
|
|
currStream = currSlice->partArr[0].bitstream;
|
1033 |
|
|
currStream->ei_flag = 0;
|
1034 |
|
|
currStream->frame_bitoffset = currStream->read_len = 0;
|
1035 |
|
|
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
|
1036 |
|
|
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
|
1037 |
|
|
|
1038 |
|
|
BitsUsedByHeader = FirstPartOfSliceHeader();
|
1039 |
|
|
UseParameterSet (currSlice->pic_parameter_set_id);
|
1040 |
|
|
BitsUsedByHeader += RestOfSliceHeader ();
|
1041 |
|
|
|
1042 |
|
|
FmoInit (active_pps, active_sps);
|
1043 |
|
|
|
1044 |
|
|
if(is_new_picture())
|
1045 |
|
|
{
|
1046 |
|
|
init_picture(img, input);
|
1047 |
|
|
current_header = SOP;
|
1048 |
|
|
CheckZeroByteVCL(nalu, &ret);
|
1049 |
|
|
}
|
1050 |
|
|
else
|
1051 |
|
|
current_header = SOS;
|
1052 |
|
|
|
1053 |
|
|
init_lists(img->type, img->currentSlice->structure);
|
1054 |
|
|
reorder_lists (img->type, img->currentSlice);
|
1055 |
|
|
|
1056 |
|
|
if (img->structure==FRAME)
|
1057 |
|
|
{
|
1058 |
|
|
init_mbaff_lists();
|
1059 |
|
|
}
|
1060 |
|
|
|
1061 |
|
|
// From here on, active_sps, active_pps and the slice header are valid
|
1062 |
|
|
if (img->MbaffFrameFlag)
|
1063 |
|
|
img->current_mb_nr = currSlice->start_mb_nr << 1;
|
1064 |
|
|
else
|
1065 |
|
|
img->current_mb_nr = currSlice->start_mb_nr;
|
1066 |
|
|
|
1067 |
|
|
// Now I need to read the slice ID, which depends on the value of
|
1068 |
|
|
// redundant_pic_cnt_present_flag
|
1069 |
|
|
|
1070 |
|
|
slice_id_a = ue_v("NALU: DP_A slice_id", currStream);
|
1071 |
|
|
|
1072 |
|
|
if (active_pps->entropy_coding_mode_flag)
|
1073 |
|
|
error ("received data partition with CABAC, this is not allowed", 500);
|
1074 |
|
|
|
1075 |
|
|
// continue with reading next DP
|
1076 |
|
|
ftell_position = ftell(bits);
|
1077 |
|
|
if (input->FileFormat == PAR_OF_ANNEXB)
|
1078 |
|
|
ret=GetAnnexbNALU (nalu);
|
1079 |
|
|
else
|
1080 |
|
|
ret=GetRTPNALU (nalu);
|
1081 |
|
|
|
1082 |
|
|
CheckZeroByteNonVCL(nalu, &ret);
|
1083 |
|
|
NALUtoRBSP(nalu);
|
1084 |
|
|
|
1085 |
|
|
if (ret < 0)
|
1086 |
|
|
printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
|
1087 |
|
|
if (ret == 0)
|
1088 |
|
|
{
|
1089 |
|
|
FreeNALU(nalu);
|
1090 |
|
|
return current_header;
|
1091 |
|
|
}
|
1092 |
|
|
|
1093 |
|
|
if ( NALU_TYPE_DPB == nalu->nal_unit_type)
|
1094 |
|
|
{
|
1095 |
|
|
// we got a DPB
|
1096 |
|
|
currStream = currSlice->partArr[1].bitstream;
|
1097 |
|
|
currStream->ei_flag = 0;
|
1098 |
|
|
currStream->frame_bitoffset = currStream->read_len = 0;
|
1099 |
|
|
|
1100 |
|
|
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
|
1101 |
|
|
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
|
1102 |
|
|
|
1103 |
|
|
slice_id_b = ue_v("NALU: DP_B slice_id", currStream);
|
1104 |
|
|
|
1105 |
|
|
if (slice_id_b != slice_id_a)
|
1106 |
|
|
{
|
1107 |
|
|
printf ("got a data partition B which does not match DP_A\n");
|
1108 |
|
|
// KS: needs error handling !!!
|
1109 |
|
|
}
|
1110 |
|
|
|
1111 |
|
|
if (active_pps->redundant_pic_cnt_present_flag)
|
1112 |
|
|
redundant_pic_cnt_b = ue_v("NALU: DP_B redudant_pic_cnt", currStream);
|
1113 |
|
|
else
|
1114 |
|
|
redundant_pic_cnt_b = 0;
|
1115 |
|
|
|
1116 |
|
|
// we're finished with DP_B, so let's continue with next DP
|
1117 |
|
|
ftell_position = ftell(bits);
|
1118 |
|
|
if (input->FileFormat == PAR_OF_ANNEXB)
|
1119 |
|
|
ret=GetAnnexbNALU (nalu);
|
1120 |
|
|
else
|
1121 |
|
|
ret=GetRTPNALU (nalu);
|
1122 |
|
|
|
1123 |
|
|
CheckZeroByteNonVCL(nalu, &ret);
|
1124 |
|
|
NALUtoRBSP(nalu);
|
1125 |
|
|
|
1126 |
|
|
if (ret < 0)
|
1127 |
|
|
printf ("Error while getting the NALU in file format %s, exit\n", input->FileFormat==PAR_OF_ANNEXB?"Annex B":"RTP");
|
1128 |
|
|
if (ret == 0)
|
1129 |
|
|
{
|
1130 |
|
|
FreeNALU(nalu);
|
1131 |
|
|
return current_header;
|
1132 |
|
|
}
|
1133 |
|
|
}
|
1134 |
|
|
|
1135 |
|
|
// check if we got DP_C
|
1136 |
|
|
if ( NALU_TYPE_DPC == nalu->nal_unit_type)
|
1137 |
|
|
{
|
1138 |
|
|
currStream = currSlice->partArr[2].bitstream;
|
1139 |
|
|
currStream->ei_flag = 0;
|
1140 |
|
|
currStream->frame_bitoffset = currStream->read_len = 0;
|
1141 |
|
|
|
1142 |
|
|
memcpy (currStream->streamBuffer, &nalu->buf[1], nalu->len-1);
|
1143 |
|
|
currStream->code_len = currStream->bitstream_length = RBSPtoSODB(currStream->streamBuffer, nalu->len-1);
|
1144 |
|
|
|
1145 |
|
|
slice_id_c = ue_v("NALU: DP_C slice_id", currStream);
|
1146 |
|
|
if (slice_id_c != slice_id_a)
|
1147 |
|
|
{
|
1148 |
|
|
printf ("got a data partition C which does not match DP_A\n");
|
1149 |
|
|
// KS: needs error handling !!!
|
1150 |
|
|
}
|
1151 |
|
|
|
1152 |
|
|
if (active_pps->redundant_pic_cnt_present_flag)
|
1153 |
|
|
redundant_pic_cnt_c = ue_v("NALU:SLICE_C redudand_pic_cnt", currStream);
|
1154 |
|
|
else
|
1155 |
|
|
redundant_pic_cnt_c = 0;
|
1156 |
|
|
}
|
1157 |
|
|
|
1158 |
|
|
// check if we read anything else than the expected partitions
|
1159 |
|
|
if ((nalu->nal_unit_type != NALU_TYPE_DPB) && (nalu->nal_unit_type != NALU_TYPE_DPC))
|
1160 |
|
|
{
|
1161 |
|
|
// reset bitstream position and read again in next call
|
1162 |
|
|
fseek(bits, ftell_position, SEEK_SET);
|
1163 |
|
|
}
|
1164 |
|
|
|
1165 |
|
|
FreeNALU(nalu);
|
1166 |
|
|
return current_header;
|
1167 |
|
|
|
1168 |
|
|
break;
|
1169 |
|
|
case NALU_TYPE_DPB:
|
1170 |
|
|
printf ("found data partition B without matching DP A, discarding\n");
|
1171 |
|
|
break;
|
1172 |
|
|
case NALU_TYPE_DPC:
|
1173 |
|
|
printf ("found data partition C without matching DP A, discarding\n");
|
1174 |
|
|
break;
|
1175 |
|
|
case NALU_TYPE_SEI:
|
1176 |
|
|
printf ("read_new_slice: Found NALU_TYPE_SEI, len %d\n", nalu->len);
|
1177 |
|
|
InterpretSEIMessage(nalu->buf,nalu->len,img);
|
1178 |
|
|
break;
|
1179 |
|
|
case NALU_TYPE_PPS:
|
1180 |
|
|
ProcessPPS(nalu);
|
1181 |
|
|
break;
|
1182 |
|
|
case NALU_TYPE_SPS:
|
1183 |
|
|
ProcessSPS(nalu);
|
1184 |
|
|
break;
|
1185 |
|
|
case NALU_TYPE_AUD:
|
1186 |
|
|
// printf ("read_new_slice: Found 'Access Unit Delimiter' NAL unit, len %d, ignored\n", nalu->len);
|
1187 |
|
|
break;
|
1188 |
|
|
case NALU_TYPE_EOSEQ:
|
1189 |
|
|
// printf ("read_new_slice: Found 'End of Sequence' NAL unit, len %d, ignored\n", nalu->len);
|
1190 |
|
|
break;
|
1191 |
|
|
case NALU_TYPE_EOSTREAM:
|
1192 |
|
|
// printf ("read_new_slice: Found 'End of Stream' NAL unit, len %d, ignored\n", nalu->len);
|
1193 |
|
|
break;
|
1194 |
|
|
case NALU_TYPE_FILL:
|
1195 |
|
|
printf ("read_new_slice: Found NALU_TYPE_FILL, len %d\n", nalu->len);
|
1196 |
|
|
printf ("Skipping these filling bits, proceeding w/ next NALU\n");
|
1197 |
|
|
break;
|
1198 |
|
|
default:
|
1199 |
|
|
printf ("Found NALU type %d, len %d undefined, ignore NALU, moving on\n", nalu->nal_unit_type, nalu->len);
|
1200 |
|
|
}
|
1201 |
|
|
}
|
1202 |
|
|
FreeNALU(nalu);
|
1203 |
|
|
|
1204 |
|
|
return current_header;
|
1205 |
|
|
}
|
1206 |
|
|
|
1207 |
|
|
|
1208 |
|
|
/*!
|
1209 |
|
|
************************************************************************
|
1210 |
|
|
* \brief
|
1211 |
|
|
* Initializes the parameters for a new picture
|
1212 |
|
|
************************************************************************
|
1213 |
|
|
*/
|
1214 |
|
|
void init_picture(struct img_par *img, struct inp_par *inp)
|
1215 |
|
|
{
|
1216 |
|
|
int i,k,l;
|
1217 |
|
|
Slice *currSlice = img->currentSlice;
|
1218 |
|
|
|
1219 |
|
|
if (dec_picture)
|
1220 |
|
|
{
|
1221 |
|
|
// this may only happen on slice loss
|
1222 |
|
|
exit_picture();
|
1223 |
|
|
}
|
1224 |
|
|
if (img->recovery_point)
|
1225 |
|
|
img->recovery_frame_num = (img->frame_num + img->recovery_frame_cnt) % img->MaxFrameNum;
|
1226 |
|
|
|
1227 |
|
|
if (img->idr_flag)
|
1228 |
|
|
img->recovery_frame_num = img->frame_num;
|
1229 |
|
|
|
1230 |
|
|
if (img->recovery_point == 0 &&
|
1231 |
|
|
img->frame_num != img->pre_frame_num &&
|
1232 |
|
|
img->frame_num != (img->pre_frame_num + 1) % img->MaxFrameNum)
|
1233 |
|
|
{
|
1234 |
|
|
if (active_sps->gaps_in_frame_num_value_allowed_flag == 0)
|
1235 |
|
|
{
|
1236 |
|
|
// picture error concealment
|
1237 |
|
|
if(inp->conceal_mode !=0)
|
1238 |
|
|
{
|
1239 |
|
|
if((img->frame_num) < ((img->pre_frame_num + 1) % img->MaxFrameNum))
|
1240 |
|
|
{
|
1241 |
|
|
/* Conceal lost IDR frames and any frames immediately
|
1242 |
|
|
following the IDR. Use frame copy for these since
|
1243 |
|
|
lists cannot be formed correctly for motion copy*/
|
1244 |
|
|
img->conceal_mode = 1;
|
1245 |
|
|
img->IDR_concealment_flag = 1;
|
1246 |
|
|
conceal_lost_frames(img);
|
1247 |
|
|
//reset to original concealment mode for future drops
|
1248 |
|
|
img->conceal_mode = inp->conceal_mode;
|
1249 |
|
|
}
|
1250 |
|
|
else
|
1251 |
|
|
{
|
1252 |
|
|
//reset to original concealment mode for future drops
|
1253 |
|
|
img->conceal_mode = inp->conceal_mode;
|
1254 |
|
|
|
1255 |
|
|
img->IDR_concealment_flag = 0;
|
1256 |
|
|
conceal_lost_frames(img);
|
1257 |
|
|
}
|
1258 |
|
|
}
|
1259 |
|
|
else
|
1260 |
|
|
{ /* Advanced Error Concealment would be called here to combat unintentional loss of pictures. */
|
1261 |
|
|
error("An unintentional loss of pictures occurs! Exit\n", 100);
|
1262 |
|
|
}
|
1263 |
|
|
}
|
1264 |
|
|
if(img->conceal_mode == 0)
|
1265 |
|
|
fill_frame_num_gap(img);
|
1266 |
|
|
}
|
1267 |
|
|
|
1268 |
|
|
if(img->nal_reference_idc)
|
1269 |
|
|
{
|
1270 |
|
|
img->pre_frame_num = img->frame_num;
|
1271 |
|
|
}
|
1272 |
|
|
|
1273 |
|
|
//img->num_dec_mb = 0;
|
1274 |
|
|
|
1275 |
|
|
//calculate POC
|
1276 |
|
|
decode_poc(img);
|
1277 |
|
|
|
1278 |
|
|
if (img->recovery_frame_num == img->frame_num &&
|
1279 |
|
|
img->recovery_poc == 0x7fffffff)
|
1280 |
|
|
img->recovery_poc = img->framepoc;
|
1281 |
|
|
|
1282 |
|
|
if(img->nal_reference_idc)
|
1283 |
|
|
img->last_ref_pic_poc = img->framepoc;
|
1284 |
|
|
|
1285 |
|
|
// dumppoc (img);
|
1286 |
|
|
|
1287 |
|
|
if (img->structure==FRAME ||img->structure==TOP_FIELD)
|
1288 |
|
|
{
|
1289 |
|
|
#ifdef WIN32
|
1290 |
|
|
_ftime (&(img->tstruct_start)); // start time ms
|
1291 |
|
|
#else
|
1292 |
|
|
ftime (&(img->tstruct_start)); // start time ms
|
1293 |
|
|
#endif
|
1294 |
|
|
time( &(img->ltime_start)); // start time s
|
1295 |
|
|
}
|
1296 |
|
|
|
1297 |
|
|
dec_picture = alloc_storable_picture ((PictureStructure) img->structure, img->width, img->height, img->width_cr, img->height_cr);
|
1298 |
|
|
dec_picture->top_poc=img->toppoc;
|
1299 |
|
|
dec_picture->bottom_poc=img->bottompoc;
|
1300 |
|
|
dec_picture->frame_poc=img->framepoc;
|
1301 |
|
|
dec_picture->qp=img->qp;
|
1302 |
|
|
dec_picture->slice_qp_delta=currSlice->slice_qp_delta;
|
1303 |
|
|
dec_picture->chroma_qp_offset[0] = active_pps->chroma_qp_index_offset;
|
1304 |
|
|
dec_picture->chroma_qp_offset[1] = active_pps->second_chroma_qp_index_offset;
|
1305 |
|
|
|
1306 |
|
|
// reset all variables of the error concealment instance before decoding of every frame.
|
1307 |
|
|
// here the third parameter should, if perfectly, be equal to the number of slices per frame.
|
1308 |
|
|
// using little value is ok, the code will allocate more memory if the slice number is larger
|
1309 |
|
|
ercReset(erc_errorVar, img->PicSizeInMbs, img->PicSizeInMbs, dec_picture->size_x);
|
1310 |
|
|
erc_mvperMB = 0;
|
1311 |
|
|
|
1312 |
|
|
switch (img->structure )
|
1313 |
|
|
{
|
1314 |
|
|
case TOP_FIELD:
|
1315 |
|
|
{
|
1316 |
|
|
dec_picture->poc=img->toppoc;
|
1317 |
|
|
img->number *= 2;
|
1318 |
|
|
break;
|
1319 |
|
|
}
|
1320 |
|
|
case BOTTOM_FIELD:
|
1321 |
|
|
{
|
1322 |
|
|
dec_picture->poc=img->bottompoc;
|
1323 |
|
|
img->number = img->number * 2 + 1;
|
1324 |
|
|
break;
|
1325 |
|
|
}
|
1326 |
|
|
case FRAME:
|
1327 |
|
|
{
|
1328 |
|
|
dec_picture->poc=img->framepoc;
|
1329 |
|
|
break;
|
1330 |
|
|
}
|
1331 |
|
|
default:
|
1332 |
|
|
error("img->structure not initialized", 235);
|
1333 |
|
|
}
|
1334 |
|
|
|
1335 |
|
|
img->current_slice_nr=0;
|
1336 |
|
|
|
1337 |
|
|
if (img->type > SI_SLICE)
|
1338 |
|
|
{
|
1339 |
|
|
set_ec_flag(SE_PTYPE);
|
1340 |
|
|
img->type = P_SLICE; // concealed element
|
1341 |
|
|
}
|
1342 |
|
|
|
1343 |
|
|
// CAVLC init
|
1344 |
|
|
for (i=0;i < (int)img->PicSizeInMbs; i++)
|
1345 |
|
|
for (k=0;k<4;k++)
|
1346 |
|
|
for (l=0;l<(4 + img->num_blk8x8_uv);l++)
|
1347 |
|
|
img->nz_coeff[i][k][l]=-1; // CAVLC
|
1348 |
|
|
|
1349 |
|
|
if(active_pps->constrained_intra_pred_flag)
|
1350 |
|
|
{
|
1351 |
|
|
for (i=0; i<(int)img->PicSizeInMbs; i++)
|
1352 |
|
|
{
|
1353 |
|
|
img->intra_block[i] = 1;
|
1354 |
|
|
}
|
1355 |
|
|
}
|
1356 |
|
|
|
1357 |
|
|
// Set the slice_nr member of each MB to -1, to ensure correct when packet loss occurs
|
1358 |
|
|
// TO set Macroblock Map (mark all MBs as 'have to be concealed')
|
1359 |
|
|
for(i=0; i<(int)img->PicSizeInMbs; i++)
|
1360 |
|
|
{
|
1361 |
|
|
img->mb_data[i].slice_nr = -1;
|
1362 |
|
|
img->mb_data[i].ei_flag = 1;
|
1363 |
|
|
}
|
1364 |
|
|
|
1365 |
|
|
img->mb_y = img->mb_x = 0;
|
1366 |
|
|
img->block_y = img->pix_y = img->pix_c_y = 0; // define vertical positions
|
1367 |
|
|
img->block_x = img->pix_x = img->pix_c_x = 0; // define horizontal positions
|
1368 |
|
|
|
1369 |
|
|
dec_picture->slice_type = img->type;
|
1370 |
|
|
dec_picture->used_for_reference = (img->nal_reference_idc != 0);
|
1371 |
|
|
dec_picture->idr_flag = img->idr_flag;
|
1372 |
|
|
dec_picture->no_output_of_prior_pics_flag = img->no_output_of_prior_pics_flag;
|
1373 |
|
|
dec_picture->long_term_reference_flag = img->long_term_reference_flag;
|
1374 |
|
|
dec_picture->adaptive_ref_pic_buffering_flag = img->adaptive_ref_pic_buffering_flag;
|
1375 |
|
|
|
1376 |
|
|
dec_picture->dec_ref_pic_marking_buffer = img->dec_ref_pic_marking_buffer;
|
1377 |
|
|
img->dec_ref_pic_marking_buffer = NULL;
|
1378 |
|
|
|
1379 |
|
|
dec_picture->MbaffFrameFlag = img->MbaffFrameFlag;
|
1380 |
|
|
dec_picture->PicWidthInMbs = img->PicWidthInMbs;
|
1381 |
|
|
|
1382 |
|
|
get_mb_block_pos = dec_picture->MbaffFrameFlag ? get_mb_block_pos_mbaff : get_mb_block_pos_normal;
|
1383 |
|
|
getNeighbour = dec_picture->MbaffFrameFlag ? getAffNeighbour : getNonAffNeighbour;
|
1384 |
|
|
|
1385 |
|
|
|
1386 |
|
|
|
1387 |
|
|
dec_picture->pic_num = img->frame_num;
|
1388 |
|
|
dec_picture->frame_num = img->frame_num;
|
1389 |
|
|
|
1390 |
|
|
dec_picture->recovery_frame = (img->frame_num == img->recovery_frame_num);
|
1391 |
|
|
|
1392 |
|
|
dec_picture->coded_frame = (img->structure==FRAME);
|
1393 |
|
|
|
1394 |
|
|
dec_picture->chroma_format_idc = active_sps->chroma_format_idc;
|
1395 |
|
|
|
1396 |
|
|
dec_picture->frame_mbs_only_flag = active_sps->frame_mbs_only_flag;
|
1397 |
|
|
dec_picture->frame_cropping_flag = active_sps->frame_cropping_flag;
|
1398 |
|
|
|
1399 |
|
|
if (dec_picture->frame_cropping_flag)
|
1400 |
|
|
{
|
1401 |
|
|
dec_picture->frame_cropping_rect_left_offset = active_sps->frame_cropping_rect_left_offset;
|
1402 |
|
|
dec_picture->frame_cropping_rect_right_offset = active_sps->frame_cropping_rect_right_offset;
|
1403 |
|
|
dec_picture->frame_cropping_rect_top_offset = active_sps->frame_cropping_rect_top_offset;
|
1404 |
|
|
dec_picture->frame_cropping_rect_bottom_offset = active_sps->frame_cropping_rect_bottom_offset;
|
1405 |
|
|
}
|
1406 |
|
|
}
|
1407 |
|
|
|
1408 |
|
|
/*!
|
1409 |
|
|
************************************************************************
|
1410 |
|
|
* \brief
|
1411 |
|
|
* finish decoding of a picture, conceal errors and store it
|
1412 |
|
|
* into the DPB
|
1413 |
|
|
************************************************************************
|
1414 |
|
|
*/
|
1415 |
|
|
void exit_picture()
|
1416 |
|
|
{
|
1417 |
|
|
char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
|
1418 |
|
|
int ercStartMB;
|
1419 |
|
|
int ercSegment;
|
1420 |
|
|
frame recfr;
|
1421 |
|
|
unsigned int i;
|
1422 |
|
|
int structure, frame_poc, slice_type, refpic, qp, pic_num, chroma_format_idc;
|
1423 |
|
|
|
1424 |
|
|
time_t tmp_time; // time used by decoding the last frame
|
1425 |
|
|
char yuvFormat[10];
|
1426 |
|
|
|
1427 |
|
|
// return if the last picture has already been finished
|
1428 |
|
|
if (dec_picture==NULL)
|
1429 |
|
|
{
|
1430 |
|
|
return;
|
1431 |
|
|
}
|
1432 |
|
|
|
1433 |
|
|
//deblocking for frame or field
|
1434 |
|
|
DeblockPicture( img, dec_picture );
|
1435 |
|
|
|
1436 |
|
|
if (dec_picture->MbaffFrameFlag)
|
1437 |
|
|
MbAffPostProc();
|
1438 |
|
|
|
1439 |
|
|
recfr.yptr = &dec_picture->imgY[0][0];
|
1440 |
|
|
if (dec_picture->chroma_format_idc != YUV400)
|
1441 |
|
|
{
|
1442 |
|
|
recfr.uptr = &dec_picture->imgUV[0][0][0];
|
1443 |
|
|
recfr.vptr = &dec_picture->imgUV[1][0][0];
|
1444 |
|
|
}
|
1445 |
|
|
|
1446 |
|
|
//! this is always true at the beginning of a picture
|
1447 |
|
|
ercStartMB = 0;
|
1448 |
|
|
ercSegment = 0;
|
1449 |
|
|
|
1450 |
|
|
//! mark the start of the first segment
|
1451 |
|
|
if (!dec_picture->MbaffFrameFlag)
|
1452 |
|
|
{
|
1453 |
|
|
ercStartSegment(0, ercSegment, 0 , erc_errorVar);
|
1454 |
|
|
//! generate the segments according to the macroblock map
|
1455 |
|
|
for(i = 1; i<dec_picture->PicSizeInMbs; i++)
|
1456 |
|
|
{
|
1457 |
|
|
if(img->mb_data[i].ei_flag != img->mb_data[i-1].ei_flag)
|
1458 |
|
|
{
|
1459 |
|
|
ercStopSegment(i-1, ercSegment, 0, erc_errorVar); //! stop current segment
|
1460 |
|
|
|
1461 |
|
|
//! mark current segment as lost or OK
|
1462 |
|
|
if(img->mb_data[i-1].ei_flag)
|
1463 |
|
|
ercMarkCurrSegmentLost(dec_picture->size_x, erc_errorVar);
|
1464 |
|
|
else
|
1465 |
|
|
ercMarkCurrSegmentOK(dec_picture->size_x, erc_errorVar);
|
1466 |
|
|
|
1467 |
|
|
ercSegment++; //! next segment
|
1468 |
|
|
ercStartSegment(i, ercSegment, 0 , erc_errorVar); //! start new segment
|
1469 |
|
|
ercStartMB = i;//! save start MB for this segment
|
1470 |
|
|
}
|
1471 |
|
|
}
|
1472 |
|
|
//! mark end of the last segment
|
1473 |
|
|
ercStopSegment(dec_picture->PicSizeInMbs-1, ercSegment, 0, erc_errorVar);
|
1474 |
|
|
if(img->mb_data[i-1].ei_flag)
|
1475 |
|
|
ercMarkCurrSegmentLost(dec_picture->size_x, erc_errorVar);
|
1476 |
|
|
else
|
1477 |
|
|
ercMarkCurrSegmentOK(dec_picture->size_x, erc_errorVar);
|
1478 |
|
|
|
1479 |
|
|
//! call the right error concealment function depending on the frame type.
|
1480 |
|
|
erc_mvperMB /= dec_picture->PicSizeInMbs;
|
1481 |
|
|
|
1482 |
|
|
erc_img = img;
|
1483 |
|
|
if(dec_picture->slice_type == I_SLICE || dec_picture->slice_type == SI_SLICE) // I-frame
|
1484 |
|
|
ercConcealIntraFrame(&recfr, dec_picture->size_x, dec_picture->size_y, erc_errorVar);
|
1485 |
|
|
else
|
1486 |
|
|
ercConcealInterFrame(&recfr, erc_object_list, dec_picture->size_x, dec_picture->size_y, erc_errorVar, dec_picture->chroma_format_idc);
|
1487 |
|
|
}
|
1488 |
|
|
|
1489 |
|
|
if (img->structure == FRAME) // buffer mgt. for frame mode
|
1490 |
|
|
frame_postprocessing(img, input);
|
1491 |
|
|
else
|
1492 |
|
|
field_postprocessing(img, input); // reset all interlaced variables
|
1493 |
|
|
|
1494 |
|
|
structure = dec_picture->structure;
|
1495 |
|
|
slice_type = dec_picture->slice_type;
|
1496 |
|
|
frame_poc = dec_picture->frame_poc;
|
1497 |
|
|
refpic = dec_picture->used_for_reference;
|
1498 |
|
|
qp = dec_picture->qp;
|
1499 |
|
|
pic_num = dec_picture->pic_num;
|
1500 |
|
|
|
1501 |
|
|
chroma_format_idc= dec_picture->chroma_format_idc;
|
1502 |
|
|
|
1503 |
|
|
store_picture_in_dpb(dec_picture);
|
1504 |
|
|
dec_picture=NULL;
|
1505 |
|
|
|
1506 |
|
|
if (img->last_has_mmco_5)
|
1507 |
|
|
{
|
1508 |
|
|
img->pre_frame_num = 0;
|
1509 |
|
|
}
|
1510 |
|
|
|
1511 |
|
|
if ((structure==FRAME)||structure==BOTTOM_FIELD)
|
1512 |
|
|
{
|
1513 |
|
|
|
1514 |
|
|
#ifdef WIN32
|
1515 |
|
|
_ftime (&(img->tstruct_end)); // start time ms
|
1516 |
|
|
#else
|
1517 |
|
|
ftime (&(img->tstruct_end)); // start time ms
|
1518 |
|
|
#endif
|
1519 |
|
|
|
1520 |
|
|
time( &(img->ltime_end)); // start time s
|
1521 |
|
|
|
1522 |
|
|
tmp_time=(img->ltime_end*1000+img->tstruct_end.millitm) - (img->ltime_start*1000+img->tstruct_start.millitm);
|
1523 |
|
|
tot_time=tot_time + tmp_time;
|
1524 |
|
|
|
1525 |
|
|
sprintf(yuvFormat,"%s", yuv_types[chroma_format_idc]);
|
1526 |
|
|
|
1527 |
|
|
if (input->silent == FALSE)
|
1528 |
|
|
{
|
1529 |
|
|
if(slice_type == I_SLICE) // I picture
|
1530 |
|
|
fprintf(stdout,"%04d(I) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
|
1531 |
|
|
frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, (int)tmp_time);
|
1532 |
|
|
else if(slice_type == P_SLICE) // P pictures
|
1533 |
|
|
fprintf(stdout,"%04d(P) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
|
1534 |
|
|
frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, (int)tmp_time);
|
1535 |
|
|
else if(slice_type == SP_SLICE) // SP pictures
|
1536 |
|
|
fprintf(stdout,"%04d(SP) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
|
1537 |
|
|
frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, (int)tmp_time);
|
1538 |
|
|
else if (slice_type == SI_SLICE)
|
1539 |
|
|
fprintf(stdout,"%04d(SI) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
|
1540 |
|
|
frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, (int)tmp_time);
|
1541 |
|
|
else if(refpic) // stored B pictures
|
1542 |
|
|
fprintf(stdout,"%04d(RB) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
|
1543 |
|
|
frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, (int)tmp_time);
|
1544 |
|
|
else // B pictures
|
1545 |
|
|
fprintf(stdout,"%04d(B) %8d %5d %5d %7.4f %7.4f %7.4f %s %5d\n",
|
1546 |
|
|
frame_no, frame_poc, pic_num, qp, snr->snr_y, snr->snr_u, snr->snr_v, yuvFormat, (int)tmp_time);
|
1547 |
|
|
}
|
1548 |
|
|
else
|
1549 |
|
|
fprintf(stdout,"Completed Decoding frame %05d.\r",snr->frame_ctr);
|
1550 |
|
|
|
1551 |
|
|
fflush(stdout);
|
1552 |
|
|
|
1553 |
|
|
if(slice_type == I_SLICE || slice_type == SI_SLICE || slice_type == P_SLICE || refpic) // I or P pictures
|
1554 |
|
|
img->number++;
|
1555 |
|
|
else
|
1556 |
|
|
Bframe_ctr++; // B pictures
|
1557 |
|
|
snr->frame_ctr++;
|
1558 |
|
|
|
1559 |
|
|
g_nFrame++;
|
1560 |
|
|
}
|
1561 |
|
|
|
1562 |
|
|
img->current_mb_nr = -4712; // impossible value for debugging, StW
|
1563 |
|
|
img->current_slice_nr = 0;
|
1564 |
|
|
|
1565 |
|
|
}
|
1566 |
|
|
|
1567 |
|
|
/*!
|
1568 |
|
|
************************************************************************
|
1569 |
|
|
* \brief
|
1570 |
|
|
* write the encoding mode and motion vectors of current
|
1571 |
|
|
* MB to the buffer of the error concealment module.
|
1572 |
|
|
************************************************************************
|
1573 |
|
|
*/
|
1574 |
|
|
|
1575 |
|
|
void ercWriteMBMODEandMV(struct img_par *img,struct inp_par *inp)
|
1576 |
|
|
{
|
1577 |
|
|
extern objectBuffer_t *erc_object_list;
|
1578 |
|
|
int i, ii, jj, currMBNum = img->current_mb_nr;
|
1579 |
|
|
int mbx = xPosMB(currMBNum,dec_picture->size_x), mby = yPosMB(currMBNum,dec_picture->size_x);
|
1580 |
|
|
objectBuffer_t *currRegion, *pRegion;
|
1581 |
|
|
Macroblock *currMB = &img->mb_data[currMBNum];
|
1582 |
|
|
short*** mv;
|
1583 |
|
|
|
1584 |
|
|
currRegion = erc_object_list + (currMBNum<<2);
|
1585 |
|
|
|
1586 |
|
|
if(img->type != B_SLICE) //non-B frame
|
1587 |
|
|
{
|
1588 |
|
|
for (i=0; i<4; i++)
|
1589 |
|
|
{
|
1590 |
|
|
pRegion = currRegion + i;
|
1591 |
|
|
pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
|
1592 |
|
|
currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 :
|
1593 |
|
|
currMB->b8mode[i]==0 ? REGMODE_INTER_COPY :
|
1594 |
|
|
currMB->b8mode[i]==1 ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
|
1595 |
|
|
if (currMB->b8mode[i]==0 || currMB->b8mode[i]==IBLOCK) // INTRA OR COPY
|
1596 |
|
|
{
|
1597 |
|
|
pRegion->mv[0] = 0;
|
1598 |
|
|
pRegion->mv[1] = 0;
|
1599 |
|
|
pRegion->mv[2] = 0;
|
1600 |
|
|
}
|
1601 |
|
|
else
|
1602 |
|
|
{
|
1603 |
|
|
ii = 4*mbx + (i%2)*2;// + BLOCK_SIZE;
|
1604 |
|
|
jj = 4*mby + (i/2)*2;
|
1605 |
|
|
if (currMB->b8mode[i]>=5 && currMB->b8mode[i]<=7) // SMALL BLOCKS
|
1606 |
|
|
{
|
1607 |
|
|
pRegion->mv[0] = (dec_picture->mv[LIST_0][jj][ii][0] + dec_picture->mv[LIST_0][jj][ii+1][0] + dec_picture->mv[LIST_0][jj+1][ii][0] + dec_picture->mv[LIST_0][jj+1][ii+1][0] + 2)/4;
|
1608 |
|
|
pRegion->mv[1] = (dec_picture->mv[LIST_0][jj][ii][1] + dec_picture->mv[LIST_0][jj][ii+1][1] + dec_picture->mv[LIST_0][jj+1][ii][1] + dec_picture->mv[LIST_0][jj+1][ii+1][1] + 2)/4;
|
1609 |
|
|
}
|
1610 |
|
|
else // 16x16, 16x8, 8x16, 8x8
|
1611 |
|
|
{
|
1612 |
|
|
pRegion->mv[0] = dec_picture->mv[LIST_0][jj][ii][0];
|
1613 |
|
|
pRegion->mv[1] = dec_picture->mv[LIST_0][jj][ii][1];
|
1614 |
|
|
// pRegion->mv[0] = dec_picture->mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][0];
|
1615 |
|
|
// pRegion->mv[1] = dec_picture->mv[LIST_0][4*mby+(i/2)*2][4*mbx+(i%2)*2+BLOCK_SIZE][1];
|
1616 |
|
|
}
|
1617 |
|
|
erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
|
1618 |
|
|
pRegion->mv[2] = dec_picture->ref_idx[LIST_0][jj][ii];
|
1619 |
|
|
}
|
1620 |
|
|
}
|
1621 |
|
|
}
|
1622 |
|
|
else //B-frame
|
1623 |
|
|
{
|
1624 |
|
|
for (i=0; i<4; i++)
|
1625 |
|
|
{
|
1626 |
|
|
ii = 4*mbx + (i%2)*2;// + BLOCK_SIZE;
|
1627 |
|
|
jj = 4*mby + (i/2)*2;
|
1628 |
|
|
pRegion = currRegion + i;
|
1629 |
|
|
pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
|
1630 |
|
|
currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 : REGMODE_INTER_PRED_8x8);
|
1631 |
|
|
if (currMB->mb_type==I16MB || currMB->b8mode[i]==IBLOCK) // INTRA
|
1632 |
|
|
{
|
1633 |
|
|
pRegion->mv[0] = 0;
|
1634 |
|
|
pRegion->mv[1] = 0;
|
1635 |
|
|
pRegion->mv[2] = 0;
|
1636 |
|
|
}
|
1637 |
|
|
else
|
1638 |
|
|
{
|
1639 |
|
|
int idx = (dec_picture->ref_idx[0][jj][ii]<0)?1:0;
|
1640 |
|
|
// int idx = (currMB->b8mode[i]==0 && currMB->b8pdir[i]==2 ? LIST_0 : currMB->b8pdir[i]==1 ? LIST_1 : LIST_0);
|
1641 |
|
|
// int idx = currMB->b8pdir[i]==0 ? LIST_0 : LIST_1;
|
1642 |
|
|
mv = dec_picture->mv[idx];
|
1643 |
|
|
pRegion->mv[0] = (mv[jj][ii][0] + mv[jj][ii+1][0] + mv[jj+1][ii][0] + mv[jj+1][ii+1][0] + 2)/4;
|
1644 |
|
|
pRegion->mv[1] = (mv[jj][ii][1] + mv[jj][ii+1][1] + mv[jj+1][ii][1] + mv[jj+1][ii+1][1] + 2)/4;
|
1645 |
|
|
erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
|
1646 |
|
|
|
1647 |
|
|
pRegion->mv[2] = (dec_picture->ref_idx[idx][jj][ii]);
|
1648 |
|
|
/*
|
1649 |
|
|
if (currMB->b8pdir[i]==0 || (currMB->b8pdir[i]==2 && currMB->b8mode[i]!=0)) // forward or bidirect
|
1650 |
|
|
{
|
1651 |
|
|
pRegion->mv[2] = (dec_picture->ref_idx[LIST_0][jj][ii]);
|
1652 |
|
|
///???? is it right, not only "img->fw_refFrArr[jj][ii-4]"
|
1653 |
|
|
}
|
1654 |
|
|
else
|
1655 |
|
|
{
|
1656 |
|
|
pRegion->mv[2] = (dec_picture->ref_idx[LIST_1][jj][ii]);
|
1657 |
|
|
// pRegion->mv[2] = 0;
|
1658 |
|
|
}
|
1659 |
|
|
*/
|
1660 |
|
|
}
|
1661 |
|
|
}
|
1662 |
|
|
}
|
1663 |
|
|
}
|
1664 |
|
|
|
1665 |
|
|
/*!
|
1666 |
|
|
************************************************************************
|
1667 |
|
|
* \brief
|
1668 |
|
|
* set defaults for old_slice
|
1669 |
|
|
* NAL unit of a picture"
|
1670 |
|
|
************************************************************************
|
1671 |
|
|
*/
|
1672 |
|
|
void init_old_slice()
|
1673 |
|
|
{
|
1674 |
|
|
old_slice.field_pic_flag = 0;
|
1675 |
|
|
|
1676 |
|
|
old_slice.pps_id = INT_MAX;
|
1677 |
|
|
|
1678 |
|
|
old_slice.frame_num = INT_MAX;
|
1679 |
|
|
|
1680 |
|
|
old_slice.nal_ref_idc = INT_MAX;
|
1681 |
|
|
|
1682 |
|
|
old_slice.idr_flag = 0;
|
1683 |
|
|
|
1684 |
|
|
old_slice.pic_oder_cnt_lsb = UINT_MAX;
|
1685 |
|
|
old_slice.delta_pic_oder_cnt_bottom = INT_MAX;
|
1686 |
|
|
|
1687 |
|
|
old_slice.delta_pic_order_cnt[0] = INT_MAX;
|
1688 |
|
|
old_slice.delta_pic_order_cnt[1] = INT_MAX;
|
1689 |
|
|
|
1690 |
|
|
}
|
1691 |
|
|
|
1692 |
|
|
/*!
|
1693 |
|
|
************************************************************************
|
1694 |
|
|
* \brief
|
1695 |
|
|
* save slice parameters that are needed for checking of "first VCL
|
1696 |
|
|
* NAL unit of a picture"
|
1697 |
|
|
************************************************************************
|
1698 |
|
|
*/
|
1699 |
|
|
void exit_slice()
|
1700 |
|
|
{
|
1701 |
|
|
|
1702 |
|
|
old_slice.pps_id = img->currentSlice->pic_parameter_set_id;
|
1703 |
|
|
|
1704 |
|
|
old_slice.frame_num = img->frame_num;
|
1705 |
|
|
|
1706 |
|
|
old_slice.field_pic_flag = img->field_pic_flag;
|
1707 |
|
|
|
1708 |
|
|
if(img->field_pic_flag)
|
1709 |
|
|
{
|
1710 |
|
|
old_slice.bottom_field_flag = img->bottom_field_flag;
|
1711 |
|
|
}
|
1712 |
|
|
|
1713 |
|
|
old_slice.nal_ref_idc = img->nal_reference_idc;
|
1714 |
|
|
|
1715 |
|
|
old_slice.idr_flag = img->idr_flag;
|
1716 |
|
|
if (img->idr_flag)
|
1717 |
|
|
{
|
1718 |
|
|
old_slice.idr_pic_id = img->idr_pic_id;
|
1719 |
|
|
}
|
1720 |
|
|
|
1721 |
|
|
if (active_sps->pic_order_cnt_type == 0)
|
1722 |
|
|
{
|
1723 |
|
|
old_slice.pic_oder_cnt_lsb = img->pic_order_cnt_lsb;
|
1724 |
|
|
old_slice.delta_pic_oder_cnt_bottom = img->delta_pic_order_cnt_bottom;
|
1725 |
|
|
}
|
1726 |
|
|
|
1727 |
|
|
if (active_sps->pic_order_cnt_type == 1)
|
1728 |
|
|
{
|
1729 |
|
|
old_slice.delta_pic_order_cnt[0] = img->delta_pic_order_cnt[0];
|
1730 |
|
|
old_slice.delta_pic_order_cnt[1] = img->delta_pic_order_cnt[1];
|
1731 |
|
|
}
|
1732 |
|
|
}
|
1733 |
|
|
|
1734 |
|
|
/*!
|
1735 |
|
|
************************************************************************
|
1736 |
|
|
* \brief
|
1737 |
|
|
* detect if current slice is "first VCL NAL unit of a picture"
|
1738 |
|
|
************************************************************************
|
1739 |
|
|
*/
|
1740 |
|
|
int is_new_picture()
|
1741 |
|
|
{
|
1742 |
|
|
int result=0;
|
1743 |
|
|
|
1744 |
|
|
result |= (NULL==dec_picture);
|
1745 |
|
|
|
1746 |
|
|
result |= (old_slice.pps_id != img->currentSlice->pic_parameter_set_id);
|
1747 |
|
|
|
1748 |
|
|
result |= (old_slice.frame_num != img->frame_num);
|
1749 |
|
|
|
1750 |
|
|
result |= (old_slice.field_pic_flag != img->field_pic_flag);
|
1751 |
|
|
|
1752 |
|
|
if(img->field_pic_flag && old_slice.field_pic_flag)
|
1753 |
|
|
{
|
1754 |
|
|
result |= (old_slice.bottom_field_flag != img->bottom_field_flag);
|
1755 |
|
|
}
|
1756 |
|
|
|
1757 |
|
|
result |= (old_slice.nal_ref_idc != img->nal_reference_idc) && ((old_slice.nal_ref_idc == 0) || (img->nal_reference_idc == 0));
|
1758 |
|
|
|
1759 |
|
|
result |= ( old_slice.idr_flag != img->idr_flag);
|
1760 |
|
|
|
1761 |
|
|
if (img->idr_flag && old_slice.idr_flag)
|
1762 |
|
|
{
|
1763 |
|
|
result |= (old_slice.idr_pic_id != img->idr_pic_id);
|
1764 |
|
|
}
|
1765 |
|
|
|
1766 |
|
|
if (active_sps->pic_order_cnt_type == 0)
|
1767 |
|
|
{
|
1768 |
|
|
result |= (old_slice.pic_oder_cnt_lsb != img->pic_order_cnt_lsb);
|
1769 |
|
|
result |= (old_slice.delta_pic_oder_cnt_bottom != img->delta_pic_order_cnt_bottom);
|
1770 |
|
|
}
|
1771 |
|
|
|
1772 |
|
|
if (active_sps->pic_order_cnt_type == 1)
|
1773 |
|
|
{
|
1774 |
|
|
result |= (old_slice.delta_pic_order_cnt[0] != img->delta_pic_order_cnt[0]);
|
1775 |
|
|
result |= (old_slice.delta_pic_order_cnt[1] != img->delta_pic_order_cnt[1]);
|
1776 |
|
|
}
|
1777 |
|
|
|
1778 |
|
|
return result;
|
1779 |
|
|
}
|
1780 |
|
|
|
1781 |
|
|
|
1782 |
|
|
/*!
|
1783 |
|
|
************************************************************************
|
1784 |
|
|
* \brief
|
1785 |
|
|
* decodes one slice
|
1786 |
|
|
************************************************************************
|
1787 |
|
|
*/
|
1788 |
|
|
void decode_one_slice(struct img_par *img,struct inp_par *inp)
|
1789 |
|
|
{
|
1790 |
|
|
|
1791 |
|
|
Boolean end_of_slice = FALSE;
|
1792 |
|
|
int read_flag;
|
1793 |
|
|
img->cod_counter=-1;
|
1794 |
|
|
|
1795 |
|
|
set_ref_pic_num();
|
1796 |
|
|
|
1797 |
|
|
if (img->type == B_SLICE)
|
1798 |
|
|
compute_colocated(Co_located, listX);
|
1799 |
|
|
|
1800 |
|
|
//reset_ec_flags();
|
1801 |
|
|
|
1802 |
|
|
while (end_of_slice == FALSE) // loop over macroblocks
|
1803 |
|
|
{
|
1804 |
|
|
|
1805 |
|
|
#if TRACE
|
1806 |
|
|
fprintf(p_trace,"\n*********** POC: %i (I/P) MB: %i Slice: %i Type %d **********\n", img->ThisPOC, img->current_mb_nr, img->current_slice_nr, img->type);
|
1807 |
|
|
#endif
|
1808 |
|
|
|
1809 |
|
|
// Initializes the current macroblock
|
1810 |
|
|
start_macroblock(img, img->current_mb_nr);
|
1811 |
|
|
// Get the syntax elements from the NAL
|
1812 |
|
|
read_flag = read_one_macroblock(img,inp);
|
1813 |
|
|
decode_one_macroblock(img,inp);
|
1814 |
|
|
|
1815 |
|
|
if(img->MbaffFrameFlag && dec_picture->mb_field[img->current_mb_nr])
|
1816 |
|
|
{
|
1817 |
|
|
img->num_ref_idx_l0_active >>= 1;
|
1818 |
|
|
img->num_ref_idx_l1_active >>= 1;
|
1819 |
|
|
}
|
1820 |
|
|
|
1821 |
|
|
ercWriteMBMODEandMV(img,inp);
|
1822 |
|
|
|
1823 |
|
|
end_of_slice=exit_macroblock(img,inp,(!img->MbaffFrameFlag||img->current_mb_nr%2));
|
1824 |
|
|
}
|
1825 |
|
|
|
1826 |
|
|
exit_slice();
|
1827 |
|
|
//reset_ec_flags();
|
1828 |
|
|
|
1829 |
|
|
}
|
1830 |
|
|
|
1831 |
|
|
|
1832 |
|
|
void decode_slice(struct img_par *img,struct inp_par *inp, int current_header)
|
1833 |
|
|
{
|
1834 |
|
|
Slice *currSlice = img->currentSlice;
|
1835 |
|
|
|
1836 |
|
|
if (active_pps->entropy_coding_mode_flag)
|
1837 |
|
|
{
|
1838 |
|
|
init_contexts (img);
|
1839 |
|
|
cabac_new_slice();
|
1840 |
|
|
}
|
1841 |
|
|
|
1842 |
|
|
if ( (active_pps->weighted_bipred_idc > 0 && (img->type == B_SLICE)) || (active_pps->weighted_pred_flag && img->type !=I_SLICE))
|
1843 |
|
|
fill_wp_params(img);
|
1844 |
|
|
|
1845 |
|
|
//printf("frame picture %d %d %d\n",img->structure,img->ThisPOC,img->direct_spatial_mv_pred_flag);
|
1846 |
|
|
|
1847 |
|
|
|
1848 |
|
|
// decode main slice information
|
1849 |
|
|
if ((current_header == SOP || current_header == SOS) && currSlice->ei_flag == 0)
|
1850 |
|
|
decode_one_slice(img,inp);
|
1851 |
|
|
|
1852 |
|
|
// setMB-Nr in case this slice was lost
|
1853 |
|
|
// if(currSlice->ei_flag)
|
1854 |
|
|
// img->current_mb_nr = currSlice->last_mb_nr + 1;
|
1855 |
|
|
|
1856 |
|
|
}
|
1857 |
|
|
|
1858 |
|
|
|
1859 |
|
|
/*!
|
1860 |
|
|
************************************************************************
|
1861 |
|
|
* \brief
|
1862 |
|
|
* Prepare field and frame buffer after frame decoding
|
1863 |
|
|
************************************************************************
|
1864 |
|
|
*/
|
1865 |
|
|
void frame_postprocessing(struct img_par *img, struct inp_par *inp)
|
1866 |
|
|
{
|
1867 |
|
|
}
|
1868 |
|
|
|
1869 |
|
|
/*!
|
1870 |
|
|
************************************************************************
|
1871 |
|
|
* \brief
|
1872 |
|
|
* Prepare field and frame buffer after field decoding
|
1873 |
|
|
************************************************************************
|
1874 |
|
|
*/
|
1875 |
|
|
void field_postprocessing(struct img_par *img, struct inp_par *inp)
|
1876 |
|
|
{
|
1877 |
|
|
img->number /= 2;
|
1878 |
|
|
}
|
1879 |
|
|
|
1880 |
|
|
|
1881 |
|
|
|
1882 |
|
|
void reset_wp_params(struct img_par *img)
|
1883 |
|
|
{
|
1884 |
|
|
int i,comp;
|
1885 |
|
|
int log_weight_denom;
|
1886 |
|
|
|
1887 |
|
|
for (i=0; i<MAX_REFERENCE_PICTURES; i++)
|
1888 |
|
|
{
|
1889 |
|
|
for (comp=0; comp<3; comp++)
|
1890 |
|
|
{
|
1891 |
|
|
log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
|
1892 |
|
|
img->wp_weight[0][i][comp] = 1<<log_weight_denom;
|
1893 |
|
|
img->wp_weight[1][i][comp] = 1<<log_weight_denom;
|
1894 |
|
|
}
|
1895 |
|
|
}
|
1896 |
|
|
}
|
1897 |
|
|
|
1898 |
|
|
|
1899 |
|
|
void fill_wp_params(struct img_par *img)
|
1900 |
|
|
{
|
1901 |
|
|
int i, j, k;
|
1902 |
|
|
int comp;
|
1903 |
|
|
int log_weight_denom;
|
1904 |
|
|
int tb, td;
|
1905 |
|
|
int bframe = (img->type==B_SLICE);
|
1906 |
|
|
int max_bwd_ref, max_fwd_ref;
|
1907 |
|
|
int tx,DistScaleFactor;
|
1908 |
|
|
|
1909 |
|
|
max_fwd_ref = img->num_ref_idx_l0_active;
|
1910 |
|
|
max_bwd_ref = img->num_ref_idx_l1_active;
|
1911 |
|
|
|
1912 |
|
|
if (active_pps->weighted_bipred_idc == 2 && bframe)
|
1913 |
|
|
{
|
1914 |
|
|
img->luma_log2_weight_denom = 5;
|
1915 |
|
|
img->chroma_log2_weight_denom = 5;
|
1916 |
|
|
img->wp_round_luma = 16;
|
1917 |
|
|
img->wp_round_chroma = 16;
|
1918 |
|
|
|
1919 |
|
|
for (i=0; i<MAX_REFERENCE_PICTURES; i++)
|
1920 |
|
|
{
|
1921 |
|
|
for (comp=0; comp<3; comp++)
|
1922 |
|
|
{
|
1923 |
|
|
log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
|
1924 |
|
|
img->wp_weight[0][i][comp] = 1<<log_weight_denom;
|
1925 |
|
|
img->wp_weight[1][i][comp] = 1<<log_weight_denom;
|
1926 |
|
|
img->wp_offset[0][i][comp] = 0;
|
1927 |
|
|
img->wp_offset[1][i][comp] = 0;
|
1928 |
|
|
}
|
1929 |
|
|
}
|
1930 |
|
|
}
|
1931 |
|
|
|
1932 |
|
|
if (bframe)
|
1933 |
|
|
{
|
1934 |
|
|
for (i=0; i<max_fwd_ref; i++)
|
1935 |
|
|
{
|
1936 |
|
|
for (j=0; j<max_bwd_ref; j++)
|
1937 |
|
|
{
|
1938 |
|
|
for (comp = 0; comp<3; comp++)
|
1939 |
|
|
{
|
1940 |
|
|
log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
|
1941 |
|
|
if (active_pps->weighted_bipred_idc == 1)
|
1942 |
|
|
{
|
1943 |
|
|
img->wbp_weight[0][i][j][comp] = img->wp_weight[0][i][comp];
|
1944 |
|
|
img->wbp_weight[1][i][j][comp] = img->wp_weight[1][j][comp];
|
1945 |
|
|
}
|
1946 |
|
|
else if (active_pps->weighted_bipred_idc == 2)
|
1947 |
|
|
{
|
1948 |
|
|
td = iClip3(-128,127,listX[LIST_1][j]->poc - listX[LIST_0][i]->poc);
|
1949 |
|
|
if (td == 0 || listX[LIST_1][j]->is_long_term || listX[LIST_0][i]->is_long_term)
|
1950 |
|
|
{
|
1951 |
|
|
img->wbp_weight[0][i][j][comp] = 32;
|
1952 |
|
|
img->wbp_weight[1][i][j][comp] = 32;
|
1953 |
|
|
}
|
1954 |
|
|
else
|
1955 |
|
|
{
|
1956 |
|
|
tb = iClip3(-128,127,img->ThisPOC - listX[LIST_0][i]->poc);
|
1957 |
|
|
|
1958 |
|
|
tx = (16384 + iabs(td/2))/td;
|
1959 |
|
|
DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6);
|
1960 |
|
|
|
1961 |
|
|
img->wbp_weight[1][i][j][comp] = DistScaleFactor >> 2;
|
1962 |
|
|
img->wbp_weight[0][i][j][comp] = 64 - img->wbp_weight[1][i][j][comp];
|
1963 |
|
|
if (img->wbp_weight[1][i][j][comp] < -64 || img->wbp_weight[1][i][j][comp] > 128)
|
1964 |
|
|
{
|
1965 |
|
|
img->wbp_weight[0][i][j][comp] = 32;
|
1966 |
|
|
img->wbp_weight[1][i][j][comp] = 32;
|
1967 |
|
|
img->wp_offset[0][i][comp] = 0;
|
1968 |
|
|
img->wp_offset[1][j][comp] = 0;
|
1969 |
|
|
}
|
1970 |
|
|
}
|
1971 |
|
|
}
|
1972 |
|
|
}
|
1973 |
|
|
}
|
1974 |
|
|
}
|
1975 |
|
|
}
|
1976 |
|
|
|
1977 |
|
|
if (bframe && img->MbaffFrameFlag)
|
1978 |
|
|
{
|
1979 |
|
|
for (i=0; i<2*max_fwd_ref; i++)
|
1980 |
|
|
{
|
1981 |
|
|
for (j=0; j<2*max_bwd_ref; j++)
|
1982 |
|
|
{
|
1983 |
|
|
for (comp = 0; comp<3; comp++)
|
1984 |
|
|
{
|
1985 |
|
|
for (k=2; k<6; k+=2)
|
1986 |
|
|
{
|
1987 |
|
|
img->wp_offset[k+0][i][comp] = img->wp_offset[0][i/2][comp];
|
1988 |
|
|
img->wp_offset[k+1][j][comp] = img->wp_offset[1][j/2][comp];
|
1989 |
|
|
|
1990 |
|
|
log_weight_denom = (comp == 0) ? img->luma_log2_weight_denom : img->chroma_log2_weight_denom;
|
1991 |
|
|
if (active_pps->weighted_bipred_idc == 1)
|
1992 |
|
|
{
|
1993 |
|
|
img->wbp_weight[k+0][i][j][comp] = img->wp_weight[0][i/2][comp];
|
1994 |
|
|
img->wbp_weight[k+1][i][j][comp] = img->wp_weight[1][j/2][comp];
|
1995 |
|
|
}
|
1996 |
|
|
else if (active_pps->weighted_bipred_idc == 2)
|
1997 |
|
|
{
|
1998 |
|
|
td = iClip3(-128,127,listX[k+LIST_1][j]->poc - listX[k+LIST_0][i]->poc);
|
1999 |
|
|
if (td == 0 || listX[k+LIST_1][j]->is_long_term || listX[k+LIST_0][i]->is_long_term)
|
2000 |
|
|
{
|
2001 |
|
|
img->wbp_weight[k+0][i][j][comp] = 32;
|
2002 |
|
|
img->wbp_weight[k+1][i][j][comp] = 32;
|
2003 |
|
|
}
|
2004 |
|
|
else
|
2005 |
|
|
{
|
2006 |
|
|
tb = iClip3(-128,127,((k==2)?img->toppoc:img->bottompoc) - listX[k+LIST_0][i]->poc);
|
2007 |
|
|
|
2008 |
|
|
tx = (16384 + iabs(td/2))/td;
|
2009 |
|
|
DistScaleFactor = iClip3(-1024, 1023, (tx*tb + 32 )>>6);
|
2010 |
|
|
|
2011 |
|
|
img->wbp_weight[k+1][i][j][comp] = DistScaleFactor >> 2;
|
2012 |
|
|
img->wbp_weight[k+0][i][j][comp] = 64 - img->wbp_weight[k+1][i][j][comp];
|
2013 |
|
|
if (img->wbp_weight[k+1][i][j][comp] < -64 || img->wbp_weight[k+1][i][j][comp] > 128)
|
2014 |
|
|
{
|
2015 |
|
|
img->wbp_weight[k+1][i][j][comp] = 32;
|
2016 |
|
|
img->wbp_weight[k+0][i][j][comp] = 32;
|
2017 |
|
|
img->wp_offset[k+0][i][comp] = 0;
|
2018 |
|
|
img->wp_offset[k+1][j][comp] = 0;
|
2019 |
|
|
}
|
2020 |
|
|
}
|
2021 |
|
|
}
|
2022 |
|
|
}
|
2023 |
|
|
}
|
2024 |
|
|
}
|
2025 |
|
|
}
|
2026 |
|
|
}
|
2027 |
|
|
}
|
2028 |
|
|
|
2029 |
|
|
/*!
|
2030 |
|
|
************************************************************************
|
2031 |
|
|
* \brief
|
2032 |
|
|
* Error tracking: if current frame is lost or any reference frame of
|
2033 |
|
|
* current frame is lost, current frame is incorrect.
|
2034 |
|
|
************************************************************************
|
2035 |
|
|
*/
|
2036 |
|
|
void Error_tracking()
|
2037 |
|
|
{
|
2038 |
|
|
int i;
|
2039 |
|
|
|
2040 |
|
|
if(img->redundant_pic_cnt == 0)
|
2041 |
|
|
{
|
2042 |
|
|
Is_primary_correct = Is_redundant_correct = 1;
|
2043 |
|
|
}
|
2044 |
|
|
|
2045 |
|
|
if(img->redundant_pic_cnt == 0 && img->type != I_SLICE)
|
2046 |
|
|
{
|
2047 |
|
|
for(i=0;i<img->num_ref_idx_l0_active;i++)
|
2048 |
|
|
{
|
2049 |
|
|
if(ref_flag[i] == 0) // any reference of primary slice is incorrect
|
2050 |
|
|
{
|
2051 |
|
|
Is_primary_correct = 0; // primary slice is incorrect
|
2052 |
|
|
}
|
2053 |
|
|
}
|
2054 |
|
|
}
|
2055 |
|
|
else if(img->redundant_pic_cnt != 0 && img->type != I_SLICE)
|
2056 |
|
|
{
|
2057 |
|
|
if(ref_flag[redundant_slice_ref_idx] == 0) // reference of redundant slice is incorrect
|
2058 |
|
|
{
|
2059 |
|
|
Is_redundant_correct = 0; // redundant slice is incorrect
|
2060 |
|
|
}
|
2061 |
|
|
}
|
2062 |
|
|
}
|