diff --git a/libde265/Makefile.am b/libde265/Makefile.am index 305f934a9..580a18e5a 100644 --- a/libde265/Makefile.am +++ b/libde265/Makefile.am @@ -120,4 +120,5 @@ EXTRA_DIST = Makefile.vc7 \ libde265_la_HEADERS = \ de265.h \ + de265-error.h \ de265-version.h diff --git a/libde265/contextmodel.h b/libde265/contextmodel.h index cde83e110..597d6121c 100644 --- a/libde265/contextmodel.h +++ b/libde265/contextmodel.h @@ -25,7 +25,6 @@ #define DE265_CONTEXTMODEL_H #include "libde265/cabac.h" -#include "libde265/de265.h" #include #include diff --git a/libde265/de265-error.h b/libde265/de265-error.h new file mode 100644 index 000000000..080bc6b2d --- /dev/null +++ b/libde265/de265-error.h @@ -0,0 +1,86 @@ +/* + * H.265 video codec. + * Copyright (c) 2013-2014 struktur AG, Dirk Farin + * + * This file is part of libde265. + * + * libde265 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * libde265 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libde265. If not, see . +*/ + + +#ifndef DE265_ERROR_H +#define DE265_ERROR_H + +/* === error codes === */ + +typedef enum { + DE265_OK = 0, + DE265_ERROR_NO_SUCH_FILE=1, + //DE265_ERROR_NO_STARTCODE=2, obsolete + //DE265_ERROR_EOF=3, + DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS=4, + DE265_ERROR_CHECKSUM_MISMATCH=5, + DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA=6, + DE265_ERROR_OUT_OF_MEMORY=7, + DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE=8, + DE265_ERROR_IMAGE_BUFFER_FULL=9, + DE265_ERROR_CANNOT_START_THREADPOOL=10, + DE265_ERROR_LIBRARY_INITIALIZATION_FAILED=11, + DE265_ERROR_LIBRARY_NOT_INITIALIZED=12, + DE265_ERROR_WAITING_FOR_INPUT_DATA=13, + DE265_ERROR_CANNOT_PROCESS_SEI=14, + DE265_ERROR_PARAMETER_PARSING=15, + DE265_ERROR_NO_INITIAL_SLICE_HEADER=16, + DE265_ERROR_PREMATURE_END_OF_SLICE=17, + DE265_ERROR_UNSPECIFIED_DECODING_ERROR=18, + + // --- errors that should become obsolete in later libde265 versions --- + + //DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED = 500, obsolete + //DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED = 501, obsolete + DE265_ERROR_NOT_IMPLEMENTED_YET = 502, + //DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED = 502, obsolete + + // --- warnings --- + + DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING = 1000, + DE265_WARNING_WARNING_BUFFER_FULL=1001, + DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT=1002, + DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET=1003, + DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA=1004, + DE265_WARNING_SPS_HEADER_INVALID=1005, + DE265_WARNING_PPS_HEADER_INVALID=1006, + DE265_WARNING_SLICEHEADER_INVALID=1007, + DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING=1008, + DE265_WARNING_NONEXISTING_PPS_REFERENCED=1009, + DE265_WARNING_NONEXISTING_SPS_REFERENCED=1010, + DE265_WARNING_BOTH_PREDFLAGS_ZERO=1011, + DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED=1012, + DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ=1013, + DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE=1014, + DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE=1015, + DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST=1016, + DE265_WARNING_EOSS_BIT_NOT_SET=1017, + DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED=1018, + DE265_WARNING_INVALID_CHROMA_FORMAT=1019, + DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID=1020, + DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO=1021, + DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM=1022, + DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER=1023, + DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY=1024, + DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI=1025, + DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA=1026 +} de265_error; + +#endif diff --git a/libde265/de265.cc b/libde265/de265.cc index 75dd0a893..c793901e8 100644 --- a/libde265/de265.cc +++ b/libde265/de265.cc @@ -37,7 +37,6 @@ // TODO: should be in some vps.c related header de265_error read_vps(decoder_context* ctx, bitreader* reader, video_parameter_set* vps); -extern "C" { LIBDE265_API const char *de265_get_version(void) { return (LIBDE265_VERSION); @@ -468,6 +467,18 @@ LIBDE265_API int de265_change_framerate(de265_decoder_context* de265ctx,int mor return ctx->change_framerate(more); } +LIBDE265_API void de265_callback_register(de265_decoder_context* de265ctx, de265_callback_block* cbb) +{ + decoder_context* ctx = (decoder_context*)de265ctx; + ctx->callback_register(cbb); +} + +LIBDE265_API void de265_callback_unregister(de265_decoder_context* de265ctx) +{ + decoder_context* ctx = (decoder_context*)de265ctx; + ctx->callback_unregister(); +} + LIBDE265_API de265_error de265_get_warning(de265_decoder_context* de265ctx) { @@ -708,4 +719,3 @@ LIBDE265_API void de265_get_image_NAL_header(const struct de265_image* img, if (nuh_layer_id) *nuh_layer_id = img->nal_hdr.nuh_layer_id; if (nuh_temporal_id) *nuh_temporal_id = img->nal_hdr.nuh_temporal_id; } -} diff --git a/libde265/de265.h b/libde265/de265.h index 6481d8f0a..af35ad949 100644 --- a/libde265/de265.h +++ b/libde265/de265.h @@ -22,9 +22,6 @@ #ifndef DE265_H #define DE265_H -#ifdef __cplusplus -extern "C" { -#endif #include @@ -66,6 +63,11 @@ extern "C" { #define LIBDE265_INLINE inline #endif +#include "de265-error.h" +#include "vps.h" +#include "pps.h" +#include "sps.h" + /* === version numbers === */ // version of linked libde265 library @@ -77,67 +79,7 @@ LIBDE265_API int de265_get_version_number_minor(void); LIBDE265_API int de265_get_version_number_maintenance(void); -/* === error codes === */ - -typedef enum { - DE265_OK = 0, - DE265_ERROR_NO_SUCH_FILE=1, - //DE265_ERROR_NO_STARTCODE=2, obsolet - //DE265_ERROR_EOF=3, - DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS=4, - DE265_ERROR_CHECKSUM_MISMATCH=5, - DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA=6, - DE265_ERROR_OUT_OF_MEMORY=7, - DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE=8, - DE265_ERROR_IMAGE_BUFFER_FULL=9, - DE265_ERROR_CANNOT_START_THREADPOOL=10, - DE265_ERROR_LIBRARY_INITIALIZATION_FAILED=11, - DE265_ERROR_LIBRARY_NOT_INITIALIZED=12, - DE265_ERROR_WAITING_FOR_INPUT_DATA=13, - DE265_ERROR_CANNOT_PROCESS_SEI=14, - DE265_ERROR_PARAMETER_PARSING=15, - DE265_ERROR_NO_INITIAL_SLICE_HEADER=16, - DE265_ERROR_PREMATURE_END_OF_SLICE=17, - DE265_ERROR_UNSPECIFIED_DECODING_ERROR=18, - - // --- errors that should become obsolete in later libde265 versions --- - - //DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED = 500, obsolet - //DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED = 501, obsolet - DE265_ERROR_NOT_IMPLEMENTED_YET = 502, - //DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED = 502, obsolet - - // --- warnings --- - - DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING = 1000, - DE265_WARNING_WARNING_BUFFER_FULL=1001, - DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT=1002, - DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET=1003, - DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA=1004, - DE265_WARNING_SPS_HEADER_INVALID=1005, - DE265_WARNING_PPS_HEADER_INVALID=1006, - DE265_WARNING_SLICEHEADER_INVALID=1007, - DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING=1008, - DE265_WARNING_NONEXISTING_PPS_REFERENCED=1009, - DE265_WARNING_NONEXISTING_SPS_REFERENCED=1010, - DE265_WARNING_BOTH_PREDFLAGS_ZERO=1011, - DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED=1012, - DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ=1013, - DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE=1014, - DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE=1015, - DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST=1016, - DE265_WARNING_EOSS_BIT_NOT_SET=1017, - DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED=1018, - DE265_WARNING_INVALID_CHROMA_FORMAT=1019, - DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID=1020, - DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO=1021, - DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM=1022, - DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER=1023, - DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY=1024, - DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI=1025, - DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA=1026 -} de265_error; - +/* === error code management === */ LIBDE265_API const char* de265_get_error_text(de265_error err); /* Returns true, if 'err' is DE265_OK or a warning. @@ -387,6 +329,20 @@ enum de265_param { //DE265_DECODER_PARAM_DISABLE_INTRA_RESIDUAL_IDCT=10 // (bool) disable decoding of IDCT residuals in MC blocks }; +/* --- callback --- */ +struct de265_callback_block +{ + void (*get_vps)(video_parameter_set* vps); + void (*get_sps)(seq_parameter_set* sps); + void (*get_pps)(pic_parameter_set* pps); + void (*get_image)(de265_image* img); +}; +LIBDE265_API void de265_callback_register(de265_decoder_context*, de265_callback_block*); +LIBDE265_API void de265_callback_unregister(de265_decoder_context*); + +/* The user data pointer will be given to the get_buffer() and release_buffer() functions + in de265_image_allocation. */ + // sorted such that a large ID includes all optimizations from lower IDs enum de265_acceleration { de265_acceleration_SCALAR = 0, // only fallback implementation @@ -430,8 +386,5 @@ LIBDE265_API de265_error de265_init(void); LIBDE265_API de265_error de265_free(void); -#ifdef __cplusplus -} -#endif #endif diff --git a/libde265/decctx.cc b/libde265/decctx.cc index edebb7136..ad061c7fd 100644 --- a/libde265/decctx.cc +++ b/libde265/decctx.cc @@ -301,6 +301,7 @@ decoder_context::decoder_context() */ + cbb = NULL; // --- internal data --- @@ -540,6 +541,10 @@ de265_error decoder_context::read_vps_NAL(bitreader& reader) new_vps->dump(param_vps_headers_fd); } + if (cbb != NULL && cbb->get_vps != NULL) { + cbb->get_vps(new_vps.get()); + } + vps[ new_vps->video_parameter_set_id ] = new_vps; return DE265_OK; @@ -560,6 +565,10 @@ de265_error decoder_context::read_sps_NAL(bitreader& reader) new_sps->dump(param_sps_headers_fd); } + if (cbb != NULL && cbb->get_sps != NULL) { + cbb->get_sps(new_sps.get()); + } + sps[ new_sps->seq_parameter_set_id ] = new_sps; return DE265_OK; @@ -577,6 +586,10 @@ de265_error decoder_context::read_pps_NAL(bitreader& reader) new_pps->dump(param_pps_headers_fd); } + if (cbb != NULL && cbb->get_pps != NULL) { + cbb->get_pps(new_pps.get()); + } + if (success) { pps[ (int)new_pps->pic_parameter_set_id ] = new_pps; } @@ -596,6 +609,7 @@ de265_error decoder_context::read_sei_NAL(bitreader& reader, bool suffix) if ((err=read_sei(&reader,&sei, suffix, current_sps.get())) == DE265_OK) { dump_sei(&sei, current_sps.get()); + // TODO: add SEI callback here if (image_units.empty()==false && suffix) { image_units.back()->suffix_SEIs.push_back(sei); @@ -635,6 +649,7 @@ de265_error decoder_context::read_slice_NAL(bitreader& reader, NAL_unit* nal, na shdr->dump_slice_segment_header(this, param_slice_headers_fd); } + // TODO: add slice_header callback here if (process_slice_segment_header(shdr, &err, nal->pts, &nal_hdr, nal->user_data) == false) { @@ -778,6 +793,9 @@ de265_error decoder_context::decode_some(bool* did_work) break; } + if (cbb != NULL && cbb->get_image != NULL) { + cbb->get_image(imgunit->img); + } push_picture_to_output_queue(imgunit); @@ -2228,6 +2246,18 @@ void decoder_context::calc_tid_and_framerate_ratio() } +void decoder_context::callback_register(de265_callback_block* cbb_) +{ + cbb = cbb_; +} + + +void decoder_context::callback_unregister() +{ + cbb = NULL; +} + + void error_queue::add_warning(de265_error warning, bool once) { // check if warning was already shown diff --git a/libde265/decctx.h b/libde265/decctx.h index c1acdcef0..e40b28816 100644 --- a/libde265/decctx.h +++ b/libde265/decctx.h @@ -412,6 +412,11 @@ class decoder_context : public base_context { int change_framerate(int more_vs_less); // 1: more, -1: less void set_framerate_ratio(int percent); + // --- decode callback --- + + void callback_register(de265_callback_block* cbb); + void callback_unregister(); + private: // input parameters int limit_HighestTid; // never switch to a layer above this one @@ -429,6 +434,8 @@ class decoder_context : public base_context { } framedrop_tab[100+1]; int framedrop_tid_index[6+1]; + de265_callback_block* cbb; + void compute_framedrop_table(); void calc_tid_and_framerate_ratio(); diff --git a/libde265/en265.h b/libde265/en265.h index a22e5d14a..9c53c3d49 100644 --- a/libde265/en265.h +++ b/libde265/en265.h @@ -23,10 +23,6 @@ #ifndef EN265_H #define EN265_H -#ifdef __cplusplus -extern "C" { -#endif - #include @@ -210,9 +206,5 @@ LIBDE265_API void en265_free_packet(en265_encoder_context*, struct en265_packet* LIBDE265_API int en265_number_of_queued_packets(en265_encoder_context*); -#ifdef __cplusplus -} -#endif - #endif diff --git a/libde265/sps.h b/libde265/sps.h index b06151d23..e48796def 100644 --- a/libde265/sps.h +++ b/libde265/sps.h @@ -25,7 +25,7 @@ #include "libde265/vui.h" #include "libde265/bitstream.h" #include "libde265/refpic.h" -#include "libde265/de265.h" +#include "libde265/de265-error.h" #include "libde265/cabac.h" #include diff --git a/libde265/vps.h b/libde265/vps.h index 04c9c1529..08d7d8d07 100644 --- a/libde265/vps.h +++ b/libde265/vps.h @@ -30,7 +30,7 @@ #endif #include "libde265/bitstream.h" -#include "libde265/de265.h" +#include "libde265/de265-error.h" #include "libde265/cabac.h" #include diff --git a/libde265/vui.h b/libde265/vui.h index c412669ae..e281bbf32 100644 --- a/libde265/vui.h +++ b/libde265/vui.h @@ -21,7 +21,7 @@ #ifndef DE265_VUI_H #define DE265_VUI_H -#include "libde265/de265.h" +#include "libde265/de265-error.h" #include "libde265/bitstream.h" #include