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