Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : /***************************************
7 : * Includes
8 : ***************************************/
9 : #include <stdio.h>
10 : #include <stdlib.h>
11 : #include <string.h>
12 : #include <math.h>
13 : #include "EbAppContext.h"
14 : #include "EbAppConfig.h"
15 : #include "EbSvtAv1ErrorCodes.h"
16 : #include "EbAppInputy4m.h"
17 :
18 : #include "EbTime.h"
19 :
20 : #define IVF_FRAME_HEADER_IN_LIB 0
21 :
22 : /***************************************
23 : * Macros
24 : ***************************************/
25 : #define CLIP3(min_val, max_val, a) (((a)<(min_val)) ? (min_val) : (((a)>(max_val)) ? (max_val) :(a)))
26 : #define FUTURE_WINDOW_WIDTH 4
27 : #define SIZE_OF_ONE_FRAME_IN_BYTES(width, height, csp, is16bit) \
28 : ( (((width)*(height)) + 2*(((width)*(height))>>(3-csp)))<<is16bit)
29 : #define YUV4MPEG2_IND_SIZE 9
30 : extern volatile int32_t keepRunning;
31 :
32 : /***************************************
33 : * Process Error Log
34 : ***************************************/
35 0 : void LogErrorOutput(
36 : FILE *error_log_file,
37 : uint32_t error_code)
38 : {
39 0 : switch (error_code) {
40 : // EB_ENC_AMVP_ERRORS:
41 0 : case EB_ENC_AMVP_ERROR1:
42 0 : fprintf(error_log_file, "Error: The input PU to GetNonScalingSpatialAMVP() can not be I_MODE!\n");
43 0 : break;
44 :
45 0 : case EB_ENC_AMVP_ERROR2:
46 0 : fprintf(error_log_file, "Error: The input PU to GetNonScalingSpatialAMVP() must be available!\n");
47 0 : break;
48 :
49 0 : case EB_ENC_AMVP_ERROR3:
50 0 : fprintf(error_log_file, "Error: The input PU to GetNonScalingSpatialAMVP() can not be I_MODE!\n");
51 0 : break;
52 :
53 0 : case EB_ENC_AMVP_ERROR4:
54 0 : fprintf(error_log_file, "Error: The availability parameter in GetSpatialMVPPosAx() function can not be > 3 !\n");
55 0 : break;
56 :
57 0 : case EB_ENC_AMVP_ERROR5:
58 0 : fprintf(error_log_file, "Error: The availability parameter in GetSpatialMVPPosBx() function can not be > 7 !\n");
59 0 : break;
60 :
61 0 : case EB_ENC_AMVP_NULL_REF_ERROR:
62 0 : fprintf(error_log_file, "Error: The referenceObject can not be NULL!\n");
63 0 : break;
64 :
65 0 : case EB_ENC_AMVP_SPATIAL_NA_ERROR:
66 0 : fprintf(error_log_file, "Error: The input PU to GetNonScalingSpatialAMVP() must be available!\n");
67 0 : break;
68 :
69 : // EB_ENC_CL_ERRORS:
70 0 : case EB_ENC_CL_ERROR1:
71 0 : fprintf(error_log_file, "Error: Unknown Inter Prediction Direction!\n");
72 0 : break;
73 :
74 0 : case EB_ENC_CL_ERROR2:
75 0 : fprintf(error_log_file, "Error: Unknown coding mode!\n");
76 0 : break;
77 :
78 0 : case EB_ENC_CL_ERROR3:
79 0 : fprintf(error_log_file, "Error: Mode Decision Candidate Buffer Overflow!\n");
80 0 : break;
81 :
82 0 : case EB_ENC_CL_ERROR4:
83 0 : fprintf(error_log_file, "Error: Too many Mode Decision Fast Candidates!\n");
84 0 : break;
85 :
86 0 : case EB_ENC_CL_ERROR5:
87 0 : fprintf(error_log_file, "Error: Too many buffers chosen for this level by PreModeDecision!\n");
88 0 : break;
89 :
90 0 : case EB_ENC_CL_ERROR6:
91 0 : fprintf(error_log_file, "Error: Ping-Pong structure needs at least two buffers to work properly!\n");
92 0 : break;
93 :
94 0 : case EB_ENC_CL_ERROR7:
95 0 : fprintf(error_log_file, "Error: Invalid Intra Partition\n");
96 0 : break;
97 :
98 0 : case EB_ENC_CL_ERROR8:
99 0 : fprintf(error_log_file, "Error: Invalid TU Configuration\n");
100 0 : break;
101 0 : case EB_ENC_CL_ERROR9:
102 0 : fprintf(error_log_file, "Error: Invalid Prediction Mode\n");
103 0 : break;
104 :
105 : // EB_ENC_DLF_ERRORS:
106 0 : case EB_ENC_DLF_ERROR1:
107 0 : fprintf(error_log_file, "Error: While calculating bS for DLF!\n");
108 0 : break;
109 :
110 0 : case EB_ENC_DLF_ERROR2:
111 0 : fprintf(error_log_file, "Error: Unknown Inter Prediction Direction Combination!\n");
112 0 : break;
113 :
114 0 : case EB_ENC_DLF_ERROR3:
115 0 : fprintf(error_log_file, "Error: If any PU is in I_MODE, the bS will be 2!\n");
116 0 : break;
117 :
118 0 : case EB_ENC_DLF_ERROR4:
119 0 : fprintf(error_log_file, "Error: The x/y location of the CU must be the multiple of minmum CU size!");
120 0 : break;
121 :
122 0 : case EB_ENC_DLF_ERROR5:
123 0 : fprintf(error_log_file, "Error: Unknown Slice Type!");
124 0 : break;
125 :
126 0 : case EB_ENC_DLF_ERROR6:
127 0 : fprintf(error_log_file, "Error: While calculating the bS for the PU bounday, the 4x4 block must be guaranteed at the PU boundary!");
128 0 : break;
129 :
130 0 : case EB_ENC_DLF_ERROR7:
131 0 : fprintf(error_log_file, "Error: LCU size must be power of 2!");
132 0 : break;
133 :
134 0 : case EB_ENC_DLF_ERROR8:
135 0 : fprintf(error_log_file, "Error: Deblocking filter can not support the picture whose width or height is not the multiple of 8!");
136 0 : break;
137 :
138 0 : case EB_ENC_DLF_ERROR9:
139 0 : fprintf(error_log_file, "Error: Neighbor PU must be available!");
140 0 : break;
141 :
142 0 : case EB_ENC_DLF_ERROR10:
143 0 : fprintf(error_log_file, "Error: Deblocking filter can not support the picture whose width or height is not the multiple of 8!");
144 0 : break;
145 :
146 : // EB_ENC_EC_ERRORS:
147 0 : case EB_ENC_EC_ERROR1:
148 0 : fprintf(error_log_file, "Error: EncodeCodedBlockFlags: context value too large!\n");
149 0 : break;
150 :
151 0 : case EB_ENC_EC_ERROR10:
152 0 : fprintf(error_log_file, "Error: EncodeTuSplitCoeff: context value too large!\n");
153 0 : break;
154 :
155 0 : case EB_ENC_EC_ERROR11:
156 0 : fprintf(error_log_file, "Error: CodeSPS: Long term reference pictures are not currently handled!\n");
157 0 : break;
158 :
159 0 : case EB_ENC_EC_ERROR12:
160 0 : fprintf(error_log_file, "Error: CodeProfileTierLevel: The maximum sublayers must be equal to 1!\n");
161 0 : break;
162 :
163 0 : case EB_ENC_EC_ERROR13:
164 0 : fprintf(error_log_file, "Error: EncodeRootCodedBlockFlag: rootCbf too large!\n");
165 0 : break;
166 :
167 0 : case EB_ENC_EC_ERROR14:
168 0 : fprintf(error_log_file, "Error: cpbCountMinus1 in HRD parameter exceeds the upper limit 4!\n");
169 0 : break;
170 :
171 0 : case EB_ENC_EC_ERROR15:
172 0 : fprintf(error_log_file, "Error: numDecodingUnitsMinus1 in picture timeing SEI exceeds the upper limit 64!\n");
173 0 : break;
174 :
175 0 : case EB_ENC_EC_ERROR16:
176 0 : fprintf(error_log_file, "Error: The size of the unregistered user data SEI payload is not allowed!\n");
177 0 : break;
178 :
179 0 : case EB_ENC_EC_ERROR2:
180 0 : fprintf(error_log_file, "Error: copy_rbsp_bitstream_to_payload: output buffer too small!\n");
181 0 : break;
182 :
183 0 : case EB_ENC_EC_ERROR3:
184 0 : fprintf(error_log_file, "Error: EncodeLcu: Unknown mode type!\n");
185 0 : break;
186 :
187 0 : case EB_ENC_EC_ERROR4:
188 0 : fprintf(error_log_file, "Error: 8x4 & 4x8 PU should not have Bi-pred mode!\n");
189 0 : break;
190 :
191 0 : case EB_ENC_EC_ERROR5:
192 0 : fprintf(error_log_file, "Error: EncodeMergeIndex: value too large!\n");
193 0 : break;
194 :
195 0 : case EB_ENC_EC_ERROR6:
196 0 : fprintf(error_log_file, "Error: EncodeSkipFlag: context too large!\n");
197 0 : break;
198 :
199 0 : case EB_ENC_EC_ERROR7:
200 0 : fprintf(error_log_file, "Error: EncodeBypassBins: binsLength must be less than 32!\n");
201 0 : break;
202 :
203 0 : case EB_ENC_EC_ERROR8:
204 0 : fprintf(error_log_file, "Error: EncodeQuantizedCoefficients: Invalid block size!\n");
205 0 : break;
206 :
207 0 : case EB_ENC_EC_ERROR9:
208 0 : fprintf(error_log_file, "Error: EncodeSplitFlag: context too large!\n");
209 0 : break;
210 :
211 0 : case EB_ENC_EC_ERROR26:
212 0 : fprintf(error_log_file, "Error: Level not recognized!\n");
213 0 : break;
214 :
215 0 : case EB_ENC_EC_ERROR27:
216 0 : fprintf(error_log_file, "Error: EncodeOneBin: BinaryValue must be less than 2\n");
217 0 : break;
218 :
219 0 : case EB_ENC_EC_ERROR28:
220 0 : fprintf(error_log_file, "Error: No more than 6 SAO types\n");
221 0 : break;
222 :
223 0 : case EB_ENC_EC_ERROR29:
224 0 : fprintf(error_log_file, "Error: No more than 6 SAO types\n");
225 0 : break;
226 :
227 : // EB_ENC_FL_ERRORS:
228 0 : case EB_ENC_FL_ERROR1:
229 0 : fprintf(error_log_file, "Error: Uncovered area inside Cu!\n");
230 0 : break;
231 :
232 0 : case EB_ENC_FL_ERROR2:
233 0 : fprintf(error_log_file, "Error: Depth 2 is not allowed for 8x8 CU!\n");
234 0 : break;
235 :
236 0 : case EB_ENC_FL_ERROR3:
237 0 : fprintf(error_log_file, "Error: Depth 0 is not allowed for 64x64 CU!\n");
238 0 : break;
239 :
240 0 : case EB_ENC_FL_ERROR4:
241 0 : fprintf(error_log_file, "Error: Max CU Depth Exceeded!\n");
242 0 : break;
243 :
244 : // EB_ENC_HANDLE_ERRORS:
245 0 : case EB_ENC_HANDLE_ERROR1:
246 0 : fprintf(error_log_file, "Error: Only one Resource Coordination Process allowed!\n");
247 0 : break;
248 :
249 0 : case EB_ENC_HANDLE_ERROR10:
250 0 : fprintf(error_log_file, "Error: Need at least one Entropy Coding Process!\n");
251 0 : break;
252 :
253 0 : case EB_ENC_HANDLE_ERROR11:
254 0 : fprintf(error_log_file, "Error: Only one Packetization Process allowed!\n");
255 0 : break;
256 :
257 0 : case EB_ENC_HANDLE_ERROR12:
258 0 : fprintf(error_log_file, "Error: RC Results Fifo Size should be greater than RC Tasks Fifo Size in order to avoid deadlock!\n");
259 0 : break;
260 :
261 0 : case EB_ENC_HANDLE_ERROR13:
262 0 : fprintf(error_log_file, "Error: RC Tasks Fifo Size should be greater than EC results Fifo Size in order to avoid deadlock!\n");
263 0 : break;
264 :
265 0 : case EB_ENC_HANDLE_ERROR14:
266 0 : fprintf(error_log_file, "Error: RC Tasks Fifo Size should be greater than Picture Manager results Fifo Size in order to avoid deadlock!\n");
267 0 : break;
268 :
269 0 : case EB_ENC_HANDLE_ERROR18:
270 0 : fprintf(error_log_file, "Error: Intra period setting breaks mini-gop!\n");
271 0 : break;
272 :
273 0 : case EB_ENC_HANDLE_ERROR2:
274 0 : fprintf(error_log_file, "Error: Only one Picture Enhancement Process allowed!\n");
275 0 : break;
276 :
277 0 : case EB_ENC_HANDLE_ERROR3:
278 0 : fprintf(error_log_file, "Error: Only one Picture Manager Process allowed!\n");
279 0 : break;
280 :
281 0 : case EB_ENC_HANDLE_ERROR4:
282 0 : fprintf(error_log_file, "Error: Need at least one ME Process!\n");
283 0 : break;
284 :
285 0 : case EB_ENC_HANDLE_ERROR5:
286 0 : fprintf(error_log_file, "Error: Only one Rate-Control Process allowed!\n");
287 0 : break;
288 :
289 0 : case EB_ENC_HANDLE_ERROR6:
290 0 : fprintf(error_log_file, "Error: Need at least one Mode Decision Configuration Process!\n");
291 0 : break;
292 :
293 0 : case EB_ENC_HANDLE_ERROR7:
294 0 : fprintf(error_log_file, "Error: Need at least one Coding Loop Process!\n");
295 0 : break;
296 :
297 0 : case EB_ENC_HANDLE_ERROR8:
298 0 : fprintf(error_log_file, "Error: Only one Second Pass Deblocking Process allowed!\n");
299 0 : break;
300 :
301 0 : case EB_ENC_HANDLE_ERROR9:
302 0 : fprintf(error_log_file, "Error: Only one ALF Process allowed!\n");
303 0 : break;
304 :
305 : // EB_ENC_INTER_ERRORS:
306 0 : case EB_ENC_INTER_INVLD_MCP_ERROR:
307 0 : fprintf(error_log_file, "Error: Motion compensation prediction is out of the picture boundary!\n");
308 0 : break;
309 :
310 0 : case EB_ENC_INTER_PRED_ERROR0:
311 0 : fprintf(error_log_file, "Error: Unkown Inter Prediction Direction!\n");
312 0 : break;
313 :
314 0 : case EB_ENC_INTER_PRED_ERROR1:
315 0 : fprintf(error_log_file, "Error: Inter prediction can not support more than 2 MVPs!\n");
316 0 : break;
317 :
318 : // EB_ENC_INTRA_ERRORS:
319 0 : case EB_ENC_INTRA_PRED_ERROR1:
320 0 : fprintf(error_log_file, "Error: IntraPrediction does not support 2Nx2N partition size!\n");
321 0 : break;
322 :
323 0 : case EB_ENC_INTRA_PRED_ERROR2:
324 0 : fprintf(error_log_file, "Error: IntraPrediction: intra prediction only supports square PU!\n");
325 0 : break;
326 :
327 0 : case EB_ENC_INTRA_PRED_ERROR3:
328 0 : fprintf(error_log_file, "Error: IntraPredictionChroma: Only Planar!\n");
329 0 : break;
330 :
331 0 : case EB_ENC_INVLD_PART_SIZE_ERROR:
332 0 : fprintf(error_log_file, "Error: IntraPrediction: only PU sizes of 8 or largers are currently supported!\n");
333 0 : break;
334 :
335 : // EB_ENC_MD_ERRORS:
336 0 : case EB_ENC_MD_ERROR1:
337 0 : fprintf(error_log_file, "Error: Unknown AMVP Mode Decision Candidate Type!\n");
338 0 : break;
339 :
340 0 : case EB_ENC_MD_ERROR2:
341 0 : fprintf(error_log_file, "Error: PreModeDecision: need at least one buffer!\n");
342 0 : break;
343 :
344 0 : case EB_ENC_MD_ERROR3:
345 0 : fprintf(error_log_file, "Error: Unknow Inter Prediction Direction!\n");
346 0 : break;
347 :
348 0 : case EB_ENC_MD_ERROR4:
349 0 : fprintf(error_log_file, "Error: Unknown ME SAD Level!\n");
350 0 : break;
351 :
352 0 : case EB_ENC_MD_ERROR5:
353 0 : fprintf(error_log_file, "Error: Invalid encoder mode. The encoder mode should be 0, 1 or 2!\n");
354 0 : break;
355 :
356 0 : case EB_ENC_MD_ERROR6:
357 0 : fprintf(error_log_file, "Error: Invalid TU size!\n");
358 0 : break;
359 :
360 0 : case EB_ENC_MD_ERROR7:
361 0 : fprintf(error_log_file, "Error: Unknown depth!\n");
362 0 : break;
363 :
364 0 : case EB_ENC_MD_ERROR8:
365 0 : fprintf(error_log_file, "Error: Depth not supported!\n");
366 0 : break;
367 :
368 0 : case EB_ENC_MD_ERROR9:
369 0 : fprintf(error_log_file, "Error: Ping-Pong structure needs at least two buffers to work properly\n");
370 0 : break;
371 :
372 0 : case EB_ENC_MD_ERROR10:
373 0 : fprintf(error_log_file, "Error: Ping-Pong structure needs at least two buffers to work properly\n");
374 0 : break;
375 :
376 : // EB_ENC_ME_ERRORS:
377 0 : case EB_ENC_ME_ERROR1:
378 0 : fprintf(error_log_file, "Error: Motion Estimation: non valid value of the subPelDirection !\n");
379 0 : break;
380 :
381 0 : case EB_ENC_ME_ERROR2:
382 0 : fprintf(error_log_file, "Error: FillMvMergeCandidate() method only supports P or B slices!\n");
383 0 : break;
384 :
385 : // EB_ENC_ERRORS:
386 0 : case EB_ENC_ROB_OF_ERROR:
387 0 : fprintf(error_log_file, "Error: Recon Output Buffer Overflow!\n");
388 0 : break;
389 :
390 : // EB_ENC_PACKETIZATION_ERRORS:
391 0 : case EB_ENC_PACKETIZATION_ERROR1:
392 0 : fprintf(error_log_file, "Error: PacketizationProcess: Picture Number does not match entry. PacketizationReorderQueue overflow!\n");
393 0 : break;
394 :
395 0 : case EB_ENC_PACKETIZATION_ERROR2:
396 0 : fprintf(error_log_file, "Error: Entropy Coding Result can not be outputed by processes other than entropy coder and ALF!\n");
397 0 : break;
398 :
399 0 : case EB_ENC_PACKETIZATION_ERROR3:
400 0 : fprintf(error_log_file, "Error: The encoder can not support the SliceMode other than 0 and 1!\n");
401 0 : break;
402 :
403 0 : case EB_ENC_PACKETIZATION_ERROR4:
404 0 : fprintf(error_log_file, "Error: Statistics Output Buffer Overflow!\n");
405 0 : break;
406 0 : case EB_ENC_PACKETIZATION_ERROR5:
407 0 : fprintf(error_log_file, "Error: Stream Fifo is starving..deadlock, increase EB_outputStreamBufferFifoInitCount APP_ENCODERSTREAMBUFFERCOUNT \n");
408 0 : break;
409 :
410 : // EB_ENC_PM_ERRORS:
411 0 : case EB_ENC_PM_ERROR0:
412 0 : fprintf(error_log_file, "Error: PictureManagerProcess: Unknown Slice Type!\n");
413 0 : break;
414 :
415 0 : case EB_ENC_PM_ERROR1:
416 0 : fprintf(error_log_file, "Error: EbPictureManager: dependent_count underflow!\n");
417 0 : break;
418 :
419 0 : case EB_ENC_PM_ERROR10:
420 0 : fprintf(error_log_file, "Error: picture_manager_kernel: referenceEntryPtr should never be null!\n");
421 0 : break;
422 :
423 0 : case EB_ENC_PM_ERROR2:
424 0 : fprintf(error_log_file, "Error: PictureManagerProcess: The Reference Structure period must be less than the MAX_ELAPSED_IDR_COUNT or false-IDR boundary logic will be activated!\n");
425 0 : break;
426 :
427 0 : case EB_ENC_PM_ERROR3:
428 0 : fprintf(error_log_file, "Error: PictureManagerProcess: The dependent_count underflow detected!\n");
429 0 : break;
430 :
431 0 : case EB_ENC_PM_ERROR4:
432 0 : fprintf(error_log_file, "Error: PictureManagerProcess: Empty input queue!\n");
433 0 : break;
434 :
435 0 : case EB_ENC_PM_ERROR5:
436 0 : fprintf(error_log_file, "Error: PictureManagerProcess: Empty reference queue!\n");
437 0 : break;
438 :
439 0 : case EB_ENC_PM_ERROR6:
440 0 : fprintf(error_log_file, "Error: PictureManagerProcess: The capped elaspedNonIdrCount must be larger than the maximum supported delta ref poc!\n");
441 0 : break;
442 :
443 0 : case EB_ENC_PM_ERROR7:
444 0 : fprintf(error_log_file, "Error: PictureManagerProcess: Reference Picture Queue Full!\n");
445 0 : break;
446 :
447 0 : case EB_ENC_PM_ERROR8:
448 0 : fprintf(error_log_file, "Error: PictureManagerProcess: No reference match found - this will lead to a memory leak!\n");
449 0 : break;
450 :
451 0 : case EB_ENC_PM_ERROR9:
452 0 : fprintf(error_log_file, "Error: PictureManagerProcess: Unknown picture type!\n");
453 0 : break;
454 :
455 0 : case EB_ENC_PM_ERROR12:
456 0 : fprintf(error_log_file, "Error: PictureManagerProcess: prediction structure configuration API has too many reference pictures\n");
457 0 : break;
458 :
459 0 : case EB_ENC_PM_ERROR13:
460 0 : fprintf(error_log_file, "Error: PictureManagerProcess: The maximum allowed frame rate is 60 fps\n");
461 0 : break;
462 :
463 0 : case EB_ENC_PM_ERROR14:
464 0 : fprintf(error_log_file, "Error: PictureManagerProcess: The minimum allowed frame rate is 1 fps\n");
465 0 : break;
466 :
467 : // EB_ENC_PRED_STRC_ERRORS:
468 0 : case EB_ENC_PRED_STRC_ERROR1:
469 0 : fprintf(error_log_file, "Error: PredictionStructureCtor: DecodeOrder LUT too small!\n");
470 0 : break;
471 :
472 0 : case EB_ENC_PRED_STRC_ERROR2:
473 0 : fprintf(error_log_file, "Error: PredictionStructureCtor: prediction structure improperly configured!\n");
474 0 : break;
475 :
476 : // EB_ENC_PU_ERRORS:
477 0 : case EB_ENC_PU_ERROR1:
478 0 : fprintf(error_log_file, "Error: Unknown partition size!\n");
479 0 : break;
480 :
481 0 : case EB_ENC_PU_ERROR2:
482 0 : fprintf(error_log_file, "Error: The target area is not inside the CU!\n");
483 0 : break;
484 :
485 : // EB_ENC_RC_ERRORS:
486 0 : case EB_ENC_RC_ERROR1:
487 0 : fprintf(error_log_file, "Error: RateControlProcess: Unknown input task_type!\n");
488 0 : break;
489 :
490 0 : case EB_ENC_RC_ERROR2:
491 0 : fprintf(error_log_file, "Error: RateControlProcess: No RC interval found!\n");
492 0 : break;
493 :
494 0 : case EB_ENC_RC_ERROR3:
495 0 : fprintf(error_log_file, "Error: RateControlProcess: RC input Picture Queue Full!\n");
496 0 : break;
497 :
498 0 : case EB_ENC_RC_ERROR4:
499 0 : fprintf(error_log_file, "Error: RateControlProcess: RC feedback Picture Queue Full!\n");
500 0 : break;
501 :
502 0 : case EB_ENC_RC_ERROR5:
503 0 : fprintf(error_log_file, "Error: RateControlProcess: RC feedback Picture Queue Full!\n");
504 0 : break;
505 :
506 0 : case EB_ENC_RC_ERROR6:
507 0 : fprintf(error_log_file, "Error: RateControlProcess: No feedback frame match found - this will lead to a memory leak!\n");
508 0 : break;
509 :
510 0 : case EB_ENC_RC_ERROR7:
511 0 : fprintf(error_log_file, "Error: remainingBytes has to be multiple of 2 for 16 bit input\n");
512 0 : break;
513 :
514 0 : case EB_ENC_RC_ERROR8:
515 0 : fprintf(error_log_file, "Error: hlRateControlHistorgramQueue Overflow\n");
516 0 : break;
517 :
518 : // EB_ENC_RD_COST_ERRORS:
519 0 : case EB_ENC_RD_COST_ERROR1:
520 0 : fprintf(error_log_file, "Error: Skip mode only exists in 2Nx2N partition type!\n");
521 0 : break;
522 :
523 0 : case EB_ENC_RD_COST_ERROR2:
524 0 : fprintf(error_log_file, "Error: IntraChromaCost: Unknown slice type!\n");
525 0 : break;
526 :
527 0 : case EB_ENC_RD_COST_ERROR3:
528 0 : fprintf(error_log_file, "Error: intra2_nx2_n_fast_cost_islice can only support 2Nx2N partition type!\n");
529 0 : break;
530 :
531 : // EB_ENC_SAO_ERRORS:
532 0 : case EB_ENC_SAO_ERROR1:
533 0 : fprintf(error_log_file, "Error: No more than 6 SAO types!\n");
534 0 : break;
535 :
536 0 : case EB_ENC_SAO_ERROR2:
537 0 : fprintf(error_log_file, "Error: No more than 5 EO SAO categories!\n");
538 0 : break;
539 : // EB_ENC_SCS_ERRORS:
540 0 : case EB_ENC_SCS_ERROR1:
541 0 : fprintf(error_log_file, "Error: SequenceControlSetCopy: Not all SequenceControlSet members are being copied!\n");
542 0 : break;
543 :
544 : // EB_ENC_BITSTREAM_ERRORS:
545 0 : case EB_ENC_BITSTREAM_ERROR1:
546 0 : fprintf(error_log_file, "Error: OutputBitstreamRBSPToPayload: Bitstream payload buffer empty!\n");
547 0 : break;
548 :
549 0 : case EB_ENC_BITSTREAM_ERROR2:
550 0 : fprintf(error_log_file, "Error: OutputBitstreamWrite: Empty bitstream!\n");
551 0 : break;
552 :
553 0 : case EB_ENC_BITSTREAM_ERROR3:
554 0 : fprintf(error_log_file, "Error: OutputBitstreamRBSPToPayload: Buffer index more than buffer size!\n");
555 0 : break;
556 :
557 0 : case EB_ENC_BITSTREAM_ERROR4:
558 0 : fprintf(error_log_file, "Error: OutputBitstreamRBSPToPayload: Start Location in not inside the buffer!\n");
559 0 : break;
560 :
561 0 : case EB_ENC_BITSTREAM_ERROR5:
562 0 : fprintf(error_log_file, "Error: OutputBitstreamWrite: Trying to write more than one word!\n");
563 0 : break;
564 :
565 0 : case EB_ENC_BITSTREAM_ERROR6:
566 0 : fprintf(error_log_file, "Error: OutputBitstreamRBSPToPayload: Expecting Start code!\n");
567 0 : break;
568 :
569 0 : case EB_ENC_BITSTREAM_ERROR7:
570 0 : fprintf(error_log_file, "Error: OutputBitstreamRBSPToPayload: Bitstream not flushed (i.e. byte-aligned)!\n");
571 0 : break;
572 :
573 0 : case EB_ENC_RESS_COOR_ERRORS1:
574 0 : fprintf(error_log_file, "Error: ResourceCoordinationProcess: The received input data should be equal to the buffer size - only complete frame transfer is supported\n");
575 0 : break;
576 :
577 0 : case EB_ENC_RES_COORD_InvalidQP:
578 0 : fprintf(error_log_file, "Error: ResourceCoordinationProcess: The QP value in the QP file is invalid\n");
579 0 : break;
580 :
581 0 : case EB_ENC_RES_COORD_InvalidSliceType:
582 0 : fprintf(error_log_file, "Error: ResourceCoordinationProcess: Slice Type Invalid\n");
583 0 : break;
584 :
585 : // picture decision Errors
586 0 : case EB_ENC_PD_ERROR8:
587 0 : fprintf(error_log_file, "Error: PictureDecisionProcess: Picture Decision Reorder Queue overflow\n");
588 0 : break;
589 :
590 0 : default:
591 0 : fprintf(error_log_file, "Error: Others!\n");
592 0 : break;
593 : }
594 :
595 0 : return;
596 : }
597 :
598 : /******************************************************
599 : * Copy fields from the stream to the input buffer
600 : Input : stream
601 : Output : valid input buffer
602 : ******************************************************/
603 0 : void ProcessInputFieldStandardMode(
604 : EbConfig *config,
605 : EbBufferHeaderType *headerPtr,
606 : FILE *input_file,
607 : uint8_t *lumaInputPtr,
608 : uint8_t *cbInputPtr,
609 : uint8_t *crInputPtr,
610 : uint8_t is16bit) {
611 0 : const int64_t input_padded_width = config->input_padded_width;
612 0 : const int64_t input_padded_height = config->input_padded_height;
613 0 : const uint8_t color_format = config->encoder_color_format;
614 0 : const uint8_t subsampling_x = (color_format == EB_YUV444 ? 1 : 2) - 1;
615 0 : const uint8_t subsampling_y = (color_format >= EB_YUV422 ? 1 : 2) - 1;
616 0 : const uint64_t source_luma_row_size = (uint64_t)(input_padded_width << is16bit);
617 0 : const uint64_t source_chroma_row_size = source_luma_row_size >> subsampling_x;
618 : uint8_t *ebInputPtr;
619 : uint32_t inputRowIndex;
620 :
621 : // Y
622 0 : ebInputPtr = lumaInputPtr;
623 : // Skip 1 luma row if bottom field (point to the bottom field)
624 0 : if (config->processed_frame_count % 2 != 0)
625 0 : fseeko(input_file, (long)source_luma_row_size, SEEK_CUR);
626 :
627 0 : for (inputRowIndex = 0; inputRowIndex < input_padded_height; inputRowIndex++) {
628 0 : headerPtr->n_filled_len += (uint32_t)fread(ebInputPtr, 1, source_luma_row_size, input_file);
629 : // Skip 1 luma row (only fields)
630 0 : fseeko(input_file, (long)source_luma_row_size, SEEK_CUR);
631 0 : ebInputPtr += source_luma_row_size;
632 : }
633 :
634 : // U
635 0 : ebInputPtr = cbInputPtr;
636 : // Step back 1 luma row if bottom field (undo the previous jump), and skip 1 chroma row if bottom field (point to the bottom field)
637 0 : if (config->processed_frame_count % 2 != 0) {
638 0 : fseeko(input_file, -(long)source_luma_row_size, SEEK_CUR);
639 0 : fseeko(input_file, (long)source_chroma_row_size, SEEK_CUR);
640 : }
641 :
642 0 : for (inputRowIndex = 0; inputRowIndex < input_padded_height >> subsampling_y; inputRowIndex++) {
643 0 : headerPtr->n_filled_len += (uint32_t)fread(ebInputPtr, 1, source_chroma_row_size, input_file);
644 : // Skip 1 chroma row (only fields)
645 0 : fseeko(input_file, (long)source_chroma_row_size, SEEK_CUR);
646 0 : ebInputPtr += source_chroma_row_size;
647 : }
648 :
649 : // V
650 0 : ebInputPtr = crInputPtr;
651 : // Step back 1 chroma row if bottom field (undo the previous jump), and skip 1 chroma row if bottom field (point to the bottom field)
652 : // => no action
653 :
654 0 : for (inputRowIndex = 0; inputRowIndex < input_padded_height >> subsampling_y; inputRowIndex++) {
655 0 : headerPtr->n_filled_len += (uint32_t)fread(ebInputPtr, 1, source_chroma_row_size, input_file);
656 : // Skip 1 chroma row (only fields)
657 0 : fseeko(input_file, (long)source_chroma_row_size, SEEK_CUR);
658 0 : ebInputPtr += source_chroma_row_size;
659 : }
660 :
661 : // Step back 1 chroma row if bottom field (undo the previous jump)
662 0 : if (config->processed_frame_count % 2 != 0)
663 0 : fseeko(input_file, -(long)source_chroma_row_size, SEEK_CUR);
664 0 : }
665 :
666 : //************************************/
667 : // GetNextQpFromQpFile
668 : // Reads and extracts one qp from the qp_file
669 : // Input : QP file
670 : // Output : QP value
671 : /************************************/
672 : static int32_t qpReadFromFile = 0;
673 :
674 0 : int32_t GetNextQpFromQpFile(
675 : EbConfig *config
676 : )
677 : {
678 : uint8_t *line;
679 0 : int32_t qp = 0;
680 0 : uint32_t readsize = 0, eof = 0;
681 0 : EB_APP_MALLOC(uint8_t*, line, 8, EB_N_PTR, EB_ErrorInsufficientResources);
682 0 : memset(line,0,8);
683 0 : readsize = (uint32_t)fread(line, 1, 2, config->qp_file);
684 :
685 0 : if (readsize == 0) {
686 : // end of file
687 0 : return -1;
688 : }
689 0 : else if (readsize == 1) {
690 0 : qp = strtol((const char*)line, NULL, 0);
691 0 : if (qp == 0) // eof
692 0 : qp = -1;
693 : }
694 0 : else if (readsize == 2 && (line[0] == '\n')) {
695 : // new line
696 0 : fseek(config->qp_file, -1, SEEK_CUR);
697 0 : qp = 0;
698 : }
699 0 : else if (readsize == 2 && (line[1] == '\n')) {
700 : // new line
701 0 : qp = strtol((const char*)line, NULL, 0);
702 : }
703 0 : else if (readsize == 2 && (line[0] == '#' || line[0] == '/' || line[0] == '-' || line[0] == ' ')) {
704 : // Backup one step to not miss the new line char
705 0 : fseek(config->qp_file, -1, SEEK_CUR);
706 : do {
707 0 : readsize = (uint32_t)fread(line, 1, 1, config->qp_file);
708 0 : if (readsize != 1)
709 0 : break;
710 0 : } while (line[0] != '\n');
711 :
712 0 : if (eof != 0)
713 : // end of file
714 0 : qp = -1;
715 : else
716 : // skip line
717 0 : qp = 0;
718 : }
719 0 : else if (readsize == 2) {
720 0 : qp = strtol((const char*)line, NULL, 0);
721 : do {
722 0 : readsize = (uint32_t)fread(line, 1, 1, config->qp_file);
723 0 : if (readsize != 1)
724 0 : break;
725 0 : } while (line[0] != '\n');
726 : }
727 :
728 0 : if (qp > 0)
729 0 : qpReadFromFile |= 1;
730 :
731 0 : return qp;
732 : }
733 :
734 120 : void ReadInputFrames(
735 : EbConfig *config,
736 : uint8_t is16bit,
737 : EbBufferHeaderType *headerPtr)
738 : {
739 : uint64_t readSize;
740 120 : const uint32_t input_padded_width = config->input_padded_width;
741 120 : const uint32_t input_padded_height = config->input_padded_height;
742 120 : FILE *input_file = config->input_file;
743 : uint8_t *ebInputPtr;
744 120 : EbSvtIOFormat* inputPtr = (EbSvtIOFormat*)headerPtr->p_buffer;
745 :
746 120 : const uint8_t color_format = config->encoder_color_format;
747 120 : const uint8_t subsampling_x = (color_format == EB_YUV444 ? 1 : 2) - 1;
748 :
749 120 : inputPtr->y_stride = input_padded_width;
750 120 : inputPtr->cr_stride = input_padded_width >> subsampling_x;
751 120 : inputPtr->cb_stride = input_padded_width >> subsampling_x;
752 :
753 120 : if (config->buffered_input == -1) {
754 120 : if (is16bit == 0 || (is16bit == 1 && config->compressed_ten_bit_format == 0)) {
755 120 : readSize = (uint64_t)SIZE_OF_ONE_FRAME_IN_BYTES(input_padded_width, input_padded_height, color_format, is16bit);
756 :
757 120 : headerPtr->n_filled_len = 0;
758 :
759 : // Interlaced Video
760 120 : if (config->separate_fields) {
761 0 : ProcessInputFieldStandardMode(
762 : config,
763 : headerPtr,
764 : input_file,
765 : inputPtr->luma,
766 : inputPtr->cb,
767 : inputPtr->cr,
768 : is16bit);
769 :
770 0 : if (readSize != headerPtr->n_filled_len) {
771 0 : fseek(input_file, 0, SEEK_SET);
772 0 : headerPtr->n_filled_len = 0;
773 :
774 0 : ProcessInputFieldStandardMode(
775 : config,
776 : headerPtr,
777 : input_file,
778 : inputPtr->luma,
779 : inputPtr->cb,
780 : inputPtr->cr,
781 : is16bit);
782 : }
783 :
784 : // Reset the pointer position after a top field
785 0 : if (config->processed_frame_count % 2 == 0)
786 0 : fseek(input_file, -(long)(readSize << 1), SEEK_CUR);
787 : }
788 : else {
789 : /* if input is a y4m file, read next line which contains "FRAME" */
790 120 : if(config->y4m_input==EB_TRUE)
791 120 : read_y4m_frame_delimiter(config);
792 120 : uint64_t lumaReadSize = (uint64_t)input_padded_width*input_padded_height << is16bit;
793 120 : ebInputPtr = inputPtr->luma;
794 120 : if (!config->y4m_input && config->processed_frame_count == 0 && (config->input_file == stdin || config->input_file_is_fifo)) {
795 : /* 9 bytes were already buffered during the the YUV4MPEG2 header probe */
796 0 : memcpy(ebInputPtr, config->y4m_buf, YUV4MPEG2_IND_SIZE);
797 0 : headerPtr->n_filled_len += YUV4MPEG2_IND_SIZE;
798 0 : ebInputPtr += YUV4MPEG2_IND_SIZE;
799 0 : headerPtr->n_filled_len += (uint32_t)fread(ebInputPtr, 1, lumaReadSize-YUV4MPEG2_IND_SIZE, input_file);
800 : } else {
801 120 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->luma, 1, lumaReadSize, input_file);
802 : }
803 120 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cb, 1, lumaReadSize >> (3 - color_format), input_file);
804 120 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cr, 1, lumaReadSize >> (3 - color_format), input_file);
805 :
806 120 : if (readSize != headerPtr->n_filled_len) {
807 0 : fseek(input_file, 0, SEEK_SET);
808 0 : headerPtr->n_filled_len = (uint32_t)fread(inputPtr->luma, 1, lumaReadSize, input_file);
809 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cb, 1, lumaReadSize >> (3 - color_format), input_file);
810 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cr, 1, lumaReadSize >> (3 - color_format), input_file);
811 : }
812 : }
813 : } else {
814 0 : assert(is16bit == 1 && config->compressed_ten_bit_format == 1);
815 : // 10-bit Compressed Unpacked Mode
816 0 : const uint32_t lumaReadSize = input_padded_width * input_padded_height;
817 0 : const uint32_t chromaReadSize = lumaReadSize >> (3 - color_format);
818 0 : const uint32_t nbitLumaReadSize = (input_padded_width / 4) * input_padded_height;
819 0 : const uint32_t nbitChromaReadSize = nbitLumaReadSize >> (3 - color_format);
820 :
821 : // Fill the buffer with a complete frame
822 0 : headerPtr->n_filled_len = 0;
823 :
824 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->luma, 1, lumaReadSize, input_file);
825 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cb, 1, chromaReadSize, input_file);
826 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cr, 1, chromaReadSize, input_file);
827 :
828 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->luma_ext, 1, nbitLumaReadSize, input_file);
829 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cb_ext, 1, nbitChromaReadSize, input_file);
830 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cr_ext, 1, nbitChromaReadSize, input_file);
831 :
832 0 : readSize = lumaReadSize + nbitLumaReadSize + 2 * (chromaReadSize + nbitChromaReadSize);
833 :
834 0 : if (readSize != headerPtr->n_filled_len) {
835 0 : fseek(input_file, 0, SEEK_SET);
836 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->luma, 1, lumaReadSize, input_file);
837 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cb, 1, chromaReadSize, input_file);
838 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cr, 1, chromaReadSize, input_file);
839 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->luma_ext, 1, nbitLumaReadSize, input_file);
840 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cb_ext, 1, nbitChromaReadSize, input_file);
841 0 : headerPtr->n_filled_len += (uint32_t)fread(inputPtr->cr_ext, 1, nbitChromaReadSize, input_file);
842 : }
843 : }
844 :
845 120 : if (feof(input_file) != 0) {
846 0 : if ((input_file == stdin) || (config->input_file_is_fifo)) {
847 : //for a fifo, we only know this when we reach eof
848 0 : config->frames_to_be_encoded = config->frames_encoded;
849 0 : if (headerPtr->n_filled_len != readSize) {
850 : // not a completed frame
851 0 : headerPtr->n_filled_len = 0;
852 : }
853 : } else {
854 : // If we reached the end of file, loop over again
855 0 : fseek(input_file, 0, SEEK_SET);
856 : }
857 : }
858 :
859 : } else {
860 0 : if (is16bit && config->compressed_ten_bit_format == 1) {
861 : // Determine size of each plane
862 0 : const size_t luma8bitSize = input_padded_width * input_padded_height;
863 0 : const size_t chroma8bitSize = luma8bitSize >> (3 - color_format);
864 0 : const size_t luma2bitSize = luma8bitSize / 4; //4-2bit pixels into 1 byte
865 0 : const size_t chroma2bitSize = luma2bitSize >> (3 - color_format);
866 :
867 0 : EbSvtIOFormat* inputPtr = (EbSvtIOFormat*)headerPtr->p_buffer;
868 0 : inputPtr->y_stride = input_padded_width;
869 0 : inputPtr->cr_stride = input_padded_width >> subsampling_x;
870 0 : inputPtr->cb_stride = input_padded_width >> subsampling_x;
871 :
872 0 : inputPtr->luma = config->sequence_buffer[config->processed_frame_count % config->buffered_input];
873 0 : inputPtr->cb = config->sequence_buffer[config->processed_frame_count % config->buffered_input] + luma8bitSize;
874 0 : inputPtr->cr = config->sequence_buffer[config->processed_frame_count % config->buffered_input] + luma8bitSize + chroma8bitSize;
875 :
876 0 : inputPtr->luma_ext = config->sequence_buffer[config->processed_frame_count % config->buffered_input] + luma8bitSize + 2 * chroma8bitSize;
877 0 : inputPtr->cb_ext = config->sequence_buffer[config->processed_frame_count % config->buffered_input] + luma8bitSize + 2 * chroma8bitSize + luma2bitSize;
878 0 : inputPtr->cr_ext = config->sequence_buffer[config->processed_frame_count % config->buffered_input] + luma8bitSize + 2 * chroma8bitSize + luma2bitSize + chroma2bitSize;
879 :
880 0 : headerPtr->n_filled_len = (uint32_t)(luma8bitSize + luma2bitSize + 2 * (chroma8bitSize + chroma2bitSize));
881 : } else {
882 : //Normal unpacked mode:yuv420p10le yuv422p10le yuv444p10le
883 0 : const size_t lumaSize = (input_padded_width * input_padded_height) << is16bit;
884 0 : const size_t chromaSize = lumaSize >> (3 - color_format);
885 :
886 0 : EbSvtIOFormat* inputPtr = (EbSvtIOFormat*)headerPtr->p_buffer;
887 :
888 0 : inputPtr->y_stride = input_padded_width;
889 0 : inputPtr->cr_stride = input_padded_width >> subsampling_x;
890 0 : inputPtr->cb_stride = input_padded_width >> subsampling_x;
891 :
892 0 : inputPtr->luma = config->sequence_buffer[config->processed_frame_count % config->buffered_input];
893 0 : inputPtr->cb = config->sequence_buffer[config->processed_frame_count % config->buffered_input] + lumaSize;
894 0 : inputPtr->cr = config->sequence_buffer[config->processed_frame_count % config->buffered_input] + lumaSize+ chromaSize;
895 :
896 0 : headerPtr->n_filled_len = (uint32_t)(lumaSize + 2 * chromaSize);
897 : }
898 : }
899 :
900 120 : return;
901 : }
902 :
903 0 : void SendQpOnTheFly(
904 : EbConfig *config,
905 : EbBufferHeaderType *headerPtr){
906 : {
907 : uint32_t qpPtr;
908 0 : int32_t tmpQp = 0;
909 :
910 : do {
911 : // get next qp
912 0 : tmpQp = GetNextQpFromQpFile(config);
913 :
914 0 : if (tmpQp == (int32_t)EB_ErrorInsufficientResources) {
915 0 : printf("Malloc has failed due to insuffucient resources");
916 0 : return;
917 : }
918 :
919 : // check if eof
920 0 : if ((tmpQp == -1) && (qpReadFromFile != 0))
921 0 : fseek(config->qp_file, 0, SEEK_SET);
922 :
923 : // check if the qp read is valid
924 0 : else if (tmpQp > 0)
925 0 : break;
926 0 : } while (tmpQp == 0 || ((tmpQp == -1) && (qpReadFromFile != 0)));
927 :
928 0 : if (tmpQp == -1) {
929 0 : config->use_qp_file = EB_FALSE;
930 0 : printf("\nWarning: QP File did not contain any valid QPs");
931 : }
932 :
933 0 : qpPtr = CLIP3(0, 51, tmpQp);
934 :
935 0 : headerPtr->qp = qpPtr;
936 : }
937 0 : return;
938 : }
939 :
940 : //************************************/
941 : // ProcessInputBuffer
942 : // Reads yuv frames from file and copy
943 : // them into the input buffer
944 : /************************************/
945 120 : AppExitConditionType ProcessInputBuffer(
946 : EbConfig *config,
947 : EbAppContext *appCallBack)
948 : {
949 120 : uint8_t is16bit = (uint8_t)(config->encoder_bit_depth > 8);
950 120 : EbBufferHeaderType *headerPtr = appCallBack->input_buffer_pool;
951 120 : EbComponentType *componentHandle = (EbComponentType*)appCallBack->svt_encoder_handle;
952 :
953 120 : AppExitConditionType return_value = APP_ExitConditionNone;
954 :
955 120 : const uint8_t color_format = config->encoder_color_format;
956 120 : const int64_t input_padded_width = config->input_padded_width;
957 120 : const int64_t input_padded_height = config->input_padded_height;
958 120 : const int64_t frames_to_be_encoded = config->frames_to_be_encoded;
959 : int64_t totalBytesToProcessCount;
960 : int64_t remainingByteCount;
961 120 : uint32_t compressed10bitFrameSize = (uint32_t)((input_padded_width*input_padded_height) + 2 * ((input_padded_width*input_padded_width) >> (3 - color_format)));
962 120 : compressed10bitFrameSize += compressed10bitFrameSize / 4;
963 :
964 120 : if (config->injector && config->processed_frame_count)
965 0 : Injector(config->processed_frame_count, config->injector_frame_rate);
966 240 : totalBytesToProcessCount = (frames_to_be_encoded < 0) ? -1 : (config->encoder_bit_depth == 10 && config->compressed_ten_bit_format == 1) ?
967 120 : frames_to_be_encoded * (int64_t)compressed10bitFrameSize:
968 120 : frames_to_be_encoded * SIZE_OF_ONE_FRAME_IN_BYTES(input_padded_width, input_padded_height, color_format, is16bit);
969 :
970 120 : remainingByteCount = (totalBytesToProcessCount < 0) ? -1 : totalBytesToProcessCount - (int64_t)config->processed_byte_count;
971 :
972 : // If there are bytes left to encode, configure the header
973 120 : if (remainingByteCount != 0 && config->stop_encoder == EB_FALSE) {
974 120 : ReadInputFrames(
975 : config,
976 : is16bit,
977 : headerPtr);
978 120 : if (headerPtr->n_filled_len) {
979 : // Update the context parameters
980 120 : config->processed_byte_count += headerPtr->n_filled_len;
981 120 : headerPtr->p_app_private = (EbPtr)EB_NULL;
982 120 : config->frames_encoded = (int32_t)(++config->processed_frame_count);
983 :
984 : // Configuration parameters changed on the fly
985 120 : if (config->use_qp_file && config->qp_file)
986 0 : SendQpOnTheFly(
987 : config,
988 : headerPtr);
989 :
990 120 : if (keepRunning == 0 && !config->stop_encoder)
991 0 : config->stop_encoder = EB_TRUE;
992 : // Fill in Buffers Header control data
993 120 : headerPtr->pts = config->processed_frame_count-1;
994 120 : headerPtr->pic_type = EB_AV1_INVALID_PICTURE;
995 :
996 120 : headerPtr->flags = 0;
997 :
998 : // Send the picture
999 120 : eb_svt_enc_send_picture(componentHandle, headerPtr);
1000 : }
1001 :
1002 120 : if ((config->processed_frame_count == (uint64_t)config->frames_to_be_encoded) || config->stop_encoder) {
1003 2 : headerPtr->n_alloc_len = 0;
1004 2 : headerPtr->n_filled_len = 0;
1005 2 : headerPtr->n_tick_count = 0;
1006 2 : headerPtr->p_app_private = NULL;
1007 2 : headerPtr->flags = EB_BUFFERFLAG_EOS;
1008 2 : headerPtr->p_buffer = NULL;
1009 2 : headerPtr->pic_type = EB_AV1_INVALID_PICTURE;
1010 :
1011 2 : eb_svt_enc_send_picture(componentHandle, headerPtr);
1012 : }
1013 :
1014 120 : return_value = (headerPtr->flags == EB_BUFFERFLAG_EOS) ? APP_ExitConditionFinished : return_value;
1015 : }
1016 :
1017 120 : return return_value;
1018 : }
1019 :
1020 : #define LONG_ENCODE_FRAME_ENCODE 4000
1021 : #define SPEED_MEASUREMENT_INTERVAL 2000
1022 : #define START_STEADY_STATE 1000
1023 : #define AV1_FOURCC 0x31305641 // used for ivf header
1024 : #define IVF_STREAM_HEADER_SIZE 32
1025 : #define IVF_FRAME_HEADER_SIZE 12
1026 : #define OBU_FRAME_HEADER_SIZE 3
1027 : #define TD_SIZE 2
1028 460 : static __inline void mem_put_le32(void *vmem, int32_t val) {
1029 460 : uint8_t *mem = (uint8_t *)vmem;
1030 :
1031 460 : mem[0] = (uint8_t)((val >> 0) & 0xff);
1032 460 : mem[1] = (uint8_t)((val >> 8) & 0xff);
1033 460 : mem[2] = (uint8_t)((val >> 16) & 0xff);
1034 460 : mem[3] = (uint8_t)((val >> 24) & 0xff);
1035 460 : }
1036 : #define MEM_VALUE_T_SZ_BITS (sizeof(MEM_VALUE_T) << 3)
1037 :
1038 8 : static __inline void mem_put_le16(void *vmem, int32_t val) {
1039 8 : uint8_t *mem = (uint8_t *)vmem;
1040 :
1041 8 : mem[0] = (uint8_t)((val >> 0) & 0xff);
1042 8 : mem[1] = (uint8_t)((val >> 8) & 0xff);
1043 8 : }
1044 :
1045 2 : static void write_ivf_stream_header(EbConfig *config)
1046 : {
1047 : char header[IVF_STREAM_HEADER_SIZE];
1048 2 : header[0] = 'D';
1049 2 : header[1] = 'K';
1050 2 : header[2] = 'I';
1051 2 : header[3] = 'F';
1052 2 : mem_put_le16(header + 4, 0); // version
1053 2 : mem_put_le16(header + 6, 32); // header size
1054 2 : mem_put_le32(header + 8, AV1_FOURCC); // fourcc
1055 2 : mem_put_le16(header + 12, config->input_padded_width); // width
1056 2 : mem_put_le16(header + 14, config->input_padded_height); // height
1057 2 : if (config->frame_rate_denominator != 0 && config->frame_rate_numerator != 0){
1058 2 : mem_put_le32(header + 16, config->frame_rate_numerator); // rate
1059 2 : mem_put_le32(header + 20, config->frame_rate_denominator); // scale
1060 : //mem_put_le32(header + 16, config->frame_rate_denominator); // rate
1061 : //mem_put_le32(header + 20, config->frame_rate_numerator); // scale
1062 : }
1063 : else {
1064 0 : mem_put_le32(header + 16, (config->frame_rate >> 16) * 1000); // rate
1065 0 : mem_put_le32(header + 20, 1000); // scale
1066 : //mem_put_le32(header + 16, config->frame_rate_denominator); // rate
1067 : //mem_put_le32(header + 20, config->frame_rate_numerator); // scale
1068 : }
1069 2 : mem_put_le32(header + 24, 0); // length
1070 2 : mem_put_le32(header + 28, 0); // unused
1071 : //config->performance_context.byte_count += 32;
1072 2 : if (config->bitstream_file)
1073 2 : fwrite(header, 1, IVF_STREAM_HEADER_SIZE, config->bitstream_file);
1074 :
1075 2 : return;
1076 : }
1077 92 : static void update_prev_ivf_header(EbConfig *config){
1078 : char header[4]; // only for the number of bytes
1079 92 : if (config && config->bitstream_file && config->byte_count_since_ivf != 0){
1080 90 : fseeko(config->bitstream_file, (-(int32_t)(config->byte_count_since_ivf + IVF_FRAME_HEADER_SIZE)),SEEK_CUR);
1081 90 : mem_put_le32(&header[0], (int32_t)(config->byte_count_since_ivf));
1082 90 : fwrite(header, 1, 4, config->bitstream_file);
1083 90 : fseeko(config->bitstream_file, (config->byte_count_since_ivf + IVF_FRAME_HEADER_SIZE - 4), SEEK_CUR);
1084 90 : config->byte_count_since_ivf = 0;
1085 : }
1086 92 : }
1087 :
1088 120 : static void write_ivf_frame_header(EbConfig *config, uint32_t byte_count){
1089 : char header[IVF_FRAME_HEADER_SIZE];
1090 120 : int32_t write_location = 0;
1091 :
1092 120 : mem_put_le32(&header[write_location], (int32_t)byte_count);
1093 120 : write_location = write_location + 4;
1094 120 : mem_put_le32(&header[write_location], (int32_t)((config->ivf_count) & 0xFFFFFFFF));
1095 120 : write_location = write_location + 4;
1096 120 : mem_put_le32(&header[write_location], (int32_t)((config->ivf_count) >> 32));
1097 120 : write_location = write_location + 4;
1098 :
1099 120 : config->byte_count_since_ivf = (byte_count);
1100 :
1101 120 : config->ivf_count++;
1102 120 : fflush(stdout);
1103 :
1104 120 : if (config->bitstream_file)
1105 120 : fwrite(header, 1, IVF_FRAME_HEADER_SIZE, config->bitstream_file);
1106 120 : }
1107 0 : double get_psnr(double sse, double max){
1108 : double psnr;
1109 0 : if (sse == 0)
1110 0 : psnr = 10 * log10(max / (double)0.1);
1111 : else
1112 0 : psnr = 10 * log10(max / sse);
1113 :
1114 0 : return psnr;
1115 : }
1116 :
1117 : /***************************************
1118 : * Process Output STATISTICS Buffer
1119 : ***************************************/
1120 0 : void process_output_statistics_buffer(
1121 : EbBufferHeaderType *header_ptr,
1122 : EbConfig *config){
1123 :
1124 0 : uint32_t max_luma_value = (config->encoder_bit_depth == 8) ? 255 : 1023;
1125 : uint64_t picture_stream_size, luma_sse, cr_sse, cb_sse, picture_number, picture_qp;
1126 : double temp_var, luma_psnr, cb_psnr, cr_psnr;
1127 :
1128 0 : picture_stream_size = header_ptr->n_filled_len;
1129 0 : luma_sse = header_ptr->luma_sse;
1130 0 : cr_sse = header_ptr->cr_sse;
1131 0 : cb_sse = header_ptr->cb_sse;
1132 0 : picture_number = header_ptr->pts;
1133 0 : picture_qp = header_ptr->qp;
1134 :
1135 0 : temp_var = (double)max_luma_value*max_luma_value *
1136 0 : (config->source_width*config->source_height);
1137 :
1138 0 : luma_psnr = get_psnr((double)luma_sse, temp_var);
1139 :
1140 0 : temp_var = (double) max_luma_value * max_luma_value *
1141 0 : (config->source_width / 2 * config->source_height / 2);
1142 :
1143 0 : cb_psnr = get_psnr((double)cb_sse, temp_var);
1144 :
1145 0 : cr_psnr = get_psnr((double)cr_sse, temp_var);
1146 :
1147 0 : config->performance_context.sum_luma_psnr += luma_psnr;
1148 0 : config->performance_context.sum_cr_psnr += cr_psnr;
1149 0 : config->performance_context.sum_cb_psnr += cb_psnr;
1150 :
1151 0 : config->performance_context.sum_luma_sse += luma_sse;
1152 0 : config->performance_context.sum_cr_sse += cr_sse;
1153 0 : config->performance_context.sum_cb_sse += cb_sse;
1154 :
1155 0 : config->performance_context.sum_qp += picture_qp;
1156 :
1157 : // Write statistic Data to file
1158 0 : if (config->stat_file)
1159 0 : fprintf(config->stat_file, "Picture Number: %4d\t QP: %4d [ PSNR-Y: %.2f dB,\tPSNR-U: %.2f dB,\tPSNR-V: %.2f dB,\tMSE-Y: %.2f,\tMSE-U: %.2f,\tMSE-V: %.2f ]\t %6d bits\n",
1160 : (int)picture_number,
1161 : (int)picture_qp,
1162 : luma_psnr,
1163 : cb_psnr,
1164 : cr_psnr,
1165 0 : (double)luma_sse/(config->source_width * config->source_height),
1166 0 : (double)cb_sse/(config->source_width / 2 * config->source_height / 2),
1167 0 : (double)cr_sse/(config->source_width / 2 * config->source_height / 2),
1168 : (int)picture_stream_size);
1169 :
1170 0 : return;
1171 : }
1172 :
1173 :
1174 238 : AppExitConditionType ProcessOutputStreamBuffer(
1175 : EbConfig *config,
1176 : EbAppContext *appCallBack,
1177 : uint8_t pic_send_done)
1178 : {
1179 238 : AppPortActiveType *portState = &appCallBack->output_stream_port_active;
1180 : EbBufferHeaderType *headerPtr;
1181 238 : EbComponentType *componentHandle = (EbComponentType*)appCallBack->svt_encoder_handle;
1182 238 : AppExitConditionType return_value = APP_ExitConditionNone;
1183 238 : EbErrorType stream_status = EB_ErrorNone;
1184 : // Per channel variables
1185 238 : FILE *streamFile = config->bitstream_file;
1186 :
1187 238 : uint64_t *total_latency = &config->performance_context.total_latency;
1188 238 : uint32_t *max_latency = &config->performance_context.max_latency;
1189 :
1190 : // System performance variables
1191 : static int32_t frame_count = 0;
1192 :
1193 : // Local variables
1194 238 : uint64_t finishsTime = 0;
1195 238 : uint64_t finishuTime = 0;
1196 238 : uint8_t is_alt_ref = 1;
1197 476 : while (is_alt_ref) {
1198 238 : is_alt_ref = 0;
1199 : // non-blocking call until all input frames are sent
1200 238 : stream_status = eb_svt_get_packet(componentHandle, &headerPtr, pic_send_done);
1201 :
1202 238 : if (stream_status == EB_ErrorMax) {
1203 0 : printf("\n");
1204 0 : LogErrorOutput(
1205 : config->error_log_file,
1206 0 : headerPtr->flags);
1207 0 : return APP_ExitConditionError;
1208 : }
1209 238 : else if (stream_status != EB_NoErrorEmptyQueue) {
1210 120 : is_alt_ref = (headerPtr->flags & EB_BUFFERFLAG_IS_ALT_REF);
1211 120 : EbBool has_tiles = (EbBool)(appCallBack->eb_enc_parameters.tile_columns || appCallBack->eb_enc_parameters.tile_rows);
1212 120 : uint8_t obu_frame_header_size = has_tiles ? OBU_FRAME_HEADER_SIZE + 1 : OBU_FRAME_HEADER_SIZE;
1213 120 : if (!(headerPtr->flags & EB_BUFFERFLAG_IS_ALT_REF))
1214 120 : ++(config->performance_context.frame_count);
1215 120 : *total_latency += (uint64_t)headerPtr->n_tick_count;
1216 120 : *max_latency = (headerPtr->n_tick_count > *max_latency) ? headerPtr->n_tick_count : *max_latency;
1217 :
1218 120 : FinishTime((uint64_t*)&finishsTime, (uint64_t*)&finishuTime);
1219 :
1220 : // total execution time, inc init time
1221 120 : ComputeOverallElapsedTime(
1222 : config->performance_context.lib_start_time[0],
1223 : config->performance_context.lib_start_time[1],
1224 : finishsTime,
1225 : finishuTime,
1226 : &config->performance_context.total_execution_time);
1227 :
1228 : // total encode time
1229 120 : ComputeOverallElapsedTime(
1230 : config->performance_context.encode_start_time[0],
1231 : config->performance_context.encode_start_time[1],
1232 : finishsTime,
1233 : finishuTime,
1234 : &config->performance_context.total_encode_time);
1235 :
1236 : // Write Stream Data to file
1237 120 : if (streamFile) {
1238 120 : if (config->performance_context.frame_count == 1 && !(headerPtr->flags & EB_BUFFERFLAG_IS_ALT_REF)){
1239 2 : write_ivf_stream_header(config);
1240 : }
1241 :
1242 120 : switch (headerPtr->flags & 0x00000006) { // Check for the flags EB_BUFFERFLAG_HAS_TD and EB_BUFFERFLAG_SHOW_EXT
1243 28 : case (EB_BUFFERFLAG_HAS_TD | EB_BUFFERFLAG_SHOW_EXT):
1244 :
1245 : // terminate previous ivf packet, update the combined size of packets sent
1246 28 : update_prev_ivf_header(config);
1247 :
1248 : // Write a new IVF frame header to file as a TD is in the packet
1249 28 : write_ivf_frame_header(config, headerPtr->n_filled_len - (obu_frame_header_size + TD_SIZE));
1250 28 : fwrite(headerPtr->p_buffer, 1, headerPtr->n_filled_len - (obu_frame_header_size + TD_SIZE), streamFile);
1251 :
1252 : // An EB_BUFFERFLAG_SHOW_EXT means that another TD has been added to the packet to show another frame, a new IVF is needed
1253 28 : write_ivf_frame_header(config, (obu_frame_header_size + TD_SIZE));
1254 28 : fwrite(headerPtr->p_buffer + headerPtr->n_filled_len - (obu_frame_header_size + TD_SIZE), 1, (obu_frame_header_size + TD_SIZE), streamFile);
1255 :
1256 28 : break;
1257 :
1258 36 : case (EB_BUFFERFLAG_HAS_TD):
1259 :
1260 : // terminate previous ivf packet, update the combined size of packets sent
1261 36 : update_prev_ivf_header(config);
1262 :
1263 : // Write a new IVF frame header to file as a TD is in the packet
1264 36 : write_ivf_frame_header(config, headerPtr->n_filled_len);
1265 36 : fwrite(headerPtr->p_buffer, 1, headerPtr->n_filled_len, streamFile);
1266 :
1267 36 : break;
1268 :
1269 28 : case (EB_BUFFERFLAG_SHOW_EXT):
1270 :
1271 : // this case means that there's only one TD in this packet and is relater
1272 28 : fwrite(headerPtr->p_buffer, 1, headerPtr->n_filled_len - (obu_frame_header_size + TD_SIZE), streamFile);
1273 : // this packet will be part of the previous IVF header
1274 28 : config->byte_count_since_ivf += (headerPtr->n_filled_len - (obu_frame_header_size + TD_SIZE));
1275 :
1276 : // terminate previous ivf packet, update the combined size of packets sent
1277 28 : update_prev_ivf_header(config);
1278 :
1279 : // An EB_BUFFERFLAG_SHOW_EXT means that another TD has been added to the packet to show another frame, a new IVF is needed
1280 28 : write_ivf_frame_header(config, (obu_frame_header_size + TD_SIZE));
1281 28 : fwrite(headerPtr->p_buffer + headerPtr->n_filled_len - (obu_frame_header_size + TD_SIZE), 1, (obu_frame_header_size + TD_SIZE), streamFile);
1282 :
1283 28 : break;
1284 :
1285 28 : default:
1286 :
1287 : // This is a packet without a TD, write it straight to file
1288 28 : fwrite(headerPtr->p_buffer, 1, headerPtr->n_filled_len, streamFile);
1289 :
1290 : // this packet will be part of the previous IVF header
1291 28 : config->byte_count_since_ivf += (headerPtr->n_filled_len);
1292 28 : break;
1293 : }
1294 0 : }
1295 120 : config->performance_context.byte_count += headerPtr->n_filled_len;
1296 :
1297 120 : if (config->stat_report && !(headerPtr->flags & EB_BUFFERFLAG_IS_ALT_REF))
1298 0 : process_output_statistics_buffer(headerPtr, config);
1299 :
1300 : // Update Output Port Activity State
1301 120 : *portState = (headerPtr->flags & EB_BUFFERFLAG_EOS) ? APP_PortInactive : *portState;
1302 120 : return_value = (headerPtr->flags & EB_BUFFERFLAG_EOS) ? APP_ExitConditionFinished : APP_ExitConditionNone;
1303 :
1304 : // Release the output buffer
1305 120 : eb_svt_release_out_buffer(&headerPtr);
1306 :
1307 : #if DEADLOCK_DEBUG
1308 : ++frame_count;
1309 : #else
1310 : //++frame_count;
1311 120 : if (!(headerPtr->flags & EB_BUFFERFLAG_IS_ALT_REF))
1312 120 : printf("\b\b\b\b\b\b\b\b\b%9d", ++frame_count);
1313 : #endif
1314 :
1315 : //++frame_count;
1316 120 : fflush(stdout);
1317 :
1318 : {
1319 120 : config->performance_context.average_speed = (config->performance_context.frame_count) / config->performance_context.total_encode_time;
1320 120 : config->performance_context.average_latency = config->performance_context.total_latency / (double)(config->performance_context.frame_count);
1321 : }
1322 :
1323 120 : if (!(frame_count % SPEED_MEASUREMENT_INTERVAL)) {
1324 : {
1325 0 : printf("\n");
1326 0 : printf("Average System Encoding Speed: %.2f\n", (double)(frame_count) / config->performance_context.total_encode_time);
1327 : }
1328 : }
1329 : }
1330 : }
1331 238 : return return_value;
1332 : }
1333 0 : AppExitConditionType ProcessOutputReconBuffer(
1334 : EbConfig *config,
1335 : EbAppContext *appCallBack)
1336 : {
1337 0 : EbBufferHeaderType *headerPtr = appCallBack->recon_buffer; // needs to change for buffered input
1338 0 : EbComponentType *componentHandle = (EbComponentType*)appCallBack->svt_encoder_handle;
1339 0 : AppExitConditionType return_value = APP_ExitConditionNone;
1340 0 : EbErrorType recon_status = EB_ErrorNone;
1341 : int32_t fseekReturnVal;
1342 : // non-blocking call until all input frames are sent
1343 0 : recon_status = eb_svt_get_recon(componentHandle, headerPtr);
1344 :
1345 0 : if (recon_status == EB_ErrorMax) {
1346 0 : printf("\n");
1347 0 : LogErrorOutput(
1348 : config->error_log_file,
1349 : headerPtr->flags);
1350 0 : return APP_ExitConditionError;
1351 : }
1352 0 : else if (recon_status != EB_NoErrorEmptyQueue) {
1353 : //Sets the File position to the beginning of the file.
1354 0 : rewind(config->recon_file);
1355 0 : uint64_t frameNum = headerPtr->pts;
1356 0 : while (frameNum>0) {
1357 0 : fseekReturnVal = fseeko(config->recon_file, headerPtr->n_filled_len, SEEK_CUR);
1358 :
1359 0 : if (fseekReturnVal != 0) {
1360 0 : printf("Error in fseeko returnVal %i\n", fseekReturnVal);
1361 0 : return APP_ExitConditionError;
1362 : }
1363 0 : frameNum = frameNum - 1;
1364 : }
1365 :
1366 0 : fwrite(headerPtr->p_buffer, 1, headerPtr->n_filled_len, config->recon_file);
1367 :
1368 : // Update Output Port Activity State
1369 0 : return_value = (headerPtr->flags & EB_BUFFERFLAG_EOS) ? APP_ExitConditionFinished : APP_ExitConditionNone;
1370 : }
1371 0 : return return_value;
1372 : }
|