1 /*****************************************************************************
2  * api.c: bit depth independent interface
3  *****************************************************************************
4  * Copyright (C) 2003-2021 x264 project
5  *
6  * Authors: Vittorio Giovara <vittorio.giovara@gmail.com>
7  *          Luca Barbato <lu_zero@gentoo.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *
23  * This program is also available under a commercial proprietary license.
24  * For more information, contact us at licensing@x264.com.
25  *****************************************************************************/
26 
27 #include "common/base.h"
28 
29 /****************************************************************************
30  * global symbols
31  ****************************************************************************/
32 const int x264_chroma_format = X264_CHROMA_FORMAT;
33 
34 x264_t *x264_8_encoder_open( x264_param_t *, void * );
35 void x264_8_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal );
36 int  x264_8_encoder_reconfig( x264_t *, x264_param_t * );
37 void x264_8_encoder_parameters( x264_t *, x264_param_t * );
38 int  x264_8_encoder_headers( x264_t *, x264_nal_t **pp_nal, int *pi_nal );
39 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 );
40 void x264_8_encoder_close( x264_t * );
41 int  x264_8_encoder_delayed_frames( x264_t * );
42 int  x264_8_encoder_maximum_delayed_frames( x264_t * );
43 void x264_8_encoder_intra_refresh( x264_t * );
44 int  x264_8_encoder_invalidate_reference( x264_t *, int64_t pts );
45 
46 x264_t *x264_10_encoder_open( x264_param_t *, void * );
47 void x264_10_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal );
48 int  x264_10_encoder_reconfig( x264_t *, x264_param_t * );
49 void x264_10_encoder_parameters( x264_t *, x264_param_t * );
50 int  x264_10_encoder_headers( x264_t *, x264_nal_t **pp_nal, int *pi_nal );
51 int  x264_10_encoder_encode( x264_t *, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out );
52 void x264_10_encoder_close( x264_t * );
53 int  x264_10_encoder_delayed_frames( x264_t * );
54 int  x264_10_encoder_maximum_delayed_frames( x264_t * );
55 void x264_10_encoder_intra_refresh( x264_t * );
56 int  x264_10_encoder_invalidate_reference( x264_t *, int64_t pts );
57 
58 typedef struct x264_api_t
59 {
60     /* Internal reference to x264_t data */
61     x264_t *x264;
62 
63     /* API entry points */
64     void (*nal_encode)( x264_t *h, uint8_t *dst, x264_nal_t *nal );
65     int  (*encoder_reconfig)( x264_t *, x264_param_t * );
66     void (*encoder_parameters)( x264_t *, x264_param_t * );
67     int  (*encoder_headers)( x264_t *, x264_nal_t **pp_nal, int *pi_nal );
68     int  (*encoder_encode)( x264_t *, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out );
69     void (*encoder_close)( x264_t * );
70     int  (*encoder_delayed_frames)( x264_t * );
71     int  (*encoder_maximum_delayed_frames)( x264_t * );
72     void (*encoder_intra_refresh)( x264_t * );
73     int  (*encoder_invalidate_reference)( x264_t *, int64_t pts );
74 } x264_api_t;
75 
x264_encoder_open(x264_param_t * param)76 REALIGN_STACK x264_t *x264_encoder_open( x264_param_t *param )
77 {
78     x264_api_t *api = calloc( 1, sizeof( x264_api_t ) );
79     if( !api )
80         return NULL;
81 
82     if( HAVE_BITDEPTH8 && param->i_bitdepth == 8 )
83     {
84         api->nal_encode = x264_8_nal_encode;
85         api->encoder_reconfig = x264_8_encoder_reconfig;
86         api->encoder_parameters = x264_8_encoder_parameters;
87         api->encoder_headers = x264_8_encoder_headers;
88         api->encoder_encode = x264_8_encoder_encode;
89         api->encoder_close = x264_8_encoder_close;
90         api->encoder_delayed_frames = x264_8_encoder_delayed_frames;
91         api->encoder_maximum_delayed_frames = x264_8_encoder_maximum_delayed_frames;
92         api->encoder_intra_refresh = x264_8_encoder_intra_refresh;
93         api->encoder_invalidate_reference = x264_8_encoder_invalidate_reference;
94 
95         api->x264 = x264_8_encoder_open( param, api );
96     }
97     else if( HAVE_BITDEPTH10 && param->i_bitdepth == 10 )
98     {
99         api->nal_encode = x264_10_nal_encode;
100         api->encoder_reconfig = x264_10_encoder_reconfig;
101         api->encoder_parameters = x264_10_encoder_parameters;
102         api->encoder_headers = x264_10_encoder_headers;
103         api->encoder_encode = x264_10_encoder_encode;
104         api->encoder_close = x264_10_encoder_close;
105         api->encoder_delayed_frames = x264_10_encoder_delayed_frames;
106         api->encoder_maximum_delayed_frames = x264_10_encoder_maximum_delayed_frames;
107         api->encoder_intra_refresh = x264_10_encoder_intra_refresh;
108         api->encoder_invalidate_reference = x264_10_encoder_invalidate_reference;
109 
110         api->x264 = x264_10_encoder_open( param, api );
111     }
112     else
113         x264_log_internal( X264_LOG_ERROR, "not compiled with %d bit depth support\n", param->i_bitdepth );
114 
115     if( !api->x264 )
116     {
117         free( api );
118         return NULL;
119     }
120 
121     /* x264_t is opaque */
122     return (x264_t *)api;
123 }
124 
x264_encoder_close(x264_t * h)125 REALIGN_STACK void x264_encoder_close( x264_t *h )
126 {
127     x264_api_t *api = (x264_api_t *)h;
128 
129     api->encoder_close( api->x264 );
130     free( api );
131 }
132 
x264_nal_encode(x264_t * h,uint8_t * dst,x264_nal_t * nal)133 REALIGN_STACK void x264_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal )
134 {
135     x264_api_t *api = (x264_api_t *)h;
136 
137     api->nal_encode( api->x264, dst, nal );
138 }
139 
x264_encoder_reconfig(x264_t * h,x264_param_t * param)140 REALIGN_STACK int x264_encoder_reconfig( x264_t *h, x264_param_t *param)
141 {
142     x264_api_t *api = (x264_api_t *)h;
143 
144     return api->encoder_reconfig( api->x264, param );
145 }
146 
x264_encoder_parameters(x264_t * h,x264_param_t * param)147 REALIGN_STACK void x264_encoder_parameters( x264_t *h, x264_param_t *param )
148 {
149     x264_api_t *api = (x264_api_t *)h;
150 
151     api->encoder_parameters( api->x264, param );
152 }
153 
x264_encoder_headers(x264_t * h,x264_nal_t ** pp_nal,int * pi_nal)154 REALIGN_STACK int x264_encoder_headers( x264_t *h, x264_nal_t **pp_nal, int *pi_nal )
155 {
156     x264_api_t *api = (x264_api_t *)h;
157 
158     return api->encoder_headers( api->x264, pp_nal, pi_nal );
159 }
160 
x264_encoder_encode(x264_t * h,x264_nal_t ** pp_nal,int * pi_nal,x264_picture_t * pic_in,x264_picture_t * pic_out)161 REALIGN_STACK 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 )
162 {
163     x264_api_t *api = (x264_api_t *)h;
164 
165     return api->encoder_encode( api->x264, pp_nal, pi_nal, pic_in, pic_out );
166 }
167 
x264_encoder_delayed_frames(x264_t * h)168 REALIGN_STACK int x264_encoder_delayed_frames( x264_t *h )
169 {
170     x264_api_t *api = (x264_api_t *)h;
171 
172     return api->encoder_delayed_frames( api->x264 );
173 }
174 
x264_encoder_maximum_delayed_frames(x264_t * h)175 REALIGN_STACK int x264_encoder_maximum_delayed_frames( x264_t *h )
176 {
177     x264_api_t *api = (x264_api_t *)h;
178 
179     return api->encoder_maximum_delayed_frames( api->x264 );
180 }
181 
x264_encoder_intra_refresh(x264_t * h)182 REALIGN_STACK void x264_encoder_intra_refresh( x264_t *h )
183 {
184     x264_api_t *api = (x264_api_t *)h;
185 
186     api->encoder_intra_refresh( api->x264 );
187 }
188 
x264_encoder_invalidate_reference(x264_t * h,int64_t pts)189 REALIGN_STACK int x264_encoder_invalidate_reference( x264_t *h, int64_t pts )
190 {
191     x264_api_t *api = (x264_api_t *)h;
192 
193     return api->encoder_invalidate_reference( api->x264, pts );
194 }
195