Skip to content

Commit 4f94230

Browse files
committed
libde265: add callback mechanism to parse events
Add a mechanism that allows a decoder tool to get a callback for every NAL unit, slice content, and image that it is interested on. The idea is for the decoder tool to subscribe to the event it wants to hear about, and then get the parser object. This requires: * replace C linkage with C++ linkage, so that we can add classes in the callback * move error codes to separate file, to break the circular dependency between several files (e.g. `[sps|pps|vps].h`) and de265.h Tested: Wrote a decoder that subscribes to all the events, and just calls the `dump` method for every object.
1 parent c172dd8 commit 4f94230

File tree

11 files changed

+159
-81
lines changed

11 files changed

+159
-81
lines changed

libde265/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,5 @@ EXTRA_DIST = Makefile.vc7 \
120120

121121
libde265_la_HEADERS = \
122122
de265.h \
123+
de265-error.h \
123124
de265-version.h

libde265/contextmodel.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#define DE265_CONTEXTMODEL_H
2626

2727
#include "libde265/cabac.h"
28-
#include "libde265/de265.h"
2928

3029
#include <string.h>
3130
#include <string>

libde265/de265-error.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* H.265 video codec.
3+
* Copyright (c) 2013-2014 struktur AG, Dirk Farin <[email protected]>
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+
22+
#ifndef DE265_ERROR_H
23+
#define DE265_ERROR_H
24+
25+
/* === error codes === */
26+
27+
typedef enum {
28+
DE265_OK = 0,
29+
DE265_ERROR_NO_SUCH_FILE=1,
30+
//DE265_ERROR_NO_STARTCODE=2, obsolete
31+
//DE265_ERROR_EOF=3,
32+
DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS=4,
33+
DE265_ERROR_CHECKSUM_MISMATCH=5,
34+
DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA=6,
35+
DE265_ERROR_OUT_OF_MEMORY=7,
36+
DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE=8,
37+
DE265_ERROR_IMAGE_BUFFER_FULL=9,
38+
DE265_ERROR_CANNOT_START_THREADPOOL=10,
39+
DE265_ERROR_LIBRARY_INITIALIZATION_FAILED=11,
40+
DE265_ERROR_LIBRARY_NOT_INITIALIZED=12,
41+
DE265_ERROR_WAITING_FOR_INPUT_DATA=13,
42+
DE265_ERROR_CANNOT_PROCESS_SEI=14,
43+
DE265_ERROR_PARAMETER_PARSING=15,
44+
DE265_ERROR_NO_INITIAL_SLICE_HEADER=16,
45+
DE265_ERROR_PREMATURE_END_OF_SLICE=17,
46+
DE265_ERROR_UNSPECIFIED_DECODING_ERROR=18,
47+
48+
// --- errors that should become obsolete in later libde265 versions ---
49+
50+
//DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED = 500, obsolete
51+
//DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED = 501, obsolete
52+
DE265_ERROR_NOT_IMPLEMENTED_YET = 502,
53+
//DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED = 502, obsolete
54+
55+
// --- warnings ---
56+
57+
DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING = 1000,
58+
DE265_WARNING_WARNING_BUFFER_FULL=1001,
59+
DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT=1002,
60+
DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET=1003,
61+
DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA=1004,
62+
DE265_WARNING_SPS_HEADER_INVALID=1005,
63+
DE265_WARNING_PPS_HEADER_INVALID=1006,
64+
DE265_WARNING_SLICEHEADER_INVALID=1007,
65+
DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING=1008,
66+
DE265_WARNING_NONEXISTING_PPS_REFERENCED=1009,
67+
DE265_WARNING_NONEXISTING_SPS_REFERENCED=1010,
68+
DE265_WARNING_BOTH_PREDFLAGS_ZERO=1011,
69+
DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED=1012,
70+
DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ=1013,
71+
DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE=1014,
72+
DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE=1015,
73+
DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST=1016,
74+
DE265_WARNING_EOSS_BIT_NOT_SET=1017,
75+
DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED=1018,
76+
DE265_WARNING_INVALID_CHROMA_FORMAT=1019,
77+
DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID=1020,
78+
DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO=1021,
79+
DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM=1022,
80+
DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER=1023,
81+
DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY=1024,
82+
DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI=1025,
83+
DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA=1026
84+
} de265_error;
85+
86+
#endif

libde265/de265.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
// TODO: should be in some vps.c related header
3838
de265_error read_vps(decoder_context* ctx, bitreader* reader, video_parameter_set* vps);
3939

40-
extern "C" {
4140
LIBDE265_API const char *de265_get_version(void)
4241
{
4342
return (LIBDE265_VERSION);
@@ -468,6 +467,18 @@ LIBDE265_API int de265_change_framerate(de265_decoder_context* de265ctx,int mor
468467
return ctx->change_framerate(more);
469468
}
470469

470+
LIBDE265_API void de265_callback_register(de265_decoder_context* de265ctx, de265_callback_block* cbb)
471+
{
472+
decoder_context* ctx = (decoder_context*)de265ctx;
473+
ctx->callback_register(cbb);
474+
}
475+
476+
LIBDE265_API void de265_callback_unregister(de265_decoder_context* de265ctx)
477+
{
478+
decoder_context* ctx = (decoder_context*)de265ctx;
479+
ctx->callback_unregister();
480+
}
481+
471482

472483
LIBDE265_API de265_error de265_get_warning(de265_decoder_context* de265ctx)
473484
{
@@ -708,4 +719,3 @@ LIBDE265_API void de265_get_image_NAL_header(const struct de265_image* img,
708719
if (nuh_layer_id) *nuh_layer_id = img->nal_hdr.nuh_layer_id;
709720
if (nuh_temporal_id) *nuh_temporal_id = img->nal_hdr.nuh_temporal_id;
710721
}
711-
}

libde265/de265.h

Lines changed: 20 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
#ifndef DE265_H
2323
#define DE265_H
2424

25-
#ifdef __cplusplus
26-
extern "C" {
27-
#endif
2825

2926
#include <libde265/de265-version.h>
3027

@@ -66,6 +63,11 @@ extern "C" {
6663
#define LIBDE265_INLINE inline
6764
#endif
6865

66+
#include "de265-error.h"
67+
#include "vps.h"
68+
#include "pps.h"
69+
#include "sps.h"
70+
6971
/* === version numbers === */
7072

7173
// version of linked libde265 library
@@ -77,67 +79,7 @@ LIBDE265_API int de265_get_version_number_minor(void);
7779
LIBDE265_API int de265_get_version_number_maintenance(void);
7880

7981

80-
/* === error codes === */
81-
82-
typedef enum {
83-
DE265_OK = 0,
84-
DE265_ERROR_NO_SUCH_FILE=1,
85-
//DE265_ERROR_NO_STARTCODE=2, obsolet
86-
//DE265_ERROR_EOF=3,
87-
DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS=4,
88-
DE265_ERROR_CHECKSUM_MISMATCH=5,
89-
DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA=6,
90-
DE265_ERROR_OUT_OF_MEMORY=7,
91-
DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE=8,
92-
DE265_ERROR_IMAGE_BUFFER_FULL=9,
93-
DE265_ERROR_CANNOT_START_THREADPOOL=10,
94-
DE265_ERROR_LIBRARY_INITIALIZATION_FAILED=11,
95-
DE265_ERROR_LIBRARY_NOT_INITIALIZED=12,
96-
DE265_ERROR_WAITING_FOR_INPUT_DATA=13,
97-
DE265_ERROR_CANNOT_PROCESS_SEI=14,
98-
DE265_ERROR_PARAMETER_PARSING=15,
99-
DE265_ERROR_NO_INITIAL_SLICE_HEADER=16,
100-
DE265_ERROR_PREMATURE_END_OF_SLICE=17,
101-
DE265_ERROR_UNSPECIFIED_DECODING_ERROR=18,
102-
103-
// --- errors that should become obsolete in later libde265 versions ---
104-
105-
//DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED = 500, obsolet
106-
//DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED = 501, obsolet
107-
DE265_ERROR_NOT_IMPLEMENTED_YET = 502,
108-
//DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED = 502, obsolet
109-
110-
// --- warnings ---
111-
112-
DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING = 1000,
113-
DE265_WARNING_WARNING_BUFFER_FULL=1001,
114-
DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT=1002,
115-
DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET=1003,
116-
DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA=1004,
117-
DE265_WARNING_SPS_HEADER_INVALID=1005,
118-
DE265_WARNING_PPS_HEADER_INVALID=1006,
119-
DE265_WARNING_SLICEHEADER_INVALID=1007,
120-
DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING=1008,
121-
DE265_WARNING_NONEXISTING_PPS_REFERENCED=1009,
122-
DE265_WARNING_NONEXISTING_SPS_REFERENCED=1010,
123-
DE265_WARNING_BOTH_PREDFLAGS_ZERO=1011,
124-
DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED=1012,
125-
DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ=1013,
126-
DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE=1014,
127-
DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE=1015,
128-
DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST=1016,
129-
DE265_WARNING_EOSS_BIT_NOT_SET=1017,
130-
DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED=1018,
131-
DE265_WARNING_INVALID_CHROMA_FORMAT=1019,
132-
DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID=1020,
133-
DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO=1021,
134-
DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM=1022,
135-
DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER=1023,
136-
DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY=1024,
137-
DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI=1025,
138-
DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA=1026
139-
} de265_error;
140-
82+
/* === error code management === */
14183
LIBDE265_API const char* de265_get_error_text(de265_error err);
14284

14385
/* Returns true, if 'err' is DE265_OK or a warning.
@@ -387,6 +329,20 @@ enum de265_param {
387329
//DE265_DECODER_PARAM_DISABLE_INTRA_RESIDUAL_IDCT=10 // (bool) disable decoding of IDCT residuals in MC blocks
388330
};
389331

332+
/* --- callback --- */
333+
struct de265_callback_block
334+
{
335+
void (*get_vps)(video_parameter_set* vps);
336+
void (*get_sps)(seq_parameter_set* sps);
337+
void (*get_pps)(pic_parameter_set* pps);
338+
void (*get_image)(de265_image* img);
339+
};
340+
LIBDE265_API void de265_callback_register(de265_decoder_context*, de265_callback_block*);
341+
LIBDE265_API void de265_callback_unregister(de265_decoder_context*);
342+
343+
/* The user data pointer will be given to the get_buffer() and release_buffer() functions
344+
in de265_image_allocation. */
345+
390346
// sorted such that a large ID includes all optimizations from lower IDs
391347
enum de265_acceleration {
392348
de265_acceleration_SCALAR = 0, // only fallback implementation
@@ -430,8 +386,5 @@ LIBDE265_API de265_error de265_init(void);
430386
LIBDE265_API de265_error de265_free(void);
431387

432388

433-
#ifdef __cplusplus
434-
}
435-
#endif
436389

437390
#endif

libde265/decctx.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ decoder_context::decoder_context()
301301
*/
302302

303303

304+
cbb = NULL;
304305

305306
// --- internal data ---
306307

@@ -540,6 +541,10 @@ de265_error decoder_context::read_vps_NAL(bitreader& reader)
540541
new_vps->dump(param_vps_headers_fd);
541542
}
542543

544+
if (cbb != NULL && cbb->get_vps != NULL) {
545+
cbb->get_vps(new_vps.get());
546+
}
547+
543548
vps[ new_vps->video_parameter_set_id ] = new_vps;
544549

545550
return DE265_OK;
@@ -560,6 +565,10 @@ de265_error decoder_context::read_sps_NAL(bitreader& reader)
560565
new_sps->dump(param_sps_headers_fd);
561566
}
562567

568+
if (cbb != NULL && cbb->get_sps != NULL) {
569+
cbb->get_sps(new_sps.get());
570+
}
571+
563572
sps[ new_sps->seq_parameter_set_id ] = new_sps;
564573

565574
return DE265_OK;
@@ -577,6 +586,10 @@ de265_error decoder_context::read_pps_NAL(bitreader& reader)
577586
new_pps->dump(param_pps_headers_fd);
578587
}
579588

589+
if (cbb != NULL && cbb->get_pps != NULL) {
590+
cbb->get_pps(new_pps.get());
591+
}
592+
580593
if (success) {
581594
pps[ (int)new_pps->pic_parameter_set_id ] = new_pps;
582595
}
@@ -596,6 +609,7 @@ de265_error decoder_context::read_sei_NAL(bitreader& reader, bool suffix)
596609

597610
if ((err=read_sei(&reader,&sei, suffix, current_sps.get())) == DE265_OK) {
598611
dump_sei(&sei, current_sps.get());
612+
// TODO: add SEI callback here
599613

600614
if (image_units.empty()==false && suffix) {
601615
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
635649
shdr->dump_slice_segment_header(this, param_slice_headers_fd);
636650
}
637651

652+
// TODO: add slice_header callback here
638653

639654
if (process_slice_segment_header(shdr, &err, nal->pts, &nal_hdr, nal->user_data) == false)
640655
{
@@ -778,6 +793,9 @@ de265_error decoder_context::decode_some(bool* did_work)
778793
break;
779794
}
780795

796+
if (cbb != NULL && cbb->get_image != NULL) {
797+
cbb->get_image(imgunit->img);
798+
}
781799

782800
push_picture_to_output_queue(imgunit);
783801

@@ -2228,6 +2246,18 @@ void decoder_context::calc_tid_and_framerate_ratio()
22282246
}
22292247

22302248

2249+
void decoder_context::callback_register(de265_callback_block* cbb_)
2250+
{
2251+
cbb = cbb_;
2252+
}
2253+
2254+
2255+
void decoder_context::callback_unregister()
2256+
{
2257+
cbb = NULL;
2258+
}
2259+
2260+
22312261
void error_queue::add_warning(de265_error warning, bool once)
22322262
{
22332263
// check if warning was already shown

libde265/decctx.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,11 @@ class decoder_context : public base_context {
412412
int change_framerate(int more_vs_less); // 1: more, -1: less
413413
void set_framerate_ratio(int percent);
414414

415+
// --- decode callback ---
416+
417+
void callback_register(de265_callback_block* cbb);
418+
void callback_unregister();
419+
415420
private:
416421
// input parameters
417422
int limit_HighestTid; // never switch to a layer above this one
@@ -429,6 +434,8 @@ class decoder_context : public base_context {
429434
} framedrop_tab[100+1];
430435
int framedrop_tid_index[6+1];
431436

437+
de265_callback_block* cbb;
438+
432439
void compute_framedrop_table();
433440
void calc_tid_and_framerate_ratio();
434441

libde265/en265.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
#ifndef EN265_H
2424
#define EN265_H
2525

26-
#ifdef __cplusplus
27-
extern "C" {
28-
#endif
29-
3026
#include <libde265/de265.h>
3127

3228

@@ -210,9 +206,5 @@ LIBDE265_API void en265_free_packet(en265_encoder_context*, struct en265_packet*
210206

211207
LIBDE265_API int en265_number_of_queued_packets(en265_encoder_context*);
212208

213-
#ifdef __cplusplus
214-
}
215-
#endif
216-
217209

218210
#endif

libde265/sps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "libde265/vui.h"
2626
#include "libde265/bitstream.h"
2727
#include "libde265/refpic.h"
28-
#include "libde265/de265.h"
28+
#include "libde265/de265-error.h"
2929
#include "libde265/cabac.h"
3030

3131
#include <vector>

libde265/vps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#endif
3131

3232
#include "libde265/bitstream.h"
33-
#include "libde265/de265.h"
33+
#include "libde265/de265-error.h"
3434
#include "libde265/cabac.h"
3535

3636
#include <vector>

0 commit comments

Comments
 (0)