#include <vlc_common.h>
#include <vlc_plugin.h>
+#include <vlc_access.h>
#include <vlc_demux.h>
#include <vlc_charset.h>
/*****************************************************************************
* Module descriptior
*****************************************************************************/
+static int OpenAccess (vlc_object_t *);
+static void CloseAccess(vlc_object_t *);
+
static int OpenDemux (vlc_object_t *);
static void CloseDemux(vlc_object_t *);
#define CAT_LONGTEXT N_(\
"Set the category of the elementary stream")
static const int cat_values[] = {
- 0, 1, 2, 3
+ 0, 1, 2, 3, 4,
};
static const char *cat_texts[] = {
- N_("Unknown"), N_("Audio"), N_("Video"), N_("Subtitle")
+ N_("Unknown"), N_("Audio"), N_("Video"), N_("Subtitle"), N_("Data")
};
#define CODEC_TEXT N_("Codec")
#define RELEASE_LONGTEXT N_(\
"Address of the release callback function")
+#define SIZE_TEXT N_("Size")
+#define SIZE_LONGTEXT N_(\
+ "Size of stream in bytes")
+
vlc_module_begin()
set_shortname(N_("Memory input"))
set_description(N_("Memory input"))
change_private()
change_safe()
+ add_integer ("imem-size", 0, NULL, SIZE_TEXT, SIZE_LONGTEXT, true)
+ change_private()
+ change_safe()
+
add_shortcut("imem")
set_capability("access_demux", 0)
set_callbacks(OpenDemux, CloseDemux)
+
+ add_submodule()
+ add_shortcut("imem")
+ set_capability("access", 0)
+ set_callbacks(OpenAccess, CloseAccess)
vlc_module_end()
/*****************************************************************************
*****************************************************************************/
/* */
+static block_t *Block(access_t *);
+static int ControlAccess(access_t *, int, va_list);
+
static int Demux(demux_t *);
static int ControlDemux(demux_t *, int, va_list);
} imem_sys_t;
static void ParseMRL(vlc_object_t *, const char *);
-#define var_CreateGetRational(a,b,c,d) var_CreateGetRational(VLC_OBJECT(a),b,c,d)
-static int (var_CreateGetRational)(vlc_object_t *,
- unsigned *num, unsigned *den,
- const char *var);
/**
* It closes the common part of the access and access_demux
{
char *tmp;
- /* */
+ /* */
imem_sys_t *sys = calloc(1, sizeof(*sys));
- if (!sys)
- return VLC_ENOMEM;
+ if (!sys)
+ return VLC_ENOMEM;
/* Read the user functions */
- tmp = var_CreateGetString(object, "imem-get");
+ tmp = var_InheritString(object, "imem-get");
if (tmp)
sys->source.get = (imem_get_t)(intptr_t)strtoll(tmp, NULL, 0);
free(tmp);
- tmp = var_CreateGetString(object, "imem-release");
+ tmp = var_InheritString(object, "imem-release");
if (tmp)
sys->source.release = (imem_release_t)(intptr_t)strtoll(tmp, NULL, 0);
free(tmp);
return VLC_EGENERIC;
}
- tmp = var_CreateGetString(object, "imem-data");
+ tmp = var_InheritString(object, "imem-data");
if (tmp)
sys->source.data = (void *)(uintptr_t)strtoull(tmp, NULL, 0);
free(tmp);
sys->source.cookie ? sys->source.cookie : "(null)");
/* */
- sys->pts_delay = var_CreateGetInteger(object, "imem-caching") * INT64_C(1000);
+ sys->pts_delay = var_InheritInteger(object, "imem-caching") * INT64_C(1000);
sys->dts = 0;
sys->deadline = VLC_TS_INVALID;
return VLC_SUCCESS;
}
+/**
+ * It opens an imem access.
+ */
+static int OpenAccess(vlc_object_t *object)
+{
+ access_t *access = (access_t *)object;
+ imem_sys_t *sys;
+
+ if (OpenCommon(object, &sys, access->psz_location))
+ return VLC_EGENERIC;
+
+ if (var_InheritInteger(object, "imem-cat") != 4) {
+ CloseCommon(sys);
+ return VLC_EGENERIC;
+ }
+
+ /* */
+ access_InitFields(access);
+ access->pf_control = ControlAccess;
+ access->pf_read = NULL;
+ access->pf_block = Block;
+ access->pf_seek = NULL;
+ access->p_sys = (access_sys_t*)sys;
+ access->info.i_size = var_InheritInteger(object, "imem-size");
+
+ return VLC_SUCCESS;
+}
+
+/**
+ * It closes an imem access
+ */
+static void CloseAccess(vlc_object_t *object)
+{
+ access_t *access = (access_t *)object;
+
+ CloseCommon((imem_sys_t*)access->p_sys);
+}
+
+/**
+ * It controls an imem access
+ */
+static int ControlAccess(access_t *access, int i_query, va_list args)
+{
+ imem_sys_t *sys = (imem_sys_t*)access->p_sys;
+
+ switch (i_query)
+ {
+ case ACCESS_CAN_SEEK:
+ case ACCESS_CAN_FASTSEEK: {
+ bool *b = va_arg( args, bool* );
+ *b = false;
+ return VLC_SUCCESS;
+ }
+ case ACCESS_CAN_PAUSE:
+ case ACCESS_CAN_CONTROL_PACE: {
+ bool *b = va_arg( args, bool* );
+ *b = true;
+ return VLC_SUCCESS;
+ }
+ case ACCESS_GET_PTS_DELAY: {
+ int64_t *delay = va_arg(args, int64_t *);
+ *delay = sys->pts_delay;
+ return VLC_SUCCESS;
+ }
+ case ACCESS_SET_PAUSE_STATE:
+ return VLC_SUCCESS;
+
+ case ACCESS_GET_TITLE_INFO:
+ case ACCESS_SET_TITLE:
+ case ACCESS_SET_SEEKPOINT:
+ case ACCESS_SET_PRIVATE_ID_STATE:
+ case ACCESS_GET_META:
+ case ACCESS_GET_PRIVATE_ID_STATE:
+ case ACCESS_GET_CONTENT_TYPE:
+ default:
+ return VLC_EGENERIC;
+ }
+}
+
+/**
+ * It retreives data using the get() callback, copies them,
+ * and then release them using the release() callback.
+ */
+static block_t *Block(access_t *access)
+{
+ imem_sys_t *sys = (imem_sys_t*)access->p_sys;
+
+ unsigned flags;
+ size_t buffer_size;
+ void *buffer;
+
+ if (sys->source.get(sys->source.data, sys->source.cookie,
+ NULL, NULL, &flags, &buffer_size, &buffer)) {
+ access->info.b_eof = true;
+ return NULL;
+ }
+
+ block_t *block = NULL;
+ if (buffer_size > 0) {
+ block = block_New(access, buffer_size);
+ if (block)
+ memcpy(block->p_buffer, buffer, buffer_size);
+ }
+
+ sys->source.release(sys->source.data, sys->source.cookie,
+ buffer_size, buffer);
+ return block;
+}
+
/**
* It opens an imem access_demux.
*/
demux_t *demux = (demux_t *)object;
imem_sys_t *sys;
- if (OpenCommon(VLC_OBJECT(demux), &sys, demux->psz_path))
+ if (OpenCommon(object, &sys, demux->psz_location))
return VLC_EGENERIC;
- /* ES format */
+ /* ES format */
es_format_t fmt;
- es_format_Init(&fmt, UNKNOWN_ES, 0);
+ es_format_Init(&fmt, UNKNOWN_ES, 0);
- fmt.i_id = var_CreateGetInteger(object, "imem-id");
- fmt.i_group = var_CreateGetInteger(object, "imem-group");
+ fmt.i_id = var_InheritInteger(object, "imem-id");
+ fmt.i_group = var_InheritInteger(object, "imem-group");
- char *tmp = var_CreateGetString(object, "imem-codec");
+ char *tmp = var_InheritString(object, "imem-codec");
if (tmp)
fmt.i_codec = vlc_fourcc_GetCodecFromString(UNKNOWN_ES, tmp);
free(tmp);
- switch (var_CreateGetInteger(object, "imem-cat")) {
+ const int cat = var_InheritInteger(object, "imem-cat");
+ switch (cat) {
case 1: {
fmt.i_cat = AUDIO_ES;
- fmt.audio.i_channels = var_CreateGetInteger(object, "imem-channels");
- fmt.audio.i_rate = var_CreateGetInteger(object, "imem-samplerate");
+ fmt.audio.i_channels = var_InheritInteger(object, "imem-channels");
+ fmt.audio.i_rate = var_InheritInteger(object, "imem-samplerate");
msg_Dbg(object, "Audio %4.4s %d channels %d Hz",
(const char *)&fmt.i_codec,
}
case 2: {
fmt.i_cat = VIDEO_ES;
- fmt.video.i_width = var_CreateGetInteger(object, "imem-width");
- fmt.video.i_height = var_CreateGetInteger(object, "imem-height");
+ fmt.video.i_width = var_InheritInteger(object, "imem-width");
+ fmt.video.i_height = var_InheritInteger(object, "imem-height");
unsigned num, den;
- if (!var_CreateGetRational(object, &num, &den, "imem-dar") && num > 0 && den > 0) {
+ if (!var_InheritURational(object, &num, &den, "imem-dar") && num > 0 && den > 0) {
if (fmt.video.i_width > 0 && fmt.video.i_height > 0) {
fmt.video.i_sar_num = num * fmt.video.i_height;
fmt.video.i_sar_den = den * fmt.video.i_width;
}
}
- if (!var_CreateGetRational(object, &num, &den, "imem-fps") && num > 0 && den > 0) {
+ if (!var_InheritURational(object, &num, &den, "imem-fps") && num > 0 && den > 0) {
fmt.video.i_frame_rate = num;
fmt.video.i_frame_rate_base = den;
}
case 3: {
fmt.i_cat = SPU_ES;
fmt.subs.spu.i_original_frame_width =
- var_CreateGetInteger(object, "imem-width");
+ var_InheritInteger(object, "imem-width");
fmt.subs.spu.i_original_frame_height =
- var_CreateGetInteger(object, "imem-height");
+ var_InheritInteger(object, "imem-height");
msg_Dbg(object, "Subtitle %4.4s",
(const char *)&fmt.i_codec);
break;
}
default:
- msg_Err(object, "Invalid ES category");
+ if (cat != 4)
+ msg_Err(object, "Invalid ES category");
es_format_Clean(&fmt);
CloseCommon(sys);
return VLC_EGENERIC;
}
- fmt.psz_language = var_CreateGetString(object, "imem-language");
+ fmt.psz_language = var_InheritString(object, "imem-language");
- sys->es = es_out_Add(demux->out, &fmt);
+ sys->es = es_out_Add(demux->out, &fmt);
es_format_Clean(&fmt);
if (!sys->es) {
}
/**
- * It controls imem
+ * It controls an imem access_demux
*/
static int ControlDemux(demux_t *demux, int i_query, va_list args)
{
return 1;
}
-/**
- * It parses a rational number (it also accepts basic float number).
- *
- * It returns an error if the rational number cannot be parsed (0/0 is valid).
- */
-static int (var_CreateGetRational)(vlc_object_t *object,
- unsigned *num, unsigned *den,
- const char *var)
-{
- /* */
- *num = 0;
- *den = 0;
-
- /* */
- char *tmp = var_CreateGetString(object, var);
- if (!tmp)
- goto error;
-
- char *next;
- unsigned n = strtol(tmp, &next, 0);
- unsigned d = strtol(*next ? &next[1] : "0", NULL, 0);
-
- if (*next == '.') {
- /* Interpret as a float number */
- double r = us_atof(tmp);
- double c = ceil(r);
- if (c >= UINT_MAX)
- goto error;
- unsigned m = c;
- if (m > 0) {
- d = UINT_MAX / m;
- n = r * d;
- } else {
- n = 0;
- d = 0;
- }
- }
-
- if (n > 0 && d > 0)
- vlc_ureduce(num, den, n, d, 0);
-
- free(tmp);
- return VLC_SUCCESS;
-
-error:
- free(tmp);
- return VLC_EGENERIC;
-}
-
/**
* Parse the MRL and extract configuration from it.
*