[x264-devel] [PATCH 17/29] Templatize the public API

Vittorio Giovara vittorio.giovara at gmail.com
Thu Feb 2 10:05:29 CET 2017


Include an implementation file to wrap the appropriate calls. The
current API calls are renamed according to the compiled bitdepth value.
This file allocates an internal structure and calls the main API entry points.

In upcoming commits more functions will be renamed and this file will
support and  use the correct function depending on bitdepth value set at
runtime.
---
 Makefile          |   2 +-
 common/api.c      | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 common/common.h   |  15 +++++
 common/osdep.h    |   5 ++
 encoder/encoder.c |   3 +
 5 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 common/api.c

diff --git a/Makefile b/Makefile
index f039fcc..d93ce95 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ SRCS = common/mc.c common/predict.c common/pixel.c common/macroblock.c \
        common/set.c common/quant.c common/deblock.c common/vlc.c \
        common/mvpred.c common/bitstream.c \
        common/log.c common/mem.c common/picture.c common/mathematics.c \
-       common/param.c common/tables.c \
+       common/param.c common/tables.c common/api.c \
        encoder/analyse.c encoder/me.c encoder/ratecontrol.c \
        encoder/set.c encoder/macroblock.c encoder/cabac.c \
        encoder/cavlc.c encoder/encoder.c encoder/lookahead.c
diff --git a/common/api.c b/common/api.c
new file mode 100644
index 0000000..4a08d1e
--- /dev/null
+++ b/common/api.c
@@ -0,0 +1,165 @@
+/*****************************************************************************
+ * api.c: bitdepth-independent interface
+ *****************************************************************************
+ * Copyright (C) 2003-2017 x264 project
+ *
+ * Authors: Vittorio Giovara <vittorio.giovara at gmail.com>
+ *          Luca Barbato <lu_zero at gentoo.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
+ *
+ * This program is also available under a commercial proprietary license.
+ * For more information, contact us at licensing at x264.com.
+ *****************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "x264.h"
+
+x264_t *x264_8_encoder_open( x264_param_t * );
+void x264_8_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal );
+int  x264_8_encoder_reconfig( x264_t *, x264_param_t * );
+void x264_8_encoder_parameters( x264_t *, x264_param_t * );
+int  x264_8_encoder_headers( x264_t *, x264_nal_t **pp_nal, int *pi_nal );
+int  x264_8_encoder_encode( x264_t *, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out );
+void x264_8_encoder_close( x264_t * );
+int  x264_8_encoder_delayed_frames( x264_t * );
+int  x264_8_encoder_maximum_delayed_frames( x264_t *h );
+void x264_8_encoder_intra_refresh( x264_t * );
+int  x264_8_encoder_invalidate_reference( x264_t *, int64_t pts );
+
+typedef struct x264_api_t {
+    /* Internal reference to x264_t data */
+    void *x264;
+
+    /* API entry points */
+    void (*x264_nal_encode) ( x264_t *h, uint8_t *dst, x264_nal_t *nal );
+    int  (*x264_encoder_reconfig) ( x264_t *, x264_param_t * );
+    void (*x264_encoder_parameters) ( x264_t *, x264_param_t * );
+    int  (*x264_encoder_headers) ( x264_t *, x264_nal_t **pp_nal, int *pi_nal );
+    int  (*x264_encoder_encode) ( x264_t *, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out );
+    void (*x264_encoder_close) ( x264_t * );
+    int  (*x264_encoder_delayed_frames) ( x264_t * );
+    int  (*x264_encoder_maximum_delayed_frames) ( x264_t *h );
+    void (*x264_encoder_intra_refresh) ( x264_t * );
+    int  (*x264_encoder_invalidate_reference) ( x264_t *, int64_t pts );
+} x264_api_t;
+
+x264_t *x264_encoder_open( x264_param_t *param )
+{
+    x264_api_t *api;
+
+    api = calloc( 1, sizeof(x264_api_t) );
+    if( !api )
+        return NULL;
+
+    if( param->i_bitdepth == 0 || param->i_bitdepth == 8 ) {
+        api->x264_encoder_reconfig = x264_8_encoder_reconfig;
+        api->x264_encoder_parameters = x264_8_encoder_parameters;
+        api->x264_encoder_headers = x264_8_encoder_headers;
+        api->x264_encoder_encode = x264_8_encoder_encode;
+        api->x264_encoder_close = x264_8_encoder_close;
+        api->x264_encoder_delayed_frames = x264_8_encoder_delayed_frames;
+        api->x264_encoder_maximum_delayed_frames = x264_8_encoder_maximum_delayed_frames;
+        api->x264_encoder_intra_refresh = x264_8_encoder_intra_refresh;
+        api->x264_encoder_invalidate_reference = x264_8_encoder_invalidate_reference;
+
+        api->x264 = x264_8_encoder_open( param );
+    } else if( param->i_bitdepth == 10 ) {
+        x264_log_internal( NULL, "Not yet implemented\n");
+    }
+
+    if( !api->x264 ) {
+        x264_encoder_close( (x264_t *) api );
+        return NULL;
+    }
+
+    /* x264_t is opaque */
+    return (x264_t *) api;
+}
+
+void x264_encoder_close( x264_t *h )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    if( api->x264_encoder_close && api->x264 )
+        api->x264_encoder_close( api->x264 );
+
+    free( h );
+}
+
+void x264_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    api->x264_nal_encode( api->x264, dst, nal );
+}
+
+int x264_encoder_reconfig( x264_t *h, x264_param_t *param)
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    return api->x264_encoder_reconfig( api->x264, param );
+}
+
+void x264_encoder_parameters( x264_t *h, x264_param_t *param )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    api->x264_encoder_parameters( api->x264, param );
+}
+
+int x264_encoder_headers( x264_t *h, x264_nal_t **pp_nal, int *pi_nal )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    return api->x264_encoder_headers( api->x264, pp_nal, pi_nal );
+}
+
+int x264_encoder_encode( x264_t *h, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    return api->x264_encoder_encode( api->x264, pp_nal, pi_nal, pic_in, pic_out );
+}
+
+int x264_encoder_delayed_frames( x264_t *h )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    return api->x264_encoder_delayed_frames( api->x264 );
+}
+
+int x264_encoder_maximum_delayed_frames( x264_t *h )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    return api->x264_encoder_maximum_delayed_frames( api->x264 );
+}
+
+void x264_encoder_intra_refresh( x264_t *h )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    api->x264_encoder_intra_refresh( api->x264 );
+}
+
+int x264_encoder_invalidate_reference( x264_t *h, int64_t pts )
+{
+    x264_api_t *api = (x264_api_t *)h;
+
+    return api->x264_encoder_invalidate_reference( api->x264, pts );
+}
diff --git a/common/common.h b/common/common.h
index db5c47b..dd9f136 100644
--- a/common/common.h
+++ b/common/common.h
@@ -117,6 +117,21 @@ do {\
 #include <assert.h>
 #include <limits.h>
 
+/****************************************************************************
+ * API Templates
+ ****************************************************************************/
+#define x264_encoder_open x264_template(encoder_open)
+#define x264_nal_encode x264_template(nal_encode)
+#define x264_encoder_reconfig x264_template(encoder_reconfig)
+#define x264_encoder_parameters x264_template(encoder_parameters)
+#define x264_encoder_headers x264_template(encoder_headers)
+#define x264_encoder_encode x264_template(encoder_encode)
+#define x264_encoder_close x264_template(encoder_close)
+#define x264_encoder_delayed_frames x264_template(encoder_delayed_frames)
+#define x264_encoder_maximum_delayed_frames x264_template(encoder_maximum_delayed_frames)
+#define x264_encoder_intra_refresh x264_template(encoder_intra_refresh)
+#define x264_encoder_invalidate_reference x264_template(encoder_invalidate_reference)
+
 #if HAVE_INTERLACED
 #   define MB_INTERLACED h->mb.b_interlaced
 #   define SLICE_MBAFF h->sh.b_mbaff
diff --git a/common/osdep.h b/common/osdep.h
index 9544401..9a6978a 100644
--- a/common/osdep.h
+++ b/common/osdep.h
@@ -103,6 +103,11 @@ int x264_is_pipe( const char *path );
 #define x264_is_pipe(x) 0
 #endif
 
+/* Macros for templating function calls according to bitdepth */
+#define x264_glue3_expand(x,y,z) x##_##y##_##z
+#define x264_glue3(x,y,z) x264_glue3_expand(x,y,z)
+#define x264_template(w) x264_glue3(x264,BIT_DEPTH,w)
+
 #ifdef _MSC_VER
 #define DECLARE_ALIGNED( var, n ) __declspec(align(n)) var
 #else
diff --git a/encoder/encoder.c b/encoder/encoder.c
index cc6217a..7edd671 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -40,6 +40,9 @@
 
 #define bs_write_ue bs_write_ue_big
 
+// forward declaration need for template usage
+void x264_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal );
+
 static int encoder_frame_end( x264_t *h, x264_t *thread_current,
                               x264_nal_t **pp_nal, int *pi_nal,
                               x264_picture_t *pic_out );
-- 
2.10.0



More information about the x264-devel mailing list