Coverage Report

Created: 2026-09-01 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/libde265/libde265/de265.cc
Line
Count
Source
1
/*
2
 * H.265 video codec.
3
 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
4
 *
5
 * This file is part of libde265.
6
 *
7
 * libde265 is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libde265 is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libde265.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#define DEBUG_INSERT_STREAM_ERRORS 0
22
23
24
#include "de265.h"
25
#include "decctx.h"
26
#include "util.h"
27
#include "scan.h"
28
#include "image.h"
29
#include "sei.h"
30
31
#include <assert.h>
32
#include <string.h>
33
#include <stdlib.h>
34
#include <mutex>
35
36
37
// TODO: should be in some vps.c related header
38
de265_error read_vps(decoder_context* ctx, bitreader* reader, video_parameter_set* vps);
39
40
extern "C" {
41
LIBDE265_API const char *de265_get_version(void)
42
0
{
43
0
    return (LIBDE265_VERSION);
44
0
}
45
46
LIBDE265_API uint32_t de265_get_version_number(void)
47
0
{
48
0
    return (LIBDE265_NUMERIC_VERSION);
49
0
}
50
51
static uint8_t bcd2dec(uint8_t v)
52
0
{
53
0
  return (v>>4) * 10 + (v & 0x0F);
54
0
}
55
56
LIBDE265_API int de265_get_version_number_major(void)
57
0
{
58
0
  return bcd2dec(((LIBDE265_NUMERIC_VERSION)>>24) & 0xFF);
59
0
}
60
61
LIBDE265_API int de265_get_version_number_minor(void)
62
0
{
63
0
  return bcd2dec(((LIBDE265_NUMERIC_VERSION)>>16) & 0xFF);
64
0
}
65
66
LIBDE265_API int de265_get_version_number_maintenance(void)
67
0
{
68
0
  return bcd2dec(((LIBDE265_NUMERIC_VERSION)>>8) & 0xFF);
69
0
}
70
71
72
LIBDE265_API const char* de265_get_error_text(de265_error err)
73
0
{
74
0
  switch (err) {
75
0
  case DE265_OK: return "no error";
76
0
  case DE265_ERROR_NO_SUCH_FILE: return "no such file";
77
    //case DE265_ERROR_NO_STARTCODE: return "no startcode found";
78
    //case DE265_ERROR_EOF: return "end of file";
79
0
  case DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS: return "coefficient out of image bounds";
80
0
  case DE265_ERROR_CHECKSUM_MISMATCH: return "image checksum mismatch";
81
0
  case DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA: return "CTB outside of image area";
82
0
  case DE265_ERROR_OUT_OF_MEMORY: return "out of memory";
83
0
  case DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE: return "coded parameter out of range";
84
0
  case DE265_ERROR_IMAGE_BUFFER_FULL: return "DPB/output queue full";
85
0
  case DE265_ERROR_IMAGE_SIZE_EXCEEDS_SECURITY_LIMIT: return "image size exceeds security limit";
86
0
  case DE265_ERROR_NAL_SIZE_EXCEEDS_SECURITY_LIMIT: return "NAL unit size exceeds security limit";
87
0
  case DE265_ERROR_INVALID_ARGUMENT: return "invalid argument";
88
0
  case DE265_ERROR_CANNOT_START_THREADPOOL: return "cannot start decoding threads";
89
0
  case DE265_ERROR_LIBRARY_INITIALIZATION_FAILED: return "global library initialization failed";
90
0
  case DE265_ERROR_LIBRARY_NOT_INITIALIZED: return "cannot free library data (not initialized";
91
92
  //case DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED:
93
  //  return "internal error: maximum number of thread contexts exceeded";
94
  //case DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED:
95
  //  return "internal error: maximum number of slices exceeded";
96
0
  case DE265_ERROR_NOT_IMPLEMENTED_YET:
97
0
    return "unimplemented decoder feature";
98
    //case DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED:
99
    //return "scaling list not implemented";
100
101
0
  case DE265_ERROR_WAITING_FOR_INPUT_DATA:
102
0
    return "no more input data, decoder stalled";
103
0
  case DE265_ERROR_CANNOT_PROCESS_SEI:
104
0
    return "SEI data cannot be processed";
105
0
  case DE265_ERROR_PARAMETER_PARSING:
106
0
    return "command-line parameter error";
107
0
  case DE265_ERROR_NO_INITIAL_SLICE_HEADER:
108
0
    return "first slice missing, cannot decode dependent slice";
109
0
  case DE265_ERROR_PREMATURE_END_OF_SLICE:
110
0
    return "premature end of slice data";
111
0
  case DE265_ERROR_UNSPECIFIED_DECODING_ERROR:
112
0
    return "unspecified decoding error";
113
114
0
  case DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING:
115
0
    return "Cannot run decoder multi-threaded because stream does not support WPP";
116
0
  case DE265_WARNING_WARNING_BUFFER_FULL:
117
0
    return "Too many warnings queued";
118
0
  case DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT:
119
0
    return "Premature end of slice segment";
120
0
  case DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET:
121
0
    return "Incorrect entry-point offsets";
122
0
  case DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA:
123
0
    return "CTB outside of image area (concealing stream error...)";
124
0
  case DE265_WARNING_SPS_HEADER_INVALID:
125
0
    return "sps header invalid";
126
0
  case DE265_WARNING_PPS_HEADER_INVALID:
127
0
    return "pps header invalid";
128
0
  case DE265_WARNING_SLICEHEADER_INVALID:
129
0
    return "slice header invalid";
130
0
  case DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING:
131
0
    return "impossible motion vector scaling";
132
0
  case DE265_WARNING_NONEXISTING_PPS_REFERENCED:
133
0
    return "non-existing PPS referenced";
134
0
  case DE265_WARNING_NONEXISTING_SPS_REFERENCED:
135
0
    return "non-existing SPS referenced";
136
0
  case DE265_WARNING_BOTH_PREDFLAGS_ZERO:
137
0
    return "both predFlags[] are zero in MC";
138
0
  case DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED:
139
0
    return "non-existing reference picture accessed";
140
0
  case DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ:
141
0
    return "numMV_P != numMV_Q in deblocking";
142
0
  case DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE:
143
0
    return "number of short-term ref-pic-sets out of range";
144
0
  case DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE:
145
0
    return "short-term ref-pic-set index out of range";
146
0
  case DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST:
147
0
    return "faulty reference picture list";
148
0
  case DE265_WARNING_EOSS_BIT_NOT_SET:
149
0
    return "end_of_sub_stream_one_bit not set to 1 when it should be";
150
0
  case DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED:
151
0
    return "maximum number of reference pictures exceeded";
152
0
  case DE265_WARNING_INVALID_CHROMA_FORMAT:
153
0
    return "invalid chroma format in SPS header";
154
0
  case DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID:
155
0
    return "slice segment address invalid";
156
0
  case DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO:
157
0
    return "dependent slice with address 0";
158
0
  case DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM:
159
0
    return "number of threads limited to maximum amount";
160
0
  case DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER:
161
0
    return "non-existing long-term reference candidate specified in slice header";
162
0
  case DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY:
163
0
    return "cannot apply SAO because we ran out of memory";
164
0
  case DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI:
165
0
    return "SPS header missing, cannot decode SEI";
166
0
  case DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA:
167
0
    return "collocated motion-vector is outside image area";
168
0
  case DE265_WARNING_PCM_BITDEPTH_TOO_LARGE:
169
0
    return "PCM bit-depth too large";
170
0
  case DE265_WARNING_REFERENCE_IMAGE_BIT_DEPTH_DOES_NOT_MATCH:
171
0
    return "Bit-depth of reference image does not match current image";
172
0
  case DE265_WARNING_REFERENCE_IMAGE_SIZE_DOES_NOT_MATCH_SPS:
173
0
    return "Size of reference image does not match current size in SPS";
174
0
  case DE265_WARNING_CHROMA_OF_CURRENT_IMAGE_DOES_NOT_MATCH_SPS:
175
0
    return "Chroma format of current image does not match chroma in SPS";
176
0
  case DE265_WARNING_BIT_DEPTH_OF_CURRENT_IMAGE_DOES_NOT_MATCH_SPS:
177
0
    return "Bit-depth of current image does not match SPS";
178
0
  case DE265_WARNING_REFERENCE_IMAGE_CHROMA_FORMAT_DOES_NOT_MATCH:
179
0
    return "Chroma format of reference image does not match current image";
180
0
  case DE265_WARNING_INVALID_SLICE_HEADER_INDEX_ACCESS:
181
0
    return "Access with invalid slice header index";
182
0
  case DE265_WARNING_INVALID_TU_BLOCK_SPLIT:
183
0
    return "Transform block split below minimum transform size";
184
0
  case DE265_WARNING_RICE_PARAMETER_OUT_OF_RANGE:
185
0
    return "Rice parameter or StatCoeff out of range, clamped";
186
0
  case DE265_WARNING_MAX_NUMBER_OF_SEI_MESSAGES_EXCEEDED:
187
0
    return "number of SEI messages exceeds security limit, dropped";
188
189
0
  default: return "unknown error";
190
0
  }
191
0
}
192
193
LIBDE265_API int de265_isOK(de265_error err)
194
68.0k
{
195
68.0k
  return err == DE265_OK || err >= 1000;
196
68.0k
}
197
198
199
200
static int de265_init_count;
201
202
static std::mutex& de265_init_mutex()
203
136k
{
204
136k
  static std::mutex de265_init_mutex;
205
136k
  return de265_init_mutex;
206
136k
}
207
208
209
LIBDE265_API de265_error de265_init()
210
68.0k
{
211
68.0k
  std::lock_guard<std::mutex> lock(de265_init_mutex());
212
213
68.0k
  de265_init_count++;
214
215
68.0k
  if (de265_init_count > 1) {
216
    // we are not the first -> already initialized
217
218
68.0k
    return DE265_OK;
219
68.0k
  }
220
221
222
  // do initializations
223
224
11
  init_scan_orders();
225
11
  pps_scan_cache_init();
226
227
11
  if (!alloc_and_init_significant_coeff_ctxIdx_lookupTable()) {
228
0
    pps_scan_cache_free();
229
0
    de265_init_count--;
230
0
    return DE265_ERROR_LIBRARY_INITIALIZATION_FAILED;
231
0
  }
232
233
11
  return DE265_OK;
234
11
}
235
236
LIBDE265_API de265_error de265_free()
237
68.0k
{
238
68.0k
  std::lock_guard<std::mutex> lock(de265_init_mutex());
239
240
68.0k
  if (de265_init_count<=0) {
241
0
    return DE265_ERROR_LIBRARY_NOT_INITIALIZED;
242
0
  }
243
244
68.0k
  de265_init_count--;
245
246
68.0k
  if (de265_init_count==0) {
247
2
    free_significant_coeff_ctxIdx_lookupTable();
248
2
    pps_scan_cache_free();
249
2
  }
250
251
68.0k
  return DE265_OK;
252
68.0k
}
253
254
255
LIBDE265_API de265_decoder_context* de265_new_decoder()
256
68.0k
{
257
68.0k
  de265_error init_err = de265_init();
258
68.0k
  if (init_err != DE265_OK) {
259
0
    return nullptr;
260
0
  }
261
262
68.0k
  decoder_context* ctx = new decoder_context;
263
68.0k
  if (!ctx) {
264
0
    de265_free();
265
0
    return nullptr;
266
0
  }
267
268
68.0k
  return reinterpret_cast<de265_decoder_context*>(ctx);
269
68.0k
}
270
271
272
LIBDE265_API de265_error de265_free_decoder(de265_decoder_context* de265ctx)
273
68.0k
{
274
68.0k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
275
276
68.0k
  ctx->stop_thread_pool();
277
278
68.0k
  delete ctx;
279
280
68.0k
  return de265_free();
281
68.0k
}
282
283
284
LIBDE265_API de265_error de265_start_worker_threads(de265_decoder_context* de265ctx, int number_of_threads)
285
68.0k
{
286
68.0k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
287
288
68.0k
  if (number_of_threads > MAX_THREADS) {
289
0
    number_of_threads = MAX_THREADS;
290
0
  }
291
292
68.0k
  if (number_of_threads>0) {
293
68.0k
    de265_error err = ctx->start_thread_pool(number_of_threads);
294
68.0k
    if (de265_isOK(err)) {
295
68.0k
      err = DE265_OK;
296
68.0k
    }
297
68.0k
    return err;
298
68.0k
  }
299
1
  else {
300
1
    return DE265_OK;
301
1
  }
302
68.0k
}
303
304
305
#ifndef LIBDE265_DISABLE_DEPRECATED
306
LIBDE265_API de265_error de265_decode_data(de265_decoder_context* de265ctx,
307
                                           const void* data8, int len)
308
0
{
309
  //decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
310
0
  de265_error err;
311
0
  if (len > 0) {
312
0
    err = de265_push_data(de265ctx, data8, len, 0, nullptr);
313
0
  } else {
314
0
    err = de265_flush_data(de265ctx);
315
0
  }
316
0
  if (err != DE265_OK) {
317
0
    return err;
318
0
  }
319
320
0
  int more = 0;
321
0
  do {
322
0
    err = de265_decode(de265ctx, &more);
323
0
    if (err != DE265_OK) {
324
0
        more = 0;
325
0
    }
326
327
0
    switch (err) {
328
0
    case DE265_ERROR_WAITING_FOR_INPUT_DATA:
329
      // ignore error (didn't exist in 0.4 and before)
330
0
      err = DE265_OK;
331
0
      break;
332
0
    default:
333
0
      break;
334
0
    }
335
0
  } while (more);
336
0
  return err;
337
0
}
338
#endif
339
340
#if 0
341
static void dumpdata(const void* data, int len)
342
{
343
  for (int i=0;i<len;i++) {
344
    printf("%02x ", ((uint8_t*)data)[i]);
345
  }
346
  printf("\n");
347
}
348
#endif
349
350
351
LIBDE265_API de265_error de265_push_data(de265_decoder_context* de265ctx,
352
                                         const void* data8, int len,
353
                                         de265_PTS pts, void* user_data)
354
0
{
355
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
356
0
  const uint8_t* data = reinterpret_cast<const uint8_t*>(data8);
357
358
  //printf("push data (size %d)\n",len);
359
  //dumpdata(data8,16);
360
361
0
  return ctx->nal_parser.push_data(data,len,pts,user_data);
362
0
}
363
364
365
LIBDE265_API de265_error de265_push_NAL(de265_decoder_context* de265ctx,
366
                                        const void* data8, int len,
367
                                        de265_PTS pts, void* user_data)
368
489k
{
369
489k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
370
489k
  const uint8_t* data = reinterpret_cast<const uint8_t*>(data8);
371
372
  //printf("push NAL (size %d)\n",len);
373
  //dumpdata(data8,16);
374
375
489k
  return ctx->nal_parser.push_NAL(data,len,pts,user_data);
376
489k
}
377
378
379
LIBDE265_API de265_error de265_decode(de265_decoder_context* de265ctx, int* more)
380
736k
{
381
736k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
382
383
736k
  return ctx->decode(more);
384
736k
}
385
386
387
LIBDE265_API void        de265_push_end_of_NAL(de265_decoder_context* de265ctx)
388
28.5k
{
389
28.5k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
390
391
28.5k
  ctx->nal_parser.flush_data();
392
28.5k
}
393
394
395
LIBDE265_API void        de265_push_end_of_frame(de265_decoder_context* de265ctx)
396
0
{
397
0
  de265_push_end_of_NAL(de265ctx);
398
399
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
400
0
  ctx->nal_parser.mark_end_of_frame();
401
0
}
402
403
404
LIBDE265_API de265_error de265_flush_data(de265_decoder_context* de265ctx)
405
28.5k
{
406
28.5k
  de265_push_end_of_NAL(de265ctx);
407
408
28.5k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
409
410
28.5k
  ctx->nal_parser.flush_data();
411
28.5k
  ctx->nal_parser.mark_end_of_stream();
412
413
28.5k
  return DE265_OK;
414
28.5k
}
415
416
417
LIBDE265_API void de265_reset(de265_decoder_context* de265ctx)
418
0
{
419
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
420
421
  //printf("--- reset ---\n");
422
423
0
  ctx->reset();
424
0
}
425
426
427
LIBDE265_API const struct de265_image* de265_get_next_picture(de265_decoder_context* de265ctx)
428
705k
{
429
705k
  const struct de265_image* img = de265_peek_next_picture(de265ctx);
430
705k
  if (img) {
431
15.5k
    de265_release_next_picture(de265ctx);
432
15.5k
  }
433
434
705k
  return img;
435
705k
}
436
437
438
LIBDE265_API const struct de265_image* de265_peek_next_picture(de265_decoder_context* de265ctx)
439
705k
{
440
705k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
441
442
705k
  if (ctx->num_pictures_in_output_queue()>0) {
443
15.5k
    de265_image* img = ctx->get_next_picture_in_output_queue();
444
15.5k
    return img;
445
15.5k
  }
446
689k
  else {
447
689k
    return nullptr;
448
689k
  }
449
705k
}
450
451
452
LIBDE265_API void de265_release_next_picture(de265_decoder_context* de265ctx)
453
23.7k
{
454
23.7k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
455
456
  // no active output picture -> ignore release request
457
458
23.7k
  if (ctx->num_pictures_in_output_queue()==0) { return; }
459
460
15.6k
  de265_image* next_image = ctx->get_next_picture_in_output_queue();
461
462
15.6k
  loginfo(LogDPB, "release DPB with POC=%d\n",next_image->PicOrderCntVal);
463
464
15.6k
  next_image->PicOutputFlag = false;
465
466
  // TODO: actually, we want to release it here, but we cannot without breaking API
467
  // compatibility, because get_next_picture calls this immediately. Hence, we release
468
  // images while scanning for available slots in the DPB.
469
  // if (next_image->can_be_released()) { next_image->release(); }
470
471
  // pop output queue
472
473
15.6k
  ctx->pop_next_picture_in_output_queue();
474
15.6k
}
475
476
477
478
LIBDE265_API int  de265_get_highest_TID(de265_decoder_context* de265ctx)
479
0
{
480
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
481
0
  return ctx->get_highest_TID();
482
0
}
483
484
LIBDE265_API int  de265_get_current_TID(de265_decoder_context* de265ctx)
485
0
{
486
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
487
0
  return ctx->get_current_TID();
488
0
}
489
490
LIBDE265_API void de265_set_limit_TID(de265_decoder_context* de265ctx,int max_tid)
491
0
{
492
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
493
0
  ctx->set_limit_TID(max_tid);
494
0
}
495
496
LIBDE265_API void de265_set_framerate_ratio(de265_decoder_context* de265ctx,int percent)
497
0
{
498
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
499
0
  ctx->set_framerate_ratio(percent);
500
0
}
501
502
LIBDE265_API int  de265_change_framerate(de265_decoder_context* de265ctx,int more)
503
0
{
504
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
505
0
  return ctx->change_framerate(more);
506
0
}
507
508
509
LIBDE265_API de265_error de265_get_warning(de265_decoder_context* de265ctx)
510
0
{
511
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
512
513
0
  return ctx->get_warning();
514
0
}
515
516
LIBDE265_API void de265_set_parameter_bool(de265_decoder_context* de265ctx, enum de265_param param, int value)
517
0
{
518
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
519
520
0
  switch (param)
521
0
    {
522
0
    case DE265_DECODER_PARAM_BOOL_SEI_CHECK_HASH:
523
0
      ctx->param_sei_check_hash = !!value;
524
0
      break;
525
526
0
    case DE265_DECODER_PARAM_SUPPRESS_FAULTY_PICTURES:
527
0
      ctx->param_suppress_faulty_pictures = !!value;
528
0
      break;
529
530
0
    case DE265_DECODER_PARAM_DISABLE_DEBLOCKING:
531
0
      ctx->param_disable_deblocking = !!value;
532
0
      break;
533
534
0
    case DE265_DECODER_PARAM_DISABLE_SAO:
535
0
      ctx->param_disable_sao = !!value;
536
0
      break;
537
538
      /*
539
    case DE265_DECODER_PARAM_DISABLE_MC_RESIDUAL_IDCT:
540
      ctx->param_disable_mc_residual_idct = !!value;
541
      break;
542
543
    case DE265_DECODER_PARAM_DISABLE_INTRA_RESIDUAL_IDCT:
544
      ctx->param_disable_intra_residual_idct = !!value;
545
      break;
546
      */
547
548
0
    default:
549
0
      assert(false);
550
0
      break;
551
0
    }
552
0
}
553
554
555
LIBDE265_API void de265_set_parameter_int(de265_decoder_context* de265ctx, enum de265_param param, int value)
556
0
{
557
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
558
559
0
  switch (param)
560
0
    {
561
0
    case DE265_DECODER_PARAM_DUMP_SPS_HEADERS:
562
0
      ctx->param_sps_headers_fd = value;
563
0
      break;
564
565
0
    case DE265_DECODER_PARAM_DUMP_VPS_HEADERS:
566
0
      ctx->param_vps_headers_fd = value;
567
0
      break;
568
569
0
    case DE265_DECODER_PARAM_DUMP_PPS_HEADERS:
570
0
      ctx->param_pps_headers_fd = value;
571
0
      break;
572
573
0
    case DE265_DECODER_PARAM_DUMP_SLICE_HEADERS:
574
0
      ctx->param_slice_headers_fd = value;
575
0
      break;
576
577
0
    case DE265_DECODER_PARAM_ACCELERATION_CODE:
578
0
      ctx->set_acceleration_functions(static_cast<enum de265_acceleration>(value));
579
0
      break;
580
581
0
    default:
582
0
      assert(false);
583
0
      break;
584
0
    }
585
0
}
586
587
588
589
590
LIBDE265_API int de265_get_parameter_bool(de265_decoder_context* de265ctx, enum de265_param param)
591
0
{
592
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
593
594
0
  switch (param)
595
0
    {
596
0
    case DE265_DECODER_PARAM_BOOL_SEI_CHECK_HASH:
597
0
      return ctx->param_sei_check_hash;
598
599
0
    case DE265_DECODER_PARAM_SUPPRESS_FAULTY_PICTURES:
600
0
      return ctx->param_suppress_faulty_pictures;
601
602
0
    case DE265_DECODER_PARAM_DISABLE_DEBLOCKING:
603
0
      return ctx->param_disable_deblocking;
604
605
0
    case DE265_DECODER_PARAM_DISABLE_SAO:
606
0
      return ctx->param_disable_sao;
607
608
      /*
609
    case DE265_DECODER_PARAM_DISABLE_MC_RESIDUAL_IDCT:
610
      return ctx->param_disable_mc_residual_idct;
611
612
    case DE265_DECODER_PARAM_DISABLE_INTRA_RESIDUAL_IDCT:
613
      return ctx->param_disable_intra_residual_idct;
614
      */
615
616
0
    default:
617
0
      assert(false);
618
0
      return false;
619
0
    }
620
0
}
621
622
623
static const de265_security_limits disabled_security_limits = {
624
  1,    // version
625
  0,    // max_image_size_pixels
626
  0,    // max_NAL_size_bytes
627
  0     // max_SEI_messages
628
};
629
630
631
LIBDE265_API de265_security_limits* de265_get_security_limits(de265_decoder_context* de265ctx)
632
68.0k
{
633
68.0k
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
634
68.0k
  return &ctx->param_security_limits;
635
68.0k
}
636
637
638
// Copy security limits field by field, but only those fields that exist in both
639
// structs, i.e. up to min(dst->version, src->version). This keeps copying safe
640
// when 'src' was compiled against a different (older or newer) header version
641
// than 'dst'. Fields not covered by the common version keep their value in 'dst'.
642
static void copy_security_limits(de265_security_limits* dst, const de265_security_limits* src)
643
0
{
644
0
  uint8_t version = (dst->version < src->version) ? dst->version : src->version;
645
646
0
  if (version >= 1) {
647
0
    dst->max_image_size_pixels = src->max_image_size_pixels;
648
0
    dst->max_NAL_size_bytes    = src->max_NAL_size_bytes;
649
0
    dst->max_SEI_messages      = src->max_SEI_messages;
650
0
  }
651
0
}
652
653
654
LIBDE265_API void de265_set_security_limits(de265_decoder_context* de265ctx,
655
                                            const de265_security_limits* limits)
656
0
{
657
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
658
0
  if (limits) {
659
0
    copy_security_limits(&ctx->param_security_limits, limits);
660
0
  }
661
0
}
662
663
664
LIBDE265_API const de265_security_limits* de265_get_disabled_security_limits()
665
0
{
666
0
  return &disabled_security_limits;
667
0
}
668
669
670
LIBDE265_API int de265_get_number_of_input_bytes_pending(de265_decoder_context* de265ctx)
671
0
{
672
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
673
674
0
  return ctx->nal_parser.bytes_in_input_queue();
675
0
}
676
677
678
LIBDE265_API int de265_get_number_of_NAL_units_pending(de265_decoder_context* de265ctx)
679
0
{
680
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
681
682
0
  return ctx->nal_parser.number_of_NAL_units_pending();
683
0
}
684
685
686
LIBDE265_API int de265_get_image_width(const struct de265_image* img,int channel)
687
47.2k
{
688
47.2k
  switch (channel) {
689
31.1k
  case 0:
690
31.1k
    return img->width_confwin;
691
8.05k
  case 1:
692
16.1k
  case 2:
693
16.1k
    return img->chroma_width_confwin;
694
0
  default:
695
0
    return 0;
696
47.2k
  }
697
47.2k
}
698
699
LIBDE265_API int de265_get_image_height(const struct de265_image* img,int channel)
700
47.2k
{
701
47.2k
  switch (channel) {
702
31.1k
  case 0:
703
31.1k
    return img->height_confwin;
704
8.05k
  case 1:
705
16.1k
  case 2:
706
16.1k
    return img->chroma_height_confwin;
707
0
  default:
708
0
    return 0;
709
47.2k
  }
710
47.2k
}
711
712
LIBDE265_API int de265_get_bits_per_pixel(const struct de265_image* img,int channel)
713
86.4k
{
714
86.4k
  switch (channel) {
715
46.7k
  case 0:
716
46.7k
    return img->get_sps().BitDepth_Y;
717
23.5k
  case 1:
718
39.6k
  case 2:
719
39.6k
    return img->get_sps().BitDepth_C;
720
0
  default:
721
0
    return 0;
722
86.4k
  }
723
86.4k
}
724
725
LIBDE265_API enum de265_chroma de265_get_chroma_format(const struct de265_image* img)
726
31.1k
{
727
31.1k
  return img->get_chroma_format();
728
31.1k
}
729
730
LIBDE265_API const uint8_t* de265_get_image_plane(const de265_image* img, int channel, int* stride)
731
31.6k
{
732
31.6k
  assert(channel>=0 && channel <= 2);
733
734
31.6k
  uint8_t* data = img->pixels_confwin[channel];
735
736
31.6k
  if (stride) *stride = static_cast<int>(img->get_image_stride(channel) * ((de265_get_bits_per_pixel(img, channel)+7) / 8));
737
738
31.6k
  return data;
739
31.6k
}
740
741
LIBDE265_API void *de265_get_image_plane_user_data(const struct de265_image* img, int channel)
742
0
{
743
0
  assert(channel>=0 && channel <= 2);
744
745
0
  return img->plane_user_data[channel];
746
0
}
747
748
LIBDE265_API void de265_set_image_plane(de265_image* img, int cIdx, void* mem, int stride, void *userdata)
749
0
{
750
  // The internal "stride" is the number of pixels per line.
751
0
  stride = stride / ((de265_get_bits_per_pixel(img, cIdx)+7) / 8);
752
0
  img->set_image_plane(cIdx, static_cast<uint8_t*>(mem), stride, userdata);
753
0
}
754
755
LIBDE265_API void de265_set_image_allocation_functions(de265_decoder_context* de265ctx,
756
                                                       de265_image_allocation* allocfunc,
757
                                                       void* userdata)
758
0
{
759
0
  decoder_context* ctx = reinterpret_cast<decoder_context*>(de265ctx);
760
761
0
  ctx->set_image_allocation_functions(allocfunc, userdata);
762
0
}
763
764
LIBDE265_API const struct de265_image_allocation *de265_get_default_image_allocation_functions(void)
765
0
{
766
0
  return &de265_image::default_image_allocation;
767
0
}
768
769
LIBDE265_API de265_PTS de265_get_image_PTS(const struct de265_image* img)
770
0
{
771
0
  return img->pts;
772
0
}
773
774
LIBDE265_API void* de265_get_image_user_data(const struct de265_image* img)
775
0
{
776
0
  return img->user_data;
777
0
}
778
779
LIBDE265_API void de265_set_image_user_data(struct de265_image* img, void *user_data)
780
0
{
781
0
  img->user_data = user_data;
782
0
}
783
784
LIBDE265_API void de265_get_image_NAL_header(const struct de265_image* img,
785
                                             int* nal_unit_type,
786
                                             const char** nal_unit_name,
787
                                             int* nuh_layer_id,
788
                                             int* nuh_temporal_id)
789
0
{
790
0
  if (nal_unit_type)   *nal_unit_type   = img->nal_hdr.nal_unit_type;
791
0
  if (nal_unit_name)   *nal_unit_name   = get_NAL_name(img->nal_hdr.nal_unit_type);
792
0
  if (nuh_layer_id)    *nuh_layer_id    = img->nal_hdr.nuh_layer_id;
793
0
  if (nuh_temporal_id) *nuh_temporal_id = img->nal_hdr.nuh_temporal_id;
794
0
}
795
796
LIBDE265_API int de265_get_image_full_range_flag(const struct de265_image* img)
797
8.15k
{
798
8.15k
  return img->get_sps().vui.video_full_range_flag;
799
8.15k
}
800
801
LIBDE265_API int de265_get_image_colour_primaries(const struct de265_image* img)
802
8.15k
{
803
8.15k
  return img->get_sps().vui.colour_primaries;
804
8.15k
}
805
806
LIBDE265_API int de265_get_image_transfer_characteristics(const struct de265_image* img)
807
8.15k
{
808
8.15k
  return img->get_sps().vui.transfer_characteristics;
809
8.15k
}
810
811
LIBDE265_API int de265_get_image_matrix_coefficients(const struct de265_image* img)
812
8.15k
{
813
8.15k
  return img->get_sps().vui.matrix_coeffs;
814
8.15k
}
815
816
}