LiVES  3.2.0
decplugin.h
Go to the documentation of this file.
1 // LiVES - decoder plugin header
2 // (c) G. Finch 2008 - 2020 <salsaman+lives@gmail.com>
3 // released under the GNU GPL 3 or later
4 // see file COPYING or www.gnu.org for details
5 
6 #ifndef __DECPLUGIN_H__
7 #define __DECPLUGIN_H__
8 
9 #ifdef __cplusplus
10 extern "C"
11 {
12 #endif /* __cplusplus */
13 
14 #define DEC_PLUGIN_VERSION_MAJOR 3
15 #define DEC_PLUGIN_VERSION_MINOR 0
16 
17 #include <inttypes.h>
18 #include <sys/types.h>
19 #include <string.h>
20 #include <stdio.h>
21 
22 #ifndef ALLOW_UNUSED
23 #ifdef __GNUC__
24 # define ALLOW_UNUSED __attribute__((unused))
25 #else
26 # define ALLOW_UNUSED
27 #endif
28 #endif
29 
30 // palettes, etc. :: don't include weed-compat.h, since plugins need to #define stuff first
31 #ifdef NEED_LOCAL_WEED
32 #include "../../../libweed/weed-palettes.h"
33 #else
34 #include <weed/weed-palettes.h>
35 #endif
36 
37 #if defined (IS_DARWIN) || defined (__FreeBSD__)
38 #ifndef lseek64
39 #define lseek64 lseek
40 #endif
41 #ifndef off64_t
42 #define off64_t off_t
43 #endif
44 #endif
45 
46 typedef int boolean;
47 #undef TRUE
48 #undef FALSE
49 #define TRUE 1
50 #define FALSE 0
51 
52 typedef enum {
57 
58 typedef struct {
60  // a value > 0. indicates some values are set. Unset values may be left as 0., or
63 
64  double ctiming_ratio; // dynamic multiplier for timing info, depends on machine load and other factors.
65  double idecode_time;
66  double kdecode_time;
67  double buffer_flush_time;
68  double kframe_nseek_time;
69  double kframe_delay_time;
70 
71  double kframe_kframe_time;
72  double kframe_inter_time;
73  double kframe_extra_time;
74 
75  // examples:
76  // iframe to next kframe with decode: kframe_nseek_time + n * kframe_delay_time + buffer_flush_tome + kdecode_time
77  // where n is the number of iframes skipped over
78 
79  // seek from iframe to another iframe, passing over several kframes, decoding frames from final kframe to target
80 
86 
87  double xvals[64];
88 } adv_timing_t;
89 
91 #define LIVES_SEEK_FAST (1<<0)
92 #define LIVES_SEEK_FAST_REV (1<<1)
93 
95 #define LIVES_SEEK_NEEDS_CALCULATION (1<<2)
96 #define LIVES_SEEK_QUALITY_LOSS (1<<3)
97 
98 // memfuncs
99 typedef void *(*malloc_f)(size_t);
100 typedef void (*free_f)(void *);
101 typedef void *(*memset_f)(void *, int, size_t);
102 typedef void *(*memcpy_f)(void *, const void *, size_t);
103 typedef void *(*realloc_f)(void *, size_t);
104 typedef void *(*calloc_f)(size_t, size_t);
105 typedef void *(*memmove_f)(void *, const void *, size_t);
106 
107 
108 #if defined NEED_TIMING || !defined HAVE_GETENTROPY
109 
110 #ifdef _POSIX_TIMERS
111 #include <time.h>
112 #else
113 #include <sys/time.h>
114 #endif
115 
116 static inline int64_t get_current_ticks(void) {
117  int64_t ret;
118 #if _POSIX_TIMERS
119  struct timespec ts;
120  clock_gettime(CLOCK_MONOTONIC, &ts);
121  ret = ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
122 #else
123  struct timeval tv;
124  gettimeofday(&tv, NULL);
125  ret = tv.tv_sec * 1000000 + tv.tv_usec;
126 #endif
127  return ret;
128 }
129 #endif
130 
131 #ifndef HAVE_GETENTROPY
132 
133 #include <string.h>
134 
135 #define myfastrand1(fval) ((fval) ^ ((fval) << 13))
136 #define myfastrand2(fval) ((fval) ^ ((fval) >> 7))
137 #define myfastrand3(fval) ((fval) ^ ((fval) << 17))
138 #define myfastrand0(fval) (myfastrand3(myfastrand2(myfastrand1((fval)))))
139 
140 static inline void myrand(void *ptr, size_t size) {
141  static uint64_t fval = 0;
142  if (fval == 0) {
143  fval = 0xAAAAAAAAAAAAAAAA ^ (get_current_ticks() >> 17);
144  }
145  fval = myfastrand0(fval);
146  memcpy(ptr, &fval, size);
147 }
148 
149 #define LSD_RANDFUNC(ptr, size) myrand(ptr, size)
150 #endif
151 
152 #include "../../../src/lsd.h"
153 
154 #define PLUGIN_TYPE_DECODER "decoder"
155 #define PLUGIN_SUBTYPE_DLL "dll"
156 
157 typedef struct {
158  char type[16];
159  char subtype[16];
160  int api_version_major;
161  int api_version_minor;
162  char name[64];
163  int pl_version_major;
164  int pl_version_minor;
165  void *capabilities;
167 
168 
169 typedef struct _lives_clip_data {
170  // fixed part
171  lives_struct_def_t lsd;
172  lives_plugin_id_t plugin_id;
173 
174  malloc_f *ext_malloc;
175  free_f *ext_free;
176  memcpy_f *ext_memcpy;
177  memset_f *ext_memset;
178  memmove_f *ext_memmove;
179  realloc_f *ext_realloc;
180  calloc_f *ext_calloc;
181 
182  void *priv;
183 
184  char *URI;
185 
186  int nclips;
187  char container_name[512];
188 
189  char title[1024];
190  char author[1024];
191  char comment[1024];
192 
194  int current_clip;
195 
196  // video data
197  int width;
198  int height;
199  int64_t nframes;
200  lives_interlace_t interlace;
201  int *rec_rowstrides;
202 
205  int offs_x;
206  int offs_y;
207  int frame_width;
208  int frame_height;
209 
210  float par;
211 
212  float video_start_time;
213 
214  float fps;
215 
217  float max_decode_fps;
218  int64_t fwd_seek_time;
219  int64_t jump_limit;
220 
221  int64_t kframe_start;
222  int64_t kframe_dist;
223 
225  int *palettes;
226 
228  int current_palette;
229 
231  int YUV_sampling;
232  int YUV_clamping;
233  int YUV_subspace;
234  int frame_gamma;
235 
236  char video_name[512];
237 
238  /* audio data */
239  int arate;
240  int achans;
241  int asamps;
242  boolean asigned;
243  boolean ainterleaf;
244  char audio_name[512];
245 
247  int seek_flag;
248 
249 #define SYNC_HINT_AUDIO_TRIM_START (1<<0)
250 #define SYNC_HINT_AUDIO_PAD_START (1<<1)
251 #define SYNC_HINT_AUDIO_TRIM_END (1<<2)
252 #define SYNC_HINT_AUDIO_PAD_END (1<<3)
253 
254 #define SYNC_HINT_VIDEO_PAD_START (1<<4)
255 #define SYNC_HINT_VIDEO_PAD_END (1<<5)
256 
257  int sync_hint;
258 
260 
261 // std functions
262 const char *version(void);
263 
268 
269 // should be threadsafe, and clip_data should be freed with clip_data_free() when no longer required
270 
272 
274 boolean get_frame(const lives_clip_data_t *, int64_t frame, int *rowstrides, int height, void **pixel_data);
275 
277 boolean chill_out(const lives_clip_data_t *cdata);
278 
281 
282 // opt fns //////////////////////////////////////////
283 
284 const char *module_check_init(void);
285 
287 
288 int64_t rip_audio(const lives_clip_data_t *, const char *fname, int64_t stframe, int64_t nframes, unsigned char **abuff);
289 boolean rip_audio_sequential(const lives_clip_data_t *, const char *fname);
291 
292 void module_unload(void);
293 
294 // little-endian
295 #define get_le16int(p) (*(p + 1) << 8 | *(p))
296 #define get_le32int(p) ((get_le16int(p + 2) << 16) | get_le16int(p))
297 #define get_le64int(p) (int64_t)(((uint64_t)(get_le32int(p + 4)) << 32) | (uint64_t)(get_le32int(p)))
298 
299 #define ABS(a) ((a) >= 0. ? (a) : -(a))
300 
301 double get_fps(const char *uri);
302 
308 };
309 
310 #ifdef NEED_CLONEFUNC
311 #define CREATOR_ID "LiVES decoder plugin"
312 static const lives_struct_def_t *cdata_lsd = NULL;
313 
314 static void make_acid(void) {
315  cdata_lsd = lsd_create("lives_clip_data_t", sizeof(lives_clip_data_t), "sync_hint", 6);
316  if (!cdata_lsd) return;
317  else {
318  lives_special_field_t **specf = cdata_lsd->special_fields;
319  lives_clip_data_t *cdata = (lives_clip_data_t *)calloc(1, sizeof(lives_clip_data_t));
320  specf[0] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY
321  | LIVES_FIELD_FLAG_FREE_ON_DELETE, cdata, &cdata->priv,
322  "priv", 0, NULL, NULL, NULL);
323  specf[1] = make_special_field(LIVES_FIELD_CHARPTR, cdata, &cdata->URI,
324  "URI", 0, NULL, NULL, NULL);
325  specf[2] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY, cdata, &cdata->title,
326  "title", 1024, NULL, NULL, NULL);
327  specf[3] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY, cdata, &cdata->author,
328  "author", 1024, NULL, NULL, NULL);
329  specf[4] = make_special_field(LIVES_FIELD_FLAG_ZERO_ON_COPY, cdata, &cdata->comment,
330  "comment", 1024, NULL, NULL, NULL);
331  specf[5] = make_special_field(LIVES_FIELD_ARRAY, cdata, &cdata->palettes,
332  "palettes", 4, NULL, NULL, NULL);
333  lives_struct_init(cdata_lsd, cdata, &cdata->lsd);
334  free(cdata);
335  lives_struct_set_class_data((lives_struct_def_t *)cdata_lsd, CREATOR_ID);
336  }
337 }
338 #endif
339 
340 static lives_clip_data_t *cdata_new(lives_clip_data_t *data) {
341  lives_clip_data_t *cdata;
342  if (data) cdata = data;
343  else {
344 #ifdef NEED_CLONEFUNC
345  if (!cdata_lsd) make_acid();
346  if (!cdata_lsd) return NULL;
347  cdata = lives_struct_create(cdata_lsd);
348 #else
349  cdata = calloc(1, sizeof(lives_clip_data_t));
350 #endif
351  }
352  if (cdata) {
353  snprintf(cdata->plugin_id.type, 16, "%s", PLUGIN_TYPE_DECODER);
354  snprintf(cdata->plugin_id.subtype, 16, "%s", PLUGIN_SUBTYPE_DLL);
357  }
358  return cdata;
359 }
360 
361 static void cdata_stamp(lives_clip_data_t *cdata, const char *name, int vmaj, int vmin) {
362  snprintf(cdata->plugin_id.name, 32, "%s", name);
363  cdata->plugin_id.pl_version_major = vmaj;
364  cdata->plugin_id.pl_version_minor = vmin;
365 }
366 
367 #ifdef NEED_CLONEFUNC
368 static lives_clip_data_t *clone_cdata(const lives_clip_data_t *cdata) {
369  if (!cdata) return NULL;
370  if (!cdata_lsd) make_acid();
371  return lives_struct_copy((void *)&cdata->lsd);
372 }
373 #endif
374 
375 #ifdef __cplusplus
376 }
377 #endif /* __cplusplus */
378 
379 #endif // #ifndef __DECPLUGIN_H__
lives_struct_def_t
112 bytes
Definition: lsd.h:241
memcpy_f
void *(* memcpy_f)(void *, const void *, size_t)
Definition: decplugin.h:102
lives_plugin_id_t::api_version_major
int api_version_major
version of interface API
Definition: plugins.h:86
get_clip_data
lives_clip_data_t * get_clip_data(const char *URI, lives_clip_data_t *)
pass in NULL clip_data for the first call, subsequent calls (if the URI, current_clip or current_pale...
lives_plugin_id_t::subtype
char subtype[16]
e.g. "dll"
Definition: plugins.h:85
lives_clip_data_t::URI
char * URI
the URI of this cdata
Definition: plugins.h:334
rip_audio_sequential
boolean rip_audio_sequential(const lives_clip_data_t *, const char *fname)
lives_clip_data_t::title
char title[1024]
Definition: plugins.h:339
boolean
int boolean
Definition: decplugin.h:46
lives_clip_data_t::palettes
int * palettes
number forames from one keyframe to the next, 0 if unknown
Definition: plugins.h:375
LIVES_MEDIA_TYPE_VIDEO
@ LIVES_MEDIA_TYPE_VIDEO
Definition: decplugin.h:305
rip_audio
int64_t rip_audio(const lives_clip_data_t *, const char *fname, int64_t stframe, int64_t nframes, unsigned char **abuff)
adv_timing_t
Definition: plugins.h:272
LIVES_FIELD_CHARPTR
#define LIVES_FIELD_CHARPTR
Definition: lsd.h:171
free_f
void(* free_f)(void *)
Definition: decplugin.h:100
chill_out
boolean chill_out(const lives_clip_data_t *cdata)
free buffers when we arent playing sequentially / on standby
LIVES_FIELD_FLAG_ZERO_ON_COPY
#define LIVES_FIELD_FLAG_ZERO_ON_COPY
Definition: lsd.h:119
LIVES_INTERLACE_TOP_FIRST
@ LIVES_INTERLACE_TOP_FIRST
Definition: decplugin.h:55
lives_special_field_t
Definition: lsd.h:228
LIVES_MEDIA_TYPE_AUDIO
@ LIVES_MEDIA_TYPE_AUDIO
Definition: decplugin.h:306
lives_clip_data_t::lsd
lives_struct_def_t lsd
Definition: plugins.h:321
tv
struct timeval tv
Definition: main.h:1136
LIVES_INTERLACE_NONE
@ LIVES_INTERLACE_NONE
Definition: decplugin.h:53
lives_interlace_t
lives_interlace_t
Definition: main.h:790
version
const char * version(void)
module_check_init
const char * module_check_init(void)
malloc_f
void *(* malloc_f)(size_t)
Definition: decplugin.h:99
get_fps
double get_fps(const char *uri)
lives_interlace_t
lives_interlace_t
Definition: decplugin.h:52
realloc_f
void *(* realloc_f)(void *, size_t)
Definition: decplugin.h:103
lives_clip_data_t::priv
void * priv
Definition: plugins.h:332
PLUGIN_TYPE_DECODER
#define PLUGIN_TYPE_DECODER
Definition: decplugin.h:154
clip_data_free
void clip_data_free(lives_clip_data_t *)
free clip data - this should be called for each instance before unloading the module
set_palette
boolean set_palette(lives_clip_data_t *)
PLUGIN_SUBTYPE_DLL
#define PLUGIN_SUBTYPE_DLL
Definition: decplugin.h:155
lives_plugin_id_t::name
char name[64]
e.g. "mkv_decoder"
Definition: plugins.h:88
LIVES_MEDIA_TYPE_DATA
@ LIVES_MEDIA_TYPE_DATA
Definition: decplugin.h:307
LIVES_FIELD_FLAG_FREE_ON_DELETE
#define LIVES_FIELD_FLAG_FREE_ON_DELETE
< field wiill be freed in lives_struct_delete free(struct->field)
Definition: lsd.h:124
lives_plugin_id_t::type
char type[16]
e.g. "decoder"
Definition: plugins.h:84
rip_audio_cleanup
void rip_audio_cleanup(const lives_clip_data_t *)
get_frame
boolean get_frame(const lives_clip_data_t *, int64_t frame, int *rowstrides, int height, void **pixel_data)
frame starts at 0
lives_clip_data_t
Definition: plugins.h:319
LIVES_MEDIA_TYPE_UNKNOWN
@ LIVES_MEDIA_TYPE_UNKNOWN
Definition: decplugin.h:304
lives_clip_data_t::plugin_id
lives_plugin_id_t plugin_id
Definition: plugins.h:322
lives_clip_data_t::comment
char comment[1024]
Definition: plugins.h:341
CREATOR_ID
#define CREATOR_ID
Definition: lsd-tab.c:13
DEC_PLUGIN_VERSION_MAJOR
#define DEC_PLUGIN_VERSION_MAJOR
Definition: decplugin.h:14
lives_plugin_id_t::pl_version_major
int pl_version_major
version of plugin
Definition: plugins.h:89
memmove_f
void *(* memmove_f)(void *, const void *, size_t)
Definition: decplugin.h:105
lives_struct_def_t::special_fields
lives_special_field_t ** special_fields
user_data for delete_struct_callback
Definition: lsd.h:263
lives_plugin_id_t
Definition: plugins.h:83
calloc_f
void *(* calloc_f)(size_t, size_t)
Definition: decplugin.h:104
DEC_PLUGIN_VERSION_MINOR
#define DEC_PLUGIN_VERSION_MINOR
Definition: decplugin.h:15
lives_clip_data_t::author
char author[1024]
Definition: plugins.h:340
LIVES_FIELD_ARRAY
#define LIVES_FIELD_ARRAY
Definition: lsd.h:174
lives_plugin_id_t::capabilities
void * capabilities
for future use
Definition: decplugin.h:165
module_unload
void module_unload(void)
myfastrand0
#define myfastrand0(fval)
Definition: decplugin.h:138
lives_plugin_id_t::pl_version_minor
int pl_version_minor
Definition: plugins.h:90
memset_f
void *(* memset_f)(void *, int, size_t)
Definition: decplugin.h:101
LiVESMediaType
LiVESMediaType
Definition: decplugin.h:303
LIVES_INTERLACE_BOTTOM_FIRST
@ LIVES_INTERLACE_BOTTOM_FIRST
Definition: decplugin.h:54