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 :
10 : #include <stdlib.h>
11 :
12 : #include "EbAppContext.h"
13 : #include "EbAppConfig.h"
14 :
15 : #define INPUT_SIZE_576p_TH 0x90000 // 0.58 Million
16 : #define INPUT_SIZE_1080i_TH 0xB71B0 // 0.75 Million
17 : #define INPUT_SIZE_1080p_TH 0x1AB3F0 // 1.75 Million
18 : #define INPUT_SIZE_4K_TH 0x29F630 // 2.75 Million
19 :
20 : #define IS_16_BIT(bit_depth) (bit_depth==10?1:0)
21 : #define EB_OUTPUTSTREAMBUFFERSIZE_MACRO(ResolutionSize) ((ResolutionSize) < (INPUT_SIZE_1080i_TH) ? 0x1E8480 : (ResolutionSize) < (INPUT_SIZE_1080p_TH) ? 0x2DC6C0 : (ResolutionSize) < (INPUT_SIZE_4K_TH) ? 0x2DC6C0 : 0x2DC6C0 )
22 :
23 : /***************************************
24 : * Variables Defining a memory table
25 : * hosting all allocated pointers
26 : ***************************************/
27 : EbMemoryMapEntry *app_memory_map;
28 : uint32_t *app_memory_map_index;
29 : uint64_t *total_app_memory;
30 : uint32_t app_malloc_count = 0;
31 : static EbMemoryMapEntry *appMemoryMapAllChannels[MAX_CHANNEL_NUMBER];
32 : static uint32_t appMemoryMapIndexAllChannels[MAX_CHANNEL_NUMBER];
33 : static uint64_t appMemoryMallocdAllChannels[MAX_CHANNEL_NUMBER];
34 :
35 : /***************************************
36 : * Allocation and initializing a memory table
37 : * hosting all allocated pointers
38 : ***************************************/
39 2 : void AllocateMemoryTable(
40 : uint32_t instance_idx)
41 : {
42 : // Malloc Memory Table for the instance @ instance_idx
43 2 : appMemoryMapAllChannels[instance_idx] = (EbMemoryMapEntry*)malloc(sizeof(EbMemoryMapEntry) * MAX_APP_NUM_PTR);
44 :
45 : // Init the table index
46 2 : appMemoryMapIndexAllChannels[instance_idx] = 0;
47 :
48 : // Size of the table
49 2 : appMemoryMallocdAllChannels[instance_idx] = sizeof(EbMemoryMapEntry) * MAX_APP_NUM_PTR;
50 2 : total_app_memory = &appMemoryMallocdAllChannels[instance_idx];
51 :
52 : // Set pointer to the first entry
53 2 : app_memory_map = appMemoryMapAllChannels[instance_idx];
54 :
55 : // Set index to the first entry
56 2 : app_memory_map_index = &appMemoryMapIndexAllChannels[instance_idx];
57 :
58 : // Init Number of pointers
59 2 : app_malloc_count = 0;
60 :
61 2 : return;
62 : }
63 :
64 : /*************************************
65 : **************************************
66 : *** Helper functions Input / Output **
67 : **************************************
68 : **************************************/
69 : /******************************************************
70 : * Copy fields from the stream to the input buffer
71 : Input : stream
72 : Output : valid input buffer
73 : ******************************************************/
74 0 : void ProcessInputFieldBufferingMode(
75 : uint64_t processed_frame_count,
76 : int32_t *filledLen,
77 : FILE *input_file,
78 : uint8_t *lumaInputPtr,
79 : uint8_t *cbInputPtr,
80 : uint8_t *crInputPtr,
81 : uint32_t input_padded_width,
82 : uint32_t input_padded_height,
83 : uint8_t is16bit) {
84 0 : uint64_t sourceLumaRowSize = (uint64_t)(input_padded_width << is16bit);
85 0 : uint64_t sourceChromaRowSize = sourceLumaRowSize >> 1;
86 :
87 : uint8_t *ebInputPtr;
88 : uint32_t inputRowIndex;
89 :
90 : // Y
91 0 : ebInputPtr = lumaInputPtr;
92 : // Skip 1 luma row if bottom field (point to the bottom field)
93 0 : if (processed_frame_count % 2 != 0)
94 0 : fseeko(input_file, (long)sourceLumaRowSize, SEEK_CUR);
95 :
96 0 : for (inputRowIndex = 0; inputRowIndex < input_padded_height; inputRowIndex++) {
97 0 : *filledLen += (uint32_t)fread(ebInputPtr, 1, sourceLumaRowSize, input_file);
98 : // Skip 1 luma row (only fields)
99 0 : fseeko(input_file, (long)sourceLumaRowSize, SEEK_CUR);
100 0 : ebInputPtr += sourceLumaRowSize;
101 : }
102 :
103 : // U
104 0 : ebInputPtr = cbInputPtr;
105 : // 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)
106 0 : if (processed_frame_count % 2 != 0) {
107 0 : fseeko(input_file, -(long)sourceLumaRowSize, SEEK_CUR);
108 0 : fseeko(input_file, (long)sourceChromaRowSize, SEEK_CUR);
109 : }
110 :
111 0 : for (inputRowIndex = 0; inputRowIndex < input_padded_height >> 1; inputRowIndex++) {
112 0 : *filledLen += (uint32_t)fread(ebInputPtr, 1, sourceChromaRowSize, input_file);
113 : // Skip 1 chroma row (only fields)
114 0 : fseeko(input_file, (long)sourceChromaRowSize, SEEK_CUR);
115 0 : ebInputPtr += sourceChromaRowSize;
116 : }
117 :
118 : // V
119 0 : ebInputPtr = crInputPtr;
120 : // 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)
121 : // => no action
122 :
123 0 : for (inputRowIndex = 0; inputRowIndex < input_padded_height >> 1; inputRowIndex++) {
124 0 : *filledLen += (uint32_t)fread(ebInputPtr, 1, sourceChromaRowSize, input_file);
125 : // Skip 1 chroma row (only fields)
126 0 : fseeko(input_file, (long)sourceChromaRowSize, SEEK_CUR);
127 0 : ebInputPtr += sourceChromaRowSize;
128 : }
129 :
130 : // Step back 1 chroma row if bottom field (undo the previous jump)
131 0 : if (processed_frame_count % 2 != 0)
132 0 : fseeko(input_file, -(long)sourceChromaRowSize, SEEK_CUR);
133 0 : }
134 :
135 : /***********************************************
136 : * Copy configuration parameters from
137 : * The config structure, to the
138 : * callback structure to send to the library
139 : ***********************************************/
140 2 : EbErrorType CopyConfigurationParameters(
141 : EbConfig *config,
142 : EbAppContext *callback_data,
143 : uint32_t instance_idx)
144 : {
145 2 : EbErrorType return_error = EB_ErrorNone;
146 : uint32_t hmeRegionIndex;
147 :
148 : // Assign Instance index to the library
149 2 : callback_data->instance_idx = (uint8_t)instance_idx;
150 :
151 : // Initialize Port Activity Flags
152 2 : callback_data->output_stream_port_active = APP_PortActive;
153 :
154 2 : callback_data->eb_enc_parameters.source_width = config->source_width;
155 2 : callback_data->eb_enc_parameters.source_height = config->source_height;
156 2 : callback_data->eb_enc_parameters.render_width = config->input_padded_width;
157 2 : callback_data->eb_enc_parameters.render_height = config->input_padded_height;
158 :
159 2 : callback_data->eb_enc_parameters.intra_period_length = config->intra_period;
160 2 : callback_data->eb_enc_parameters.intra_refresh_type = config->intra_refresh_type;
161 2 : callback_data->eb_enc_parameters.base_layer_switch_mode = config->base_layer_switch_mode;
162 2 : callback_data->eb_enc_parameters.enc_mode = (EbBool)config->enc_mode;
163 : #if TWO_PASS_USE_2NDP_ME_IN_1STP
164 2 : callback_data->eb_enc_parameters.snd_pass_enc_mode = (EbBool)config->snd_pass_enc_mode;
165 : #endif
166 2 : callback_data->eb_enc_parameters.frame_rate = config->frame_rate;
167 2 : callback_data->eb_enc_parameters.frame_rate_denominator = config->frame_rate_denominator;
168 2 : callback_data->eb_enc_parameters.frame_rate_numerator = config->frame_rate_numerator;
169 2 : callback_data->eb_enc_parameters.hierarchical_levels = config->hierarchical_levels;
170 2 : callback_data->eb_enc_parameters.pred_structure = (uint8_t)config->pred_structure;
171 2 : callback_data->eb_enc_parameters.in_loop_me_flag = config->in_loop_me_flag;
172 2 : callback_data->eb_enc_parameters.ext_block_flag = config->ext_block_flag;
173 2 : callback_data->eb_enc_parameters.tile_rows = config->tile_rows;
174 2 : callback_data->eb_enc_parameters.tile_columns = config->tile_columns;
175 :
176 2 : callback_data->eb_enc_parameters.scene_change_detection = config->scene_change_detection;
177 2 : callback_data->eb_enc_parameters.look_ahead_distance = config->look_ahead_distance;
178 2 : callback_data->eb_enc_parameters.frames_to_be_encoded = config->frames_to_be_encoded;
179 2 : callback_data->eb_enc_parameters.rate_control_mode = config->rate_control_mode;
180 2 : callback_data->eb_enc_parameters.target_bit_rate = config->target_bit_rate;
181 2 : callback_data->eb_enc_parameters.max_qp_allowed = config->max_qp_allowed;
182 2 : callback_data->eb_enc_parameters.min_qp_allowed = config->min_qp_allowed;
183 2 : callback_data->eb_enc_parameters.enable_adaptive_quantization = (EbBool)config->enable_adaptive_quantization;
184 2 : callback_data->eb_enc_parameters.qp = config->qp;
185 2 : callback_data->eb_enc_parameters.use_qp_file = (EbBool)config->use_qp_file;
186 : #if TWO_PASS
187 2 : callback_data->eb_enc_parameters.input_stat_file = config->input_stat_file;
188 2 : callback_data->eb_enc_parameters.output_stat_file = config->output_stat_file;
189 : #endif
190 2 : callback_data->eb_enc_parameters.stat_report = (EbBool)config->stat_report;
191 2 : callback_data->eb_enc_parameters.disable_dlf_flag = (EbBool)config->disable_dlf_flag;
192 2 : callback_data->eb_enc_parameters.enable_warped_motion = (EbBool)config->enable_warped_motion;
193 2 : callback_data->eb_enc_parameters.enable_global_motion = (EbBool)config->enable_global_motion;
194 2 : callback_data->eb_enc_parameters.enable_obmc = (EbBool)config->enable_obmc;
195 2 : callback_data->eb_enc_parameters.enable_rdoq = config->enable_rdoq;
196 2 : callback_data->eb_enc_parameters.enable_filter_intra = (EbBool)config->enable_filter_intra;
197 2 : callback_data->eb_enc_parameters.use_default_me_hme = (EbBool)config->use_default_me_hme;
198 2 : callback_data->eb_enc_parameters.enable_hme_flag = (EbBool)config->enable_hme_flag;
199 2 : callback_data->eb_enc_parameters.enable_hme_level0_flag = (EbBool)config->enable_hme_level0_flag;
200 2 : callback_data->eb_enc_parameters.enable_hme_level1_flag = (EbBool)config->enable_hme_level1_flag;
201 2 : callback_data->eb_enc_parameters.enable_hme_level2_flag = (EbBool)config->enable_hme_level2_flag;
202 2 : callback_data->eb_enc_parameters.search_area_width = config->search_area_width;
203 2 : callback_data->eb_enc_parameters.search_area_height = config->search_area_height;
204 2 : callback_data->eb_enc_parameters.number_hme_search_region_in_width = config->number_hme_search_region_in_width;
205 2 : callback_data->eb_enc_parameters.number_hme_search_region_in_height = config->number_hme_search_region_in_height;
206 2 : callback_data->eb_enc_parameters.hme_level0_total_search_area_width = config->hme_level0_total_search_area_width;
207 2 : callback_data->eb_enc_parameters.hme_level0_total_search_area_height = config->hme_level0_total_search_area_height;
208 2 : callback_data->eb_enc_parameters.screen_content_mode = (EbBool)config->screen_content_mode;
209 2 : callback_data->eb_enc_parameters.enable_hbd_mode_decision = (EbBool)config->enable_hbd_mode_decision;
210 2 : callback_data->eb_enc_parameters.enable_palette = config->enable_palette;
211 2 : callback_data->eb_enc_parameters.olpd_refinement = config->olpd_refinement;
212 2 : callback_data->eb_enc_parameters.constrained_intra = (EbBool)config->constrained_intra;
213 2 : callback_data->eb_enc_parameters.channel_id = config->channel_id;
214 2 : callback_data->eb_enc_parameters.active_channel_count = config->active_channel_count;
215 2 : callback_data->eb_enc_parameters.high_dynamic_range_input = config->high_dynamic_range_input;
216 2 : callback_data->eb_enc_parameters.encoder_bit_depth = config->encoder_bit_depth;
217 2 : callback_data->eb_enc_parameters.encoder_color_format =
218 2 : (EbColorFormat)config->encoder_color_format;
219 2 : callback_data->eb_enc_parameters.compressed_ten_bit_format = config->compressed_ten_bit_format;
220 2 : callback_data->eb_enc_parameters.profile = config->profile;
221 2 : callback_data->eb_enc_parameters.tier = config->tier;
222 2 : callback_data->eb_enc_parameters.level = config->level;
223 2 : callback_data->eb_enc_parameters.injector_frame_rate = config->injector_frame_rate;
224 2 : callback_data->eb_enc_parameters.speed_control_flag = config->speed_control_flag;
225 2 : callback_data->eb_enc_parameters.asm_type = config->asm_type;
226 2 : callback_data->eb_enc_parameters.logical_processors = config->logical_processors;
227 2 : callback_data->eb_enc_parameters.target_socket = config->target_socket;
228 2 : callback_data->eb_enc_parameters.unrestricted_motion_vector = config->unrestricted_motion_vector;
229 2 : callback_data->eb_enc_parameters.recon_enabled = config->recon_file ? EB_TRUE : EB_FALSE;
230 : // --- start: ALTREF_FILTERING_SUPPORT
231 2 : callback_data->eb_enc_parameters.enable_altrefs = (EbBool)config->enable_altrefs;
232 2 : callback_data->eb_enc_parameters.altref_strength = config->altref_strength;
233 2 : callback_data->eb_enc_parameters.altref_nframes = config->altref_nframes;
234 2 : callback_data->eb_enc_parameters.enable_overlays = (EbBool)config->enable_overlays;
235 : // --- end: ALTREF_FILTERING_SUPPORT
236 :
237 6 : for (hmeRegionIndex = 0; hmeRegionIndex < callback_data->eb_enc_parameters.number_hme_search_region_in_width; ++hmeRegionIndex) {
238 4 : callback_data->eb_enc_parameters.hme_level0_search_area_in_width_array[hmeRegionIndex] = config->hme_level0_search_area_in_width_array[hmeRegionIndex];
239 4 : callback_data->eb_enc_parameters.hme_level1_search_area_in_width_array[hmeRegionIndex] = config->hme_level1_search_area_in_width_array[hmeRegionIndex];
240 4 : callback_data->eb_enc_parameters.hme_level2_search_area_in_width_array[hmeRegionIndex] = config->hme_level2_search_area_in_width_array[hmeRegionIndex];
241 : }
242 :
243 6 : for (hmeRegionIndex = 0; hmeRegionIndex < callback_data->eb_enc_parameters.number_hme_search_region_in_height; ++hmeRegionIndex) {
244 4 : callback_data->eb_enc_parameters.hme_level0_search_area_in_height_array[hmeRegionIndex] = config->hme_level0_search_area_in_height_array[hmeRegionIndex];
245 4 : callback_data->eb_enc_parameters.hme_level1_search_area_in_height_array[hmeRegionIndex] = config->hme_level1_search_area_in_height_array[hmeRegionIndex];
246 4 : callback_data->eb_enc_parameters.hme_level2_search_area_in_height_array[hmeRegionIndex] = config->hme_level2_search_area_in_height_array[hmeRegionIndex];
247 : }
248 :
249 2 : callback_data->eb_enc_parameters.sq_weight = config->sq_weight;
250 :
251 2 : callback_data->eb_enc_parameters.md_stage_1_cand_prune_th = config->md_stage_1_cand_prune_th;
252 2 : callback_data->eb_enc_parameters.md_stage_1_class_prune_th = config->md_stage_1_class_prune_th;
253 2 : callback_data->eb_enc_parameters.md_stage_2_cand_prune_th = config->md_stage_2_cand_prune_th;
254 2 : callback_data->eb_enc_parameters.md_stage_2_class_prune_th = config->md_stage_2_class_prune_th;
255 :
256 2 : return return_error;
257 : }
258 :
259 2 : static EbErrorType AllocateFrameBuffer(EbConfig *config, uint8_t *p_buffer)
260 : {
261 2 : const int32_t tenBitPackedMode =
262 2 : (config->encoder_bit_depth > 8) &&
263 2 : (config->compressed_ten_bit_format == 0) ? 1 : 0;
264 :
265 : // Chroma subsampling
266 2 : const EbColorFormat color_format =
267 : (EbColorFormat)config->encoder_color_format;
268 2 : const uint8_t subsampling_x = (color_format == EB_YUV444 ? 1 : 2) - 1;
269 :
270 : // Determine size of each plane
271 2 : const size_t luma8bitSize = config->input_padded_width *
272 2 : config->input_padded_height * (1 << tenBitPackedMode);
273 :
274 2 : const size_t chroma8bitSize = luma8bitSize >> (3 - color_format);
275 :
276 2 : const size_t luma10bitSize =
277 0 : (config->encoder_bit_depth > 8 && tenBitPackedMode == 0) ?
278 2 : luma8bitSize : 0;
279 :
280 2 : const size_t chroma10bitSize =
281 0 : (config->encoder_bit_depth > 8 && tenBitPackedMode == 0) ?
282 2 : chroma8bitSize : 0;
283 :
284 : // Determine
285 2 : EbSvtIOFormat* inputPtr = (EbSvtIOFormat*)p_buffer;
286 2 : inputPtr->y_stride = config->input_padded_width;
287 2 : inputPtr->cr_stride = config->input_padded_width >> subsampling_x;
288 2 : inputPtr->cb_stride = config->input_padded_width >> subsampling_x;
289 :
290 2 : if (luma8bitSize) {
291 2 : EB_APP_MALLOC(uint8_t*, inputPtr->luma, luma8bitSize, EB_N_PTR,
292 : EB_ErrorInsufficientResources);
293 : } else {
294 0 : inputPtr->luma = 0;
295 : }
296 :
297 2 : if (chroma8bitSize) {
298 2 : EB_APP_MALLOC(uint8_t*, inputPtr->cb, chroma8bitSize, EB_N_PTR,
299 : EB_ErrorInsufficientResources);
300 : } else {
301 0 : inputPtr->cb = 0;
302 : }
303 :
304 2 : if (chroma8bitSize) {
305 2 : EB_APP_MALLOC(uint8_t*, inputPtr->cr, chroma8bitSize, EB_N_PTR,
306 : EB_ErrorInsufficientResources);
307 : } else {
308 0 : inputPtr->cr = 0;
309 : }
310 :
311 2 : if (luma10bitSize) {
312 0 : EB_APP_MALLOC(uint8_t*, inputPtr->luma_ext, luma10bitSize, EB_N_PTR,
313 : EB_ErrorInsufficientResources);
314 : } else {
315 2 : inputPtr->luma_ext = 0;
316 : }
317 :
318 2 : if (chroma10bitSize) {
319 0 : EB_APP_MALLOC(uint8_t*, inputPtr->cb_ext, chroma10bitSize, EB_N_PTR,
320 : EB_ErrorInsufficientResources);
321 : } else {
322 2 : inputPtr->cb_ext = 0;
323 : }
324 :
325 2 : if (chroma10bitSize) {
326 0 : EB_APP_MALLOC(uint8_t*, inputPtr->cr_ext, chroma10bitSize, EB_N_PTR,
327 : EB_ErrorInsufficientResources);
328 : } else {
329 2 : inputPtr->cr_ext = 0;
330 : }
331 :
332 2 : return EB_ErrorNone;
333 : }
334 :
335 2 : EbErrorType AllocateInputBuffers(EbConfig *config, EbAppContext *callback_data)
336 : {
337 2 : EB_APP_MALLOC(EbBufferHeaderType*, callback_data->input_buffer_pool,
338 : sizeof(EbBufferHeaderType), EB_N_PTR,
339 : EB_ErrorInsufficientResources);
340 :
341 : // Initialize Header
342 2 : callback_data->input_buffer_pool->size = sizeof(EbBufferHeaderType);
343 :
344 2 : EB_APP_MALLOC(uint8_t*, callback_data->input_buffer_pool->p_buffer,
345 : sizeof(EbSvtIOFormat), EB_N_PTR,
346 : EB_ErrorInsufficientResources);
347 :
348 : // Allocate frame buffer for the p_buffer
349 2 : if (config->buffered_input == -1)
350 2 : AllocateFrameBuffer(config, callback_data->input_buffer_pool->p_buffer);
351 :
352 : // Assign the variables
353 2 : callback_data->input_buffer_pool->p_app_private = NULL;
354 2 : callback_data->input_buffer_pool->pic_type = EB_AV1_INVALID_PICTURE;
355 :
356 2 : return EB_ErrorNone;
357 : }
358 :
359 2 : EbErrorType AllocateOutputReconBuffers(EbConfig *config,
360 : EbAppContext *callback_data)
361 : {
362 2 : const size_t luma_size =
363 2 : config->input_padded_width * config->input_padded_height;
364 :
365 : // both u and v
366 2 : const size_t chromaSize = luma_size >> (3 - config->encoder_color_format);
367 2 : const size_t tenBit = (config->encoder_bit_depth > 8);
368 2 : const size_t frameSize = (luma_size + 2 * chromaSize) << tenBit;
369 :
370 : // Recon Port
371 2 : EB_APP_MALLOC(EbBufferHeaderType*, callback_data->recon_buffer,
372 : sizeof(EbBufferHeaderType), EB_N_PTR,
373 : EB_ErrorInsufficientResources);
374 :
375 : // Initialize Header
376 2 : callback_data->recon_buffer->size = sizeof(EbBufferHeaderType);
377 :
378 2 : EB_APP_MALLOC(uint8_t*, callback_data->recon_buffer->p_buffer, frameSize,
379 : EB_N_PTR, EB_ErrorInsufficientResources);
380 :
381 2 : callback_data->recon_buffer->n_alloc_len = (uint32_t)frameSize;
382 2 : callback_data->recon_buffer->p_app_private = NULL;
383 :
384 2 : return EB_ErrorNone;
385 : }
386 :
387 2 : EbErrorType AllocateOutputBuffers(EbConfig *config, EbAppContext *callback_data)
388 : {
389 2 : uint32_t outputStreamBufferSize =
390 2 : (uint32_t)(EB_OUTPUTSTREAMBUFFERSIZE_MACRO(
391 : config->input_padded_height * config->input_padded_width));
392 :
393 2 : EB_APP_MALLOC(EbBufferHeaderType*, callback_data->stream_buffer_pool,
394 : sizeof(EbBufferHeaderType), EB_N_PTR,
395 : EB_ErrorInsufficientResources);
396 :
397 : // Initialize Header
398 2 : callback_data->stream_buffer_pool->size = sizeof(EbBufferHeaderType);
399 :
400 2 : EB_APP_MALLOC(uint8_t*, callback_data->stream_buffer_pool->p_buffer,
401 : outputStreamBufferSize, EB_N_PTR,
402 : EB_ErrorInsufficientResources);
403 :
404 2 : callback_data->stream_buffer_pool->n_alloc_len = outputStreamBufferSize;
405 2 : callback_data->stream_buffer_pool->p_app_private = NULL;
406 2 : callback_data->stream_buffer_pool->pic_type = EB_AV1_INVALID_PICTURE;
407 :
408 2 : return EB_ErrorNone;
409 : }
410 :
411 0 : EbErrorType PreloadFramesIntoRam(
412 : EbConfig *config)
413 : {
414 0 : EbErrorType return_error = EB_ErrorNone;
415 : int32_t processed_frame_count;
416 : int32_t filledLen;
417 0 : int32_t input_padded_width = config->input_padded_width;
418 0 : int32_t input_padded_height = config->input_padded_height;
419 : int32_t readSize;
420 0 : const EbColorFormat color_format =
421 : (EbColorFormat)config->encoder_color_format; // Chroma subsampling
422 :
423 0 : FILE *input_file = config->input_file;
424 :
425 0 : readSize = input_padded_width * input_padded_height; //Luma
426 0 : readSize += 2 * (readSize >> (3 - color_format)); // Add Chroma
427 0 : if (config->encoder_bit_depth == 10 && config->compressed_ten_bit_format == 1) {
428 0 : readSize += readSize / 4;
429 : } else
430 0 : readSize *= (config->encoder_bit_depth > 8 ? 2 : 1); //10 bit
431 0 : EB_APP_MALLOC(uint8_t **, config->sequence_buffer, sizeof(uint8_t*) * config->buffered_input, EB_N_PTR, EB_ErrorInsufficientResources);
432 :
433 0 : for (processed_frame_count = 0; processed_frame_count < config->buffered_input; ++processed_frame_count) {
434 0 : EB_APP_MALLOC(uint8_t*, config->sequence_buffer[processed_frame_count], readSize, EB_N_PTR, EB_ErrorInsufficientResources);
435 : // Interlaced Video
436 0 : if (config->separate_fields) {
437 0 : EbBool is16bit = config->encoder_bit_depth > 8;
438 0 : if (is16bit == 0 || (is16bit == 1 && config->compressed_ten_bit_format == 0)) {
439 0 : const int32_t tenBitPackedMode = (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0;
440 :
441 0 : const size_t luma8bitSize =
442 :
443 0 : (config->input_padded_width) *
444 0 : (config->input_padded_height) *
445 :
446 : (1 << tenBitPackedMode);
447 :
448 0 : const size_t chroma8bitSize = luma8bitSize >> 2;
449 :
450 0 : filledLen = 0;
451 :
452 0 : ProcessInputFieldBufferingMode(
453 : processed_frame_count,
454 : &filledLen,
455 : input_file,
456 0 : config->sequence_buffer[processed_frame_count],
457 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize,
458 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + chroma8bitSize,
459 : (uint32_t)input_padded_width,
460 : (uint32_t)input_padded_height,
461 : is16bit);
462 :
463 0 : if (readSize != filledLen) {
464 0 : fseek(input_file, 0, SEEK_SET);
465 0 : filledLen = 0;
466 :
467 0 : ProcessInputFieldBufferingMode(
468 : processed_frame_count,
469 : &filledLen,
470 : input_file,
471 0 : config->sequence_buffer[processed_frame_count],
472 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize,
473 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + chroma8bitSize,
474 : (uint32_t)input_padded_width,
475 : (uint32_t)input_padded_height,
476 : is16bit);
477 : }
478 :
479 : // Reset the pointer position after a top field
480 0 : if (processed_frame_count % 2 == 0)
481 0 : fseek(input_file, -(long)(readSize << 1), SEEK_CUR);
482 : }
483 : // Unpacked 10 bit
484 : else {
485 0 : const int32_t tenBitPackedMode = (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0;
486 :
487 0 : const size_t luma8bitSize =
488 0 : (config->input_padded_width) *
489 0 : (config->input_padded_height) *
490 : (1 << tenBitPackedMode);
491 :
492 0 : const size_t chroma8bitSize = luma8bitSize >> 2;
493 :
494 0 : const size_t luma10bitSize = (config->encoder_bit_depth > 8 && tenBitPackedMode == 0) ? luma8bitSize : 0;
495 0 : const size_t chroma10bitSize = (config->encoder_bit_depth > 8 && tenBitPackedMode == 0) ? chroma8bitSize : 0;
496 :
497 0 : filledLen = 0;
498 :
499 0 : ProcessInputFieldBufferingMode(
500 : processed_frame_count,
501 : &filledLen,
502 : input_file,
503 0 : config->sequence_buffer[processed_frame_count],
504 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize,
505 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + chroma8bitSize,
506 : (uint32_t)input_padded_width,
507 : (uint32_t)input_padded_height,
508 : 0);
509 :
510 0 : ProcessInputFieldBufferingMode(
511 : processed_frame_count,
512 : &filledLen,
513 : input_file,
514 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + (chroma8bitSize << 1),
515 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + (chroma8bitSize << 1) + luma10bitSize,
516 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + (chroma8bitSize << 1) + luma10bitSize + chroma10bitSize,
517 : (uint32_t)input_padded_width,
518 : (uint32_t)input_padded_height,
519 : 0);
520 :
521 0 : if (readSize != filledLen) {
522 0 : fseek(input_file, 0, SEEK_SET);
523 0 : filledLen = 0;
524 :
525 0 : ProcessInputFieldBufferingMode(
526 : processed_frame_count,
527 : &filledLen,
528 : input_file,
529 0 : config->sequence_buffer[processed_frame_count],
530 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize,
531 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + chroma8bitSize,
532 : (uint32_t)input_padded_width,
533 : (uint32_t)input_padded_height,
534 : 0);
535 :
536 0 : ProcessInputFieldBufferingMode(
537 : processed_frame_count,
538 : &filledLen,
539 : input_file,
540 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + (chroma8bitSize << 1),
541 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + (chroma8bitSize << 1) + luma10bitSize,
542 0 : config->sequence_buffer[processed_frame_count] + luma8bitSize + (chroma8bitSize << 1) + luma10bitSize + chroma10bitSize,
543 : (uint32_t)input_padded_width,
544 : (uint32_t)input_padded_height,
545 : 0);
546 : }
547 :
548 : // Reset the pointer position after a top field
549 0 : if (processed_frame_count % 2 == 0)
550 0 : fseek(input_file, -(long)(readSize << 1), SEEK_CUR);
551 : }
552 : } else {
553 : // Fill the buffer with a complete frame
554 0 : filledLen = 0;
555 0 : filledLen += (uint32_t)fread(config->sequence_buffer[processed_frame_count], 1, readSize, input_file);
556 :
557 0 : if (readSize != filledLen) {
558 0 : fseek(config->input_file, 0, SEEK_SET);
559 :
560 : // Fill the buffer with a complete frame
561 0 : filledLen = 0;
562 0 : filledLen += (uint32_t)fread(config->sequence_buffer[processed_frame_count], 1, readSize, input_file);
563 : }
564 : }
565 : }
566 :
567 0 : return return_error;
568 : }
569 :
570 : /***************************************
571 : * Functions Implementation
572 : ***************************************/
573 :
574 : /***********************************
575 : * Initialize Core & Component
576 : ***********************************/
577 2 : EbErrorType init_encoder(
578 : EbConfig *config,
579 : EbAppContext *callback_data,
580 : uint32_t instance_idx)
581 : {
582 2 : EbErrorType return_error = EB_ErrorNone;
583 :
584 : // Allocate a memory table hosting all allocated pointers
585 2 : AllocateMemoryTable(instance_idx);
586 :
587 : ///************************* LIBRARY INIT [START] *********************///
588 : // STEP 1: Call the library to construct a Component Handle
589 2 : return_error = eb_init_handle(&callback_data->svt_encoder_handle, callback_data, &callback_data->eb_enc_parameters);
590 :
591 2 : if (return_error != EB_ErrorNone)
592 0 : return return_error;
593 : // STEP 3: Copy all configuration parameters into the callback structure
594 2 : return_error = CopyConfigurationParameters(
595 : config,
596 : callback_data,
597 : instance_idx);
598 :
599 2 : if (return_error != EB_ErrorNone)
600 0 : return return_error;
601 : // STEP 4: Send over all configuration parameters
602 : // Set the Parameters
603 2 : return_error = eb_svt_enc_set_parameter(
604 : callback_data->svt_encoder_handle,
605 : &callback_data->eb_enc_parameters);
606 :
607 2 : if (return_error != EB_ErrorNone)
608 0 : return return_error;
609 : // STEP 5: Init Encoder
610 2 : return_error = eb_init_encoder(callback_data->svt_encoder_handle);
611 2 : if (return_error != EB_ErrorNone) { return return_error; }
612 :
613 : ///************************* LIBRARY INIT [END] *********************///
614 :
615 : ///********************** APPLICATION INIT [START] ******************///
616 :
617 : // STEP 6: Allocate input buffers carrying the yuv frames in
618 2 : return_error = AllocateInputBuffers(config, callback_data);
619 :
620 2 : if (return_error != EB_ErrorNone)
621 0 : return return_error;
622 : // STEP 7: Allocate output buffers carrying the bitstream out
623 2 : return_error = AllocateOutputBuffers(
624 : config,
625 : callback_data);
626 :
627 2 : if (return_error != EB_ErrorNone)
628 0 : return return_error;
629 : // STEP 8: Allocate output Recon Buffer
630 2 : return_error = AllocateOutputReconBuffers(
631 : config,
632 : callback_data);
633 :
634 2 : if (return_error != EB_ErrorNone)
635 0 : return return_error;
636 : // Allocate the Sequence Buffer
637 2 : if (config->buffered_input != -1) {
638 : // Preload frames into the ram for a faster yuv access time
639 0 : PreloadFramesIntoRam(
640 : config);
641 : }
642 : else
643 2 : config->sequence_buffer = 0;
644 2 : if (return_error != EB_ErrorNone)
645 0 : return return_error;
646 : ///********************** APPLICATION INIT [END] ******************////////
647 :
648 2 : return return_error;
649 : }
650 :
651 : /***********************************
652 : * Deinit Components
653 : ***********************************/
654 2 : EbErrorType de_init_encoder(
655 : EbAppContext *callback_data_ptr,
656 : uint32_t instance_index)
657 : {
658 2 : EbErrorType return_error = EB_ErrorNone;
659 2 : int32_t ptrIndex = 0;
660 2 : EbMemoryMapEntry* memory_entry = (EbMemoryMapEntry*)0;
661 :
662 2 : if (((EbComponentType*)(callback_data_ptr->svt_encoder_handle)) != NULL)
663 2 : return_error = eb_deinit_encoder(callback_data_ptr->svt_encoder_handle);
664 : // Destruct the buffer memory pool
665 2 : if (return_error != EB_ErrorNone)
666 0 : return return_error;
667 : // Loop through the ptr table and free all malloc'd pointers per channel
668 20 : for (ptrIndex = appMemoryMapIndexAllChannels[instance_index] - 1; ptrIndex >= 0; --ptrIndex) {
669 18 : memory_entry = &appMemoryMapAllChannels[instance_index][ptrIndex];
670 18 : switch (memory_entry->ptr_type) {
671 18 : case EB_N_PTR:
672 18 : free(memory_entry->ptr);
673 18 : break;
674 0 : default:
675 0 : return_error = EB_ErrorMax;
676 0 : break;
677 : }
678 : }
679 2 : free(appMemoryMapAllChannels[instance_index]);
680 :
681 : // Destruct the component
682 2 : eb_deinit_handle(callback_data_ptr->svt_encoder_handle);
683 :
684 2 : return return_error;
685 : }
|