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
35
36 // TODO: should be in some vps.c related header
37 de265_error read_vps(decoder_context* ctx, bitreader* reader, video_parameter_set* vps);
38
39 extern "C" {
de265_get_version(void)40 LIBDE265_API const char *de265_get_version(void)
41 {
42 return (LIBDE265_VERSION);
43 }
44
de265_get_version_number(void)45 LIBDE265_API uint32_t de265_get_version_number(void)
46 {
47 return (LIBDE265_NUMERIC_VERSION);
48 }
49
de265_get_version_number_major(void)50 LIBDE265_API int de265_get_version_number_major(void)
51 {
52 return ((LIBDE265_NUMERIC_VERSION)>>24) & 0xFF;
53 }
54
de265_get_version_number_minor(void)55 LIBDE265_API int de265_get_version_number_minor(void)
56 {
57 return ((LIBDE265_NUMERIC_VERSION)>>16) & 0xFF;
58 }
59
de265_get_version_number_maintenance(void)60 LIBDE265_API int de265_get_version_number_maintenance(void)
61 {
62 return ((LIBDE265_NUMERIC_VERSION)>>8) & 0xFF;
63 }
64
65
de265_get_error_text(de265_error err)66 LIBDE265_API const char* de265_get_error_text(de265_error err)
67 {
68 switch (err) {
69 case DE265_OK: return "no error";
70 case DE265_ERROR_NO_SUCH_FILE: return "no such file";
71 //case DE265_ERROR_NO_STARTCODE: return "no startcode found";
72 //case DE265_ERROR_EOF: return "end of file";
73 case DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS: return "coefficient out of image bounds";
74 case DE265_ERROR_CHECKSUM_MISMATCH: return "image checksum mismatch";
75 case DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA: return "CTB outside of image area";
76 case DE265_ERROR_OUT_OF_MEMORY: return "out of memory";
77 case DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE: return "coded parameter out of range";
78 case DE265_ERROR_IMAGE_BUFFER_FULL: return "DPB/output queue full";
79 case DE265_ERROR_CANNOT_START_THREADPOOL: return "cannot start decoding threads";
80 case DE265_ERROR_LIBRARY_INITIALIZATION_FAILED: return "global library initialization failed";
81 case DE265_ERROR_LIBRARY_NOT_INITIALIZED: return "cannot free library data (not initialized";
82
83 //case DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED:
84 // return "internal error: maximum number of thread contexts exceeded";
85 //case DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED:
86 // return "internal error: maximum number of slices exceeded";
87 case DE265_ERROR_NOT_IMPLEMENTED_YET:
88 return "unimplemented decoder feature";
89 //case DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED:
90 //return "scaling list not implemented";
91
92 case DE265_ERROR_WAITING_FOR_INPUT_DATA:
93 return "no more input data, decoder stalled";
94 case DE265_ERROR_CANNOT_PROCESS_SEI:
95 return "SEI data cannot be processed";
96 case DE265_ERROR_PARAMETER_PARSING:
97 return "command-line parameter error";
98 case DE265_ERROR_NO_INITIAL_SLICE_HEADER:
99 return "first slice missing, cannot decode dependent slice";
100 case DE265_ERROR_PREMATURE_END_OF_SLICE:
101 return "premature end of slice data";
102 case DE265_ERROR_UNSPECIFIED_DECODING_ERROR:
103 return "unspecified decoding error";
104
105 case DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING:
106 return "Cannot run decoder multi-threaded because stream does not support WPP";
107 case DE265_WARNING_WARNING_BUFFER_FULL:
108 return "Too many warnings queued";
109 case DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT:
110 return "Premature end of slice segment";
111 case DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET:
112 return "Incorrect entry-point offsets";
113 case DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA:
114 return "CTB outside of image area (concealing stream error...)";
115 case DE265_WARNING_SPS_HEADER_INVALID:
116 return "sps header invalid";
117 case DE265_WARNING_PPS_HEADER_INVALID:
118 return "pps header invalid";
119 case DE265_WARNING_SLICEHEADER_INVALID:
120 return "slice header invalid";
121 case DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING:
122 return "impossible motion vector scaling";
123 case DE265_WARNING_NONEXISTING_PPS_REFERENCED:
124 return "non-existing PPS referenced";
125 case DE265_WARNING_NONEXISTING_SPS_REFERENCED:
126 return "non-existing SPS referenced";
127 case DE265_WARNING_BOTH_PREDFLAGS_ZERO:
128 return "both predFlags[] are zero in MC";
129 case DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED:
130 return "non-existing reference picture accessed";
131 case DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ:
132 return "numMV_P != numMV_Q in deblocking";
133 case DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE:
134 return "number of short-term ref-pic-sets out of range";
135 case DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE:
136 return "short-term ref-pic-set index out of range";
137 case DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST:
138 return "faulty reference picture list";
139 case DE265_WARNING_EOSS_BIT_NOT_SET:
140 return "end_of_sub_stream_one_bit not set to 1 when it should be";
141 case DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED:
142 return "maximum number of reference pictures exceeded";
143 case DE265_WARNING_INVALID_CHROMA_FORMAT:
144 return "invalid chroma format in SPS header";
145 case DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID:
146 return "slice segment address invalid";
147 case DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO:
148 return "dependent slice with address 0";
149 case DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM:
150 return "number of threads limited to maximum amount";
151 case DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER:
152 return "non-existing long-term reference candidate specified in slice header";
153 case DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY:
154 return "cannot apply SAO because we ran out of memory";
155 case DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI:
156 return "SPS header missing, cannot decode SEI";
157 case DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA:
158 return "collocated motion-vector is outside image area";
159
160 default: return "unknown error";
161 }
162 }
163
de265_isOK(de265_error err)164 LIBDE265_API int de265_isOK(de265_error err)
165 {
166 return err == DE265_OK || err >= 1000;
167 }
168
169
170
171 ALIGNED_8(static de265_sync_int de265_init_count) = 0;
172
de265_init()173 LIBDE265_API de265_error de265_init()
174 {
175 int cnt = de265_sync_add_and_fetch(&de265_init_count,1);
176 if (cnt>1) {
177 // we are not the first -> already initialized
178
179 return DE265_OK;
180 }
181
182
183 // do initializations
184
185 init_scan_orders();
186
187 if (!alloc_and_init_significant_coeff_ctxIdx_lookupTable()) {
188 de265_sync_sub_and_fetch(&de265_init_count,1);
189 return DE265_ERROR_LIBRARY_INITIALIZATION_FAILED;
190 }
191
192 return DE265_OK;
193 }
194
de265_free()195 LIBDE265_API de265_error de265_free()
196 {
197 int cnt = de265_sync_sub_and_fetch(&de265_init_count,1);
198 if (cnt<0) {
199 de265_sync_add_and_fetch(&de265_init_count,1);
200 return DE265_ERROR_LIBRARY_NOT_INITIALIZED;
201 }
202
203 if (cnt==0) {
204 free_significant_coeff_ctxIdx_lookupTable();
205 }
206
207 return DE265_OK;
208 }
209
210
de265_new_decoder()211 LIBDE265_API de265_decoder_context* de265_new_decoder()
212 {
213 de265_error init_err = de265_init();
214 if (init_err != DE265_OK) {
215 return NULL;
216 }
217
218 decoder_context* ctx = new decoder_context;
219 if (!ctx) {
220 de265_free();
221 return NULL;
222 }
223
224 return (de265_decoder_context*)ctx;
225 }
226
227
de265_free_decoder(de265_decoder_context * de265ctx)228 LIBDE265_API de265_error de265_free_decoder(de265_decoder_context* de265ctx)
229 {
230 decoder_context* ctx = (decoder_context*)de265ctx;
231
232 ctx->stop_thread_pool();
233
234 delete ctx;
235
236 return de265_free();
237 }
238
239
de265_start_worker_threads(de265_decoder_context * de265ctx,int number_of_threads)240 LIBDE265_API de265_error de265_start_worker_threads(de265_decoder_context* de265ctx, int number_of_threads)
241 {
242 decoder_context* ctx = (decoder_context*)de265ctx;
243
244 if (number_of_threads > MAX_THREADS) {
245 number_of_threads = MAX_THREADS;
246 }
247
248 if (number_of_threads>0) {
249 de265_error err = ctx->start_thread_pool(number_of_threads);
250 if (de265_isOK(err)) {
251 err = DE265_OK;
252 }
253 return err;
254 }
255 else {
256 return DE265_OK;
257 }
258 }
259
260
261 #ifndef LIBDE265_DISABLE_DEPRECATED
de265_decode_data(de265_decoder_context * de265ctx,const void * data8,int len)262 LIBDE265_API de265_error de265_decode_data(de265_decoder_context* de265ctx,
263 const void* data8, int len)
264 {
265 //decoder_context* ctx = (decoder_context*)de265ctx;
266 de265_error err;
267 if (len > 0) {
268 err = de265_push_data(de265ctx, data8, len, 0, NULL);
269 } else {
270 err = de265_flush_data(de265ctx);
271 }
272 if (err != DE265_OK) {
273 return err;
274 }
275
276 int more = 0;
277 do {
278 err = de265_decode(de265ctx, &more);
279 if (err != DE265_OK) {
280 more = 0;
281 }
282
283 switch (err) {
284 case DE265_ERROR_WAITING_FOR_INPUT_DATA:
285 // ignore error (didn't exist in 0.4 and before)
286 err = DE265_OK;
287 break;
288 default:
289 break;
290 }
291 } while (more);
292 return err;
293 }
294 #endif
295
dumpdata(const void * data,int len)296 static void dumpdata(const void* data, int len)
297 {
298 for (int i=0;i<len;i++) {
299 printf("%02x ", ((uint8_t*)data)[i]);
300 }
301 printf("\n");
302 }
303
304
de265_push_data(de265_decoder_context * de265ctx,const void * data8,int len,de265_PTS pts,void * user_data)305 LIBDE265_API de265_error de265_push_data(de265_decoder_context* de265ctx,
306 const void* data8, int len,
307 de265_PTS pts, void* user_data)
308 {
309 decoder_context* ctx = (decoder_context*)de265ctx;
310 uint8_t* data = (uint8_t*)data8;
311
312 //printf("push data (size %d)\n",len);
313 //dumpdata(data8,16);
314
315 return ctx->nal_parser.push_data(data,len,pts,user_data);
316 }
317
318
de265_push_NAL(de265_decoder_context * de265ctx,const void * data8,int len,de265_PTS pts,void * user_data)319 LIBDE265_API de265_error de265_push_NAL(de265_decoder_context* de265ctx,
320 const void* data8, int len,
321 de265_PTS pts, void* user_data)
322 {
323 decoder_context* ctx = (decoder_context*)de265ctx;
324 uint8_t* data = (uint8_t*)data8;
325
326 //printf("push NAL (size %d)\n",len);
327 //dumpdata(data8,16);
328
329 return ctx->nal_parser.push_NAL(data,len,pts,user_data);
330 }
331
332
de265_decode(de265_decoder_context * de265ctx,int * more)333 LIBDE265_API de265_error de265_decode(de265_decoder_context* de265ctx, int* more)
334 {
335 decoder_context* ctx = (decoder_context*)de265ctx;
336
337 return ctx->decode(more);
338 }
339
340
de265_push_end_of_NAL(de265_decoder_context * de265ctx)341 LIBDE265_API void de265_push_end_of_NAL(de265_decoder_context* de265ctx)
342 {
343 decoder_context* ctx = (decoder_context*)de265ctx;
344
345 ctx->nal_parser.flush_data();
346 }
347
348
de265_push_end_of_frame(de265_decoder_context * de265ctx)349 LIBDE265_API void de265_push_end_of_frame(de265_decoder_context* de265ctx)
350 {
351 de265_push_end_of_NAL(de265ctx);
352
353 decoder_context* ctx = (decoder_context*)de265ctx;
354 ctx->nal_parser.mark_end_of_frame();
355 }
356
357
de265_flush_data(de265_decoder_context * de265ctx)358 LIBDE265_API de265_error de265_flush_data(de265_decoder_context* de265ctx)
359 {
360 de265_push_end_of_NAL(de265ctx);
361
362 decoder_context* ctx = (decoder_context*)de265ctx;
363
364 ctx->nal_parser.flush_data();
365 ctx->nal_parser.mark_end_of_stream();
366
367 return DE265_OK;
368 }
369
370
de265_reset(de265_decoder_context * de265ctx)371 LIBDE265_API void de265_reset(de265_decoder_context* de265ctx)
372 {
373 decoder_context* ctx = (decoder_context*)de265ctx;
374
375 //printf("--- reset ---\n");
376
377 ctx->reset();
378 }
379
380
de265_get_next_picture(de265_decoder_context * de265ctx)381 LIBDE265_API const struct de265_image* de265_get_next_picture(de265_decoder_context* de265ctx)
382 {
383 const struct de265_image* img = de265_peek_next_picture(de265ctx);
384 if (img) {
385 de265_release_next_picture(de265ctx);
386 }
387
388 return img;
389 }
390
391
de265_peek_next_picture(de265_decoder_context * de265ctx)392 LIBDE265_API const struct de265_image* de265_peek_next_picture(de265_decoder_context* de265ctx)
393 {
394 decoder_context* ctx = (decoder_context*)de265ctx;
395
396 if (ctx->num_pictures_in_output_queue()>0) {
397 de265_image* img = ctx->get_next_picture_in_output_queue();
398 return img;
399 }
400 else {
401 return NULL;
402 }
403 }
404
405
de265_release_next_picture(de265_decoder_context * de265ctx)406 LIBDE265_API void de265_release_next_picture(de265_decoder_context* de265ctx)
407 {
408 decoder_context* ctx = (decoder_context*)de265ctx;
409
410 // no active output picture -> ignore release request
411
412 if (ctx->num_pictures_in_output_queue()==0) { return; }
413
414 de265_image* next_image = ctx->get_next_picture_in_output_queue();
415
416 loginfo(LogDPB, "release DPB with POC=%d\n",next_image->PicOrderCntVal);
417
418 next_image->PicOutputFlag = false;
419
420 // TODO: actually, we want to release it here, but we cannot without breaking API
421 // compatibility, because get_next_picture calls this immediately. Hence, we release
422 // images while scanning for available slots in the DPB.
423 // if (next_image->can_be_released()) { next_image->release(); }
424
425 // pop output queue
426
427 ctx->pop_next_picture_in_output_queue();
428 }
429
430
431
de265_get_highest_TID(de265_decoder_context * de265ctx)432 LIBDE265_API int de265_get_highest_TID(de265_decoder_context* de265ctx)
433 {
434 decoder_context* ctx = (decoder_context*)de265ctx;
435 return ctx->get_highest_TID();
436 }
437
de265_get_current_TID(de265_decoder_context * de265ctx)438 LIBDE265_API int de265_get_current_TID(de265_decoder_context* de265ctx)
439 {
440 decoder_context* ctx = (decoder_context*)de265ctx;
441 return ctx->get_current_TID();
442 }
443
de265_set_limit_TID(de265_decoder_context * de265ctx,int max_tid)444 LIBDE265_API void de265_set_limit_TID(de265_decoder_context* de265ctx,int max_tid)
445 {
446 decoder_context* ctx = (decoder_context*)de265ctx;
447 ctx->set_limit_TID(max_tid);
448 }
449
de265_set_framerate_ratio(de265_decoder_context * de265ctx,int percent)450 LIBDE265_API void de265_set_framerate_ratio(de265_decoder_context* de265ctx,int percent)
451 {
452 decoder_context* ctx = (decoder_context*)de265ctx;
453 ctx->set_framerate_ratio(percent);
454 }
455
de265_change_framerate(de265_decoder_context * de265ctx,int more)456 LIBDE265_API int de265_change_framerate(de265_decoder_context* de265ctx,int more)
457 {
458 decoder_context* ctx = (decoder_context*)de265ctx;
459 return ctx->change_framerate(more);
460 }
461
462
de265_get_warning(de265_decoder_context * de265ctx)463 LIBDE265_API de265_error de265_get_warning(de265_decoder_context* de265ctx)
464 {
465 decoder_context* ctx = (decoder_context*)de265ctx;
466
467 return ctx->get_warning();
468 }
469
de265_set_parameter_bool(de265_decoder_context * de265ctx,enum de265_param param,int value)470 LIBDE265_API void de265_set_parameter_bool(de265_decoder_context* de265ctx, enum de265_param param, int value)
471 {
472 decoder_context* ctx = (decoder_context*)de265ctx;
473
474 switch (param)
475 {
476 case DE265_DECODER_PARAM_BOOL_SEI_CHECK_HASH:
477 ctx->param_sei_check_hash = !!value;
478 break;
479
480 case DE265_DECODER_PARAM_SUPPRESS_FAULTY_PICTURES:
481 ctx->param_suppress_faulty_pictures = !!value;
482 break;
483
484 case DE265_DECODER_PARAM_DISABLE_DEBLOCKING:
485 ctx->param_disable_deblocking = !!value;
486 break;
487
488 case DE265_DECODER_PARAM_DISABLE_SAO:
489 ctx->param_disable_sao = !!value;
490 break;
491
492 /*
493 case DE265_DECODER_PARAM_DISABLE_MC_RESIDUAL_IDCT:
494 ctx->param_disable_mc_residual_idct = !!value;
495 break;
496
497 case DE265_DECODER_PARAM_DISABLE_INTRA_RESIDUAL_IDCT:
498 ctx->param_disable_intra_residual_idct = !!value;
499 break;
500 */
501
502 default:
503 assert(false);
504 break;
505 }
506 }
507
508
de265_set_parameter_int(de265_decoder_context * de265ctx,enum de265_param param,int value)509 LIBDE265_API void de265_set_parameter_int(de265_decoder_context* de265ctx, enum de265_param param, int value)
510 {
511 decoder_context* ctx = (decoder_context*)de265ctx;
512
513 switch (param)
514 {
515 case DE265_DECODER_PARAM_DUMP_SPS_HEADERS:
516 ctx->param_sps_headers_fd = value;
517 break;
518
519 case DE265_DECODER_PARAM_DUMP_VPS_HEADERS:
520 ctx->param_vps_headers_fd = value;
521 break;
522
523 case DE265_DECODER_PARAM_DUMP_PPS_HEADERS:
524 ctx->param_pps_headers_fd = value;
525 break;
526
527 case DE265_DECODER_PARAM_DUMP_SLICE_HEADERS:
528 ctx->param_slice_headers_fd = value;
529 break;
530
531 case DE265_DECODER_PARAM_ACCELERATION_CODE:
532 ctx->set_acceleration_functions((enum de265_acceleration)value);
533 break;
534
535 default:
536 assert(false);
537 break;
538 }
539 }
540
541
542
543
de265_get_parameter_bool(de265_decoder_context * de265ctx,enum de265_param param)544 LIBDE265_API int de265_get_parameter_bool(de265_decoder_context* de265ctx, enum de265_param param)
545 {
546 decoder_context* ctx = (decoder_context*)de265ctx;
547
548 switch (param)
549 {
550 case DE265_DECODER_PARAM_BOOL_SEI_CHECK_HASH:
551 return ctx->param_sei_check_hash;
552
553 case DE265_DECODER_PARAM_SUPPRESS_FAULTY_PICTURES:
554 return ctx->param_suppress_faulty_pictures;
555
556 case DE265_DECODER_PARAM_DISABLE_DEBLOCKING:
557 return ctx->param_disable_deblocking;
558
559 case DE265_DECODER_PARAM_DISABLE_SAO:
560 return ctx->param_disable_sao;
561
562 /*
563 case DE265_DECODER_PARAM_DISABLE_MC_RESIDUAL_IDCT:
564 return ctx->param_disable_mc_residual_idct;
565
566 case DE265_DECODER_PARAM_DISABLE_INTRA_RESIDUAL_IDCT:
567 return ctx->param_disable_intra_residual_idct;
568 */
569
570 default:
571 assert(false);
572 return false;
573 }
574 }
575
576
de265_get_number_of_input_bytes_pending(de265_decoder_context * de265ctx)577 LIBDE265_API int de265_get_number_of_input_bytes_pending(de265_decoder_context* de265ctx)
578 {
579 decoder_context* ctx = (decoder_context*)de265ctx;
580
581 return ctx->nal_parser.bytes_in_input_queue();
582 }
583
584
de265_get_number_of_NAL_units_pending(de265_decoder_context * de265ctx)585 LIBDE265_API int de265_get_number_of_NAL_units_pending(de265_decoder_context* de265ctx)
586 {
587 decoder_context* ctx = (decoder_context*)de265ctx;
588
589 return ctx->nal_parser.number_of_NAL_units_pending();
590 }
591
592
de265_get_image_width(const struct de265_image * img,int channel)593 LIBDE265_API int de265_get_image_width(const struct de265_image* img,int channel)
594 {
595 switch (channel) {
596 case 0:
597 return img->width_confwin;
598 case 1:
599 case 2:
600 return img->chroma_width_confwin;
601 default:
602 return 0;
603 }
604 }
605
de265_get_image_height(const struct de265_image * img,int channel)606 LIBDE265_API int de265_get_image_height(const struct de265_image* img,int channel)
607 {
608 switch (channel) {
609 case 0:
610 return img->height_confwin;
611 case 1:
612 case 2:
613 return img->chroma_height_confwin;
614 default:
615 return 0;
616 }
617 }
618
de265_get_bits_per_pixel(const struct de265_image * img,int channel)619 LIBDE265_API int de265_get_bits_per_pixel(const struct de265_image* img,int channel)
620 {
621 switch (channel) {
622 case 0:
623 return img->sps.BitDepth_Y;
624 case 1:
625 case 2:
626 return img->sps.BitDepth_C;
627 default:
628 return 0;
629 }
630 }
631
de265_get_chroma_format(const struct de265_image * img)632 LIBDE265_API enum de265_chroma de265_get_chroma_format(const struct de265_image* img)
633 {
634 return img->get_chroma_format();
635 }
636
de265_get_image_plane(const de265_image * img,int channel,int * stride)637 LIBDE265_API const uint8_t* de265_get_image_plane(const de265_image* img, int channel, int* stride)
638 {
639 assert(channel>=0 && channel <= 2);
640
641 uint8_t* data = img->pixels_confwin[channel];
642
643 if (stride) *stride = img->get_image_stride(channel) * ((de265_get_bits_per_pixel(img, channel)+7) / 8);
644
645 return data;
646 }
647
de265_get_image_plane_user_data(const struct de265_image * img,int channel)648 LIBDE265_API void *de265_get_image_plane_user_data(const struct de265_image* img, int channel)
649 {
650 assert(channel>=0 && channel <= 2);
651
652 return img->plane_user_data[channel];
653 }
654
de265_set_image_plane(de265_image * img,int cIdx,void * mem,int stride,void * userdata)655 LIBDE265_API void de265_set_image_plane(de265_image* img, int cIdx, void* mem, int stride, void *userdata)
656 {
657 // The internal "stride" is the number of pixels per line.
658 stride = stride / ((de265_get_bits_per_pixel(img, cIdx)+7) / 8);
659 img->set_image_plane(cIdx, (uint8_t*)mem, stride, userdata);
660 }
661
de265_set_image_allocation_functions(de265_decoder_context * de265ctx,de265_image_allocation * allocfunc,void * userdata)662 LIBDE265_API void de265_set_image_allocation_functions(de265_decoder_context* de265ctx,
663 de265_image_allocation* allocfunc,
664 void* userdata)
665 {
666 decoder_context* ctx = (decoder_context*)de265ctx;
667
668 ctx->set_image_allocation_functions(allocfunc, userdata);
669 }
670
de265_get_default_image_allocation_functions(void)671 LIBDE265_API const struct de265_image_allocation *de265_get_default_image_allocation_functions(void)
672 {
673 return &de265_image::default_image_allocation;
674 }
675
de265_get_image_PTS(const struct de265_image * img)676 LIBDE265_API de265_PTS de265_get_image_PTS(const struct de265_image* img)
677 {
678 return img->pts;
679 }
680
de265_get_image_user_data(const struct de265_image * img)681 LIBDE265_API void* de265_get_image_user_data(const struct de265_image* img)
682 {
683 return img->user_data;
684 }
685
de265_set_image_user_data(struct de265_image * img,void * user_data)686 LIBDE265_API void de265_set_image_user_data(struct de265_image* img, void *user_data)
687 {
688 img->user_data = user_data;
689 }
690
de265_get_image_NAL_header(const struct de265_image * img,int * nal_unit_type,const char ** nal_unit_name,int * nuh_layer_id,int * nuh_temporal_id)691 LIBDE265_API void de265_get_image_NAL_header(const struct de265_image* img,
692 int* nal_unit_type,
693 const char** nal_unit_name,
694 int* nuh_layer_id,
695 int* nuh_temporal_id)
696 {
697 if (nal_unit_type) *nal_unit_type = img->nal_hdr.nal_unit_type;
698 if (nal_unit_name) *nal_unit_name = get_NAL_name(img->nal_hdr.nal_unit_type);
699 if (nuh_layer_id) *nuh_layer_id = img->nal_hdr.nuh_layer_id;
700 if (nuh_temporal_id) *nuh_temporal_id = img->nal_hdr.nuh_temporal_id;
701 }
702 }
703