xine-lib 1.2.13-20230125hg15249
Data Structures | Macros | Typedefs | Functions | Variables
xineplug_inp_vcd.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <xine/xineutils.h>
#include <xine/input_plugin.h>
#include <xine/xine_internal.h>
#include "cdio/logging.h"
#include "cdio/iso9660.h"
#include "cdio/cd_types.h"
#include "libvcd/files.h"
#include "libvcd/logging.h"
#include "vcdplayer.h"
#include "vcdio.h"

Data Structures

struct  vcd_config_s
 
struct  vcd_input_class_s
 
struct  vcd_input_plugin_s
 

Macros

#define SHORT_PLUGIN_NAME   "VCD"
 
#define MRL_PREFIX   "vcd://"
 
#define MRL_PREFIX_LEN   (sizeof(MRL_PREFIX) - 1)
 
#define MAX_DEVICE_LEN   1024
 
#define xine_config_entry_t   xine_cfg_entry_t
 
#define BUF_DEMUX_BLOCK   0x05000000
 
#define msg_print(class, fmt, args...)
 
#define dbg_print(class, mask, fmt, args...)
 
#define error_print(class, fmt, args...)
 
#define stream_info_assign(field, stream, info)    _x_stream_info_set(stream, field, info);
 
#define RETURN_NOOP_BUF
 
#define SLEEP_AND_HANDLE_EVENTS
 
#define FREE_AND_NULL(ptr)   if (NULL != ptr) free(ptr); ptr = NULL;
 
#define MAX_DIR_ENTRIES   250
 
#define VCD_NUM_CALLBACK(fn_name, var)
 
#define VCD_ENUM_CALLBACK(fn_name, enum_type, var)
 
#define VCD_STR_CALLBACK(fn_name, var)
 

Typedefs

typedef struct vcd_config_s vcd_config_t
 
typedef struct vcd_input_plugin_s vcd_input_plugin_t
 
typedef struct vcd_input_class_s vcd_input_class_t
 

Functions

static bool vcd_handle_events (vcd_input_plugin_t *this)
 
static void vcd_close (vcd_input_class_t *class)
 
static int XINE_FORMAT_PRINTF (3, 4)
 
static void vcd_free_mrls (vcd_input_class_t *class)
 
static bool vcd_get_default_device (vcd_input_class_t *class, bool log_msg_if_fail)
 
static void meta_info_assign (vcd_input_plugin_t *this, int field, xine_stream_t *stream, const char *info)
 
static void vcd_set_meta_info (vcd_input_plugin_t *this)
 
static void vcd_force_redisplay (void *user_data)
 
static void vcd_set_aspect_ratio (void *user_data, int i_aspect_ratio)
 
static void vcd_add_mrl_slot (vcd_input_class_t *class, const char *mrl, off_t size, unsigned int *i)
 
static int vcd_get_mrl_type_offset (vcd_input_plugin_t *inp, vcdinfo_item_enum_t type, int *size)
 
static bool vcd_build_mrl_list (vcd_input_class_t *class, char *vcd_device)
 
static bool vcd_parse_mrl (vcd_input_class_t *class, const char *default_vcd_device, const char *mrl, char *device_str, vcdinfo_itemid_t *itemid, vcdplayer_autoplay_t auto_type, bool *used_default)
 
static uint32_t vcd_plugin_get_capabilities (input_plugin_t *this_gen)
 
static void vcd_flush_buffers (void *user_data)
 
static off_t vcd_plugin_read (input_plugin_t *this_gen, void *vbuf, const off_t nlen)
 
static buf_element_tvcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, const off_t i_len)
 
static off_t vcd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin)
 
static off_t vcd_plugin_get_length (input_plugin_t *this_gen)
 
static off_t vcd_plugin_get_current_pos (input_plugin_t *this_gen)
 
static uint32_t vcd_plugin_get_blocksize (input_plugin_t *this_gen)
 
static xine_mrl_t ** vcd_class_get_dir (input_class_t *this_gen, const char *filename, int *num_files)
 
static int vcd_class_eject_media (input_class_t *this_gen)
 
static const char * vcd_plugin_get_mrl (input_plugin_t *this_gen)
 
static int vcd_get_optional_data (input_plugin_t *this_gen, void *data, int data_type)
 
static const char *const * vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files)
 
static void vcd_plugin_dispose (input_plugin_t *this_gen)
 
static void vcd_log_handler (vcd_log_level_t level, const char message[])
 
static void cdio_log_handler (cdio_log_level_t level, const char message[])
 
static void uninit_log_handler (vcd_log_level_t level, const char message[])
 
static void vcd_class_dispose (input_class_t *this_gen)
 
static void vcd_update_title_display (void *user_data)
 
static int vcd_plugin_open (input_plugin_t *this_gen)
 
static input_plugin_tvcd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *mrl)
 
static void vcd_default_dev_changed_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void vcd_title_format_changed_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void vcd_comment_format_changed_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void vcd_show_rejected_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void vcd_autoadvance_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void vcd_slider_length_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void vcd_default_autoplay_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void vcd_debug_cb (void *this_gen, xine_cfg_entry_t *entry)
 
static void * vcd_init (xine_t *xine, const void *data)
 

Variables

static const vcdinfo_item_enum_t autoplay2itemtype []
 
static vcdinfo_itemid_t old_play_item = {VCDINFO_ITEM_TYPE_NOTFOUND, 0}
 
static off_t old_get_length = 0
 
static vcdplayer_slider_length_t old_slider_length
 
static vcd_log_handler_t gl_default_vcd_log_handler = NULL
 
static cdio_log_handler_t gl_default_cdio_log_handler = NULL
 

Macro Definition Documentation

◆ BUF_DEMUX_BLOCK

#define BUF_DEMUX_BLOCK   0x05000000

◆ dbg_print

#define dbg_print ( class,
mask,
fmt,
args... )

◆ error_print

#define error_print ( class,
fmt,
args... )
Value:
{\
xprintf ((class)->xine, XINE_VERBOSITY_LOG, "input_vcd: %s error: "fmt"\n", __func__, ##args);\
}
#define XINE_VERBOSITY_LOG
Definition xine.h:429

Referenced by vcd_add_mrl_slot(), vcd_build_mrl_list(), and vcd_plugin_get_mrl().

◆ FREE_AND_NULL

#define FREE_AND_NULL ( ptr)    if (NULL != ptr) free(ptr); ptr = NULL;

Referenced by vcd_close().

◆ MAX_DEVICE_LEN

#define MAX_DEVICE_LEN   1024

◆ MAX_DIR_ENTRIES

#define MAX_DIR_ENTRIES   250

◆ MRL_PREFIX

#define MRL_PREFIX   "vcd://"

◆ MRL_PREFIX_LEN

#define MRL_PREFIX_LEN   (sizeof(MRL_PREFIX) - 1)

◆ msg_print

#define msg_print ( class,
fmt,
args... )
Value:
{\
xprintf ((class)->xine, XINE_VERBOSITY_LOG, "input_vcd: %s: "fmt"\n", __func__, ##args);\
}

Referenced by vcd_get_default_device(), and vcd_handle_events().

◆ RETURN_NOOP_BUF

#define RETURN_NOOP_BUF
Value:
p_buf = fifo->buffer_pool_alloc (fifo); \
p_buf->type = BUF_CONTROL_NOP; \
return p_buf
#define BUF_CONTROL_NOP
Definition buffer.h:74

Referenced by vcd_plugin_read_block().

◆ SHORT_PLUGIN_NAME

#define SHORT_PLUGIN_NAME   "VCD"

Referenced by vcd_init().

◆ SLEEP_AND_HANDLE_EVENTS

#define SLEEP_AND_HANDLE_EVENTS
Value:
xine_usec_sleep(50000); \
if (vcd_handle_events (this)) goto read_block; \
void xine_usec_sleep(unsigned usec)
Definition utils.c:546
#define RETURN_NOOP_BUF
Definition xineplug_inp_vcd.c:723
static bool vcd_handle_events(vcd_input_plugin_t *this)
Definition xineplug_inp_vcd.c:1096

Referenced by vcd_plugin_read_block().

◆ stream_info_assign

#define stream_info_assign ( field,
stream,
info )    _x_stream_info_set(stream, field, info);

◆ VCD_ENUM_CALLBACK

#define VCD_ENUM_CALLBACK ( fn_name,
enum_type,
var )
Value:
static void fn_name (void *this_gen, xine_cfg_entry_t *entry) {\
vcd_input_class_t *class = (vcd_input_class_t *)this_gen;\
dbg_print (class, INPUT_DBG_CALL, "Called setting %d\n", entry->num_value);\
class->var = (enum_type)entry->num_value;\
}
Definition input_vcd.c:81
Definition xine.h:1649
int num_value
Definition xine.h:1670
#define INPUT_DBG_CALL
Definition vcdplayer.h:56

◆ VCD_NUM_CALLBACK

#define VCD_NUM_CALLBACK ( fn_name,
var )
Value:
static void fn_name (void *this_gen, xine_cfg_entry_t *entry) {\
vcd_input_class_t *class = (vcd_input_class_t *)this_gen;\
dbg_print (class, INPUT_DBG_CALL, "Called setting %d\n", entry->num_value);\
class->var = entry->num_value;\
}

◆ VCD_STR_CALLBACK

#define VCD_STR_CALLBACK ( fn_name,
var )
Value:
static void fn_name (void *this_gen, xine_cfg_entry_t *entry) {\
vcd_input_class_t *class = (vcd_input_class_t *)this_gen;\
dbg_print (class, INPUT_DBG_CALL, "Called setting %s\n", entry->str_value);\
if (NULL == entry->str_value) return;\
free (class->var);\
class->var = strdup (entry->str_value);\
}
char * str_value
Definition xine.h:1663
NULL
Definition xine_plugin.c:78

◆ xine_config_entry_t

#define xine_config_entry_t   xine_cfg_entry_t

Typedef Documentation

◆ vcd_config_t

typedef struct vcd_config_s vcd_config_t

◆ vcd_input_class_t

typedef struct vcd_input_class_s vcd_input_class_t

◆ vcd_input_plugin_t

typedef struct vcd_input_plugin_s vcd_input_plugin_t

Function Documentation

◆ cdio_log_handler()

static void cdio_log_handler ( cdio_log_level_t level,
const char message[] )
static

This routine is called by libcdio routines on error. Setup is done by init_input_plugin.

Referenced by vcd_plugin_open().

◆ meta_info_assign()

static void meta_info_assign ( vcd_input_plugin_t * this,
int field,
xine_stream_t * stream,
const char * info )
static

◆ uninit_log_handler()

static void uninit_log_handler ( vcd_log_level_t level,
const char message[] )
static

This routine is when xine is not around. Setup is done by vcd_class_dispose.

Referenced by vcd_class_dispose(), and vcd_init().

◆ vcd_add_mrl_slot()

static void vcd_add_mrl_slot ( vcd_input_class_t * class,
const char * mrl,
off_t size,
unsigned int * i )
static

Add another MRL to the MRL list inside "class" to be displayed. mrl is the string name to add; size is the size of the entry in bytes. The number of mrls in "this" is incremented.

References dbg_print, error_print, INPUT_DBG_MRL, mrl_vcd, and NULL.

Referenced by vcd_build_mrl_list().

◆ vcd_autoadvance_cb()

static void vcd_autoadvance_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_build_mrl_list()

static bool vcd_build_mrl_list ( vcd_input_class_t * class,
char * vcd_device )
static

◆ vcd_class_dispose()

static void vcd_class_dispose ( input_class_t * this_gen)
static

◆ vcd_class_eject_media()

static int vcd_class_eject_media ( input_class_t * this_gen)
static

From plugin xine spec: eject/load the media (if it's possible)

returns 0 for temporary failures

References dbg_print, input_class_s::get_instance, INPUT_DBG_CALL, INPUT_DBG_EXT, MRL_PREFIX, NULL, and vcdio_close().

Referenced by vcd_init().

◆ vcd_class_get_autoplay_list()

static const char *const * vcd_class_get_autoplay_list ( input_class_t * this_gen,
int * num_files )
static

From xine plugin spec:

generate autoplay list return value: list of MRLs

– The list of MRLs returned goes into the playlist. This is called when the SHORT_PLUGIN_NAME button is pressed.

References autoplay2itemtype, dbg_print, vcd_input_class_t::filelist, input_class_s::get_instance, INPUT_DBG_CALL, INPUT_DBG_EXT, INPUT_DBG_MRL, MAX_DIR_ENTRIES, MRL_PREFIX, NULL, vcd_build_mrl_list(), and vcd_get_mrl_type_offset().

Referenced by vcd_init().

◆ vcd_class_get_dir()

static xine_mrl_t ** vcd_class_get_dir ( input_class_t * this_gen,
const char * filename,
int * num_files )
static

From xine plugin spec: ls function return value: NULL => filename is a file, **char=> filename is a dir

– This list returned forms the entries of the GUI MRL "browser".

References dbg_print, input_class_s::get_instance, INPUT_DBG_CALL, INPUT_DBG_EXT, MAX_DEVICE_LEN, MRL_PREFIX, NULL, vcd_build_mrl_list(), vcd_get_default_device(), and vcd_parse_mrl().

Referenced by vcd_init().

◆ vcd_class_get_instance()

static input_plugin_t * vcd_class_get_instance ( input_class_t * class_gen,
xine_stream_t * stream,
const char * mrl )
static

This basically sets up stream specified by MRL for playing. After this routine is called, xine-lib can read blocks from the thing specified by the MRL, set the position of the thing specified by the MRL, get its size or read its current position...

See vcdplayer_parses_mrl for the for the format that a valid MRL can take.

Return values: pointer to input plugin NULL on failure

References dbg_print, INPUT_DBG_CALL, INPUT_DBG_EXT, INPUT_DBG_MRL, INPUT_DBG_PBC, MAX_DEVICE_LEN, MRL_PREFIX, MRL_PREFIX_LEN, NULL, vcd_build_mrl_list(), vcd_flush_buffers(), vcd_force_redisplay(), vcd_get_default_device(), vcd_get_optional_data(), vcd_parse_mrl(), vcd_plugin_dispose(), vcd_plugin_get_blocksize(), vcd_plugin_get_capabilities(), vcd_plugin_get_current_pos(), vcd_plugin_get_length(), vcd_plugin_get_mrl(), vcd_plugin_open(), vcd_plugin_read(), vcd_plugin_read_block(), vcd_plugin_seek(), vcd_set_aspect_ratio(), vcd_set_meta_info(), vcd_update_title_display(), vcdio_close(), vcdplayer_play(), XINE_ANON_STREAM, and xine_event_new_queue().

Referenced by vcd_init().

◆ vcd_close()

static void vcd_close ( vcd_input_class_t * class)
static

◆ vcd_comment_format_changed_cb()

static void vcd_comment_format_changed_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_debug_cb()

static void vcd_debug_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_default_autoplay_cb()

static void vcd_default_autoplay_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_default_dev_changed_cb()

static void vcd_default_dev_changed_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_flush_buffers()

static void vcd_flush_buffers ( void * user_data)
static

◆ vcd_force_redisplay()

static void vcd_force_redisplay ( void * user_data)
static

◆ vcd_free_mrls()

static void vcd_free_mrls ( vcd_input_class_t * class)
static

References NULL.

Referenced by vcd_build_mrl_list(), and vcd_close().

◆ vcd_get_default_device()

static bool vcd_get_default_device ( vcd_input_class_t * class,
bool log_msg_if_fail )
static

◆ vcd_get_mrl_type_offset()

static int vcd_get_mrl_type_offset ( vcd_input_plugin_t * inp,
vcdinfo_item_enum_t type,
int * size )
static

Return the associated mrl_offset for the given type.

References type.

Referenced by vcd_class_get_autoplay_list(), and vcd_plugin_get_mrl().

◆ vcd_get_optional_data()

static int vcd_get_optional_data ( input_plugin_t * this_gen,
void * data,
int data_type )
static

◆ vcd_handle_events()

static bool vcd_handle_events ( vcd_input_plugin_t * this)
static

◆ vcd_init()

static void * vcd_init ( xine_t * xine,
const void * data )
static

◆ vcd_log_handler()

static void vcd_log_handler ( vcd_log_level_t level,
const char message[] )
static

This routine is called by libvcd routines on error. Setup is done by init_input_plugin.

Referenced by vcd_plugin_open().

◆ vcd_parse_mrl()

static bool vcd_parse_mrl ( vcd_input_class_t * class,
const char * default_vcd_device,
const char * mrl,
char * device_str,
vcdinfo_itemid_t * itemid,
vcdplayer_autoplay_t auto_type,
bool * used_default )
static

parses a MRL which has the format

vcd://[vcd_path][@[EPTS]?number]*?

Examples vcd:// - Play (navigate) default device: /dev/cdrom vcd://@ - same as above vcd:///dev/cdrom - probably same as above vcd:///dev/cdrom2 - Play (navigate) /dev/cdrom2 vcd:///dev/cdrom2@ - same as above vcd:///dev/cdrom2@T1 - Play Track 1 from /dev/cdrom2 vcd:///dev/cdrom@S1 - Play selection id 1 from /dev/cdrom vcd://dev/cdrom@E0 - Play Entry id 0 from default device vcd://@P1 - probably same as above. If there is no playback control, MRL will get converted into vcd://@E0 vcd://@P1* - probably same as above. vcd://@S0 - Play segment 0 from default device vcd://@3 - Play track 3 from default device vcd:///dev/cdrom2@1 - Play track 1 from /dev/cdrom2 vcd:///tmp/ntsc.bin@ - Play default item from /tmp/ntsc.bin vcd:///tmp/ntsc.bin/@E0 - Play entry 0 of /tmp/ntsc.bin

parameters: mrl : mrl to parse default_vcd_device: name of device to use when none given auto_type : type of selection (entry, track, LID) when none given used_default : true iff auto_type was used.

References _x_mrl_unescape(), dbg_print, INPUT_DBG_CALL, MAX_DEVICE_LEN, MRL_PREFIX, MRL_PREFIX_LEN, and NULL.

Referenced by vcd_class_get_dir(), and vcd_class_get_instance().

◆ vcd_plugin_dispose()

static void vcd_plugin_dispose ( input_plugin_t * this_gen)
static

Things that need to be done when a stream is closed.

References dbg_print, INPUT_DBG_CALL, INPUT_DBG_EXT, NULL, and vcdio_close().

Referenced by vcd_class_get_instance().

◆ vcd_plugin_get_blocksize()

static uint32_t vcd_plugin_get_blocksize ( input_plugin_t * this_gen)
static

From xine plugin spec: return block size of input source (if supported, 0 otherwise)

References dbg_print, INPUT_DBG_CALL, and INPUT_DBG_EXT.

Referenced by vcd_class_get_instance().

◆ vcd_plugin_get_capabilities()

static uint32_t vcd_plugin_get_capabilities ( input_plugin_t * this_gen)
static

◆ vcd_plugin_get_current_pos()

static off_t vcd_plugin_get_current_pos ( input_plugin_t * this_gen)
static

From xine plugin spec: get current position in stream.

References vcd_plugin_seek().

Referenced by vcd_class_get_instance().

◆ vcd_plugin_get_length()

static off_t vcd_plugin_get_length ( input_plugin_t * this_gen)
static

◆ vcd_plugin_get_mrl()

static const char * vcd_plugin_get_mrl ( input_plugin_t * this_gen)
static

◆ vcd_plugin_open()

static int vcd_plugin_open ( input_plugin_t * this_gen)
static

◆ vcd_plugin_read()

static off_t vcd_plugin_read ( input_plugin_t * this_gen,
void * vbuf,
const off_t nlen )
static

From xine plugin spec:

read nlen bytes, return number of bytes read.

References dbg_print, INPUT_DBG_CALL, and INPUT_DBG_EXT.

Referenced by vcd_class_get_instance(), and vcd_class_get_instance().

◆ vcd_plugin_read_block()

static buf_element_t * vcd_plugin_read_block ( input_plugin_t * this_gen,
fifo_buffer_t * fifo,
const off_t i_len )
static

From xine plugin spec:

read one block, return newly allocated block (or NULL on failure) for blocked input sources len must be == blocksize the fifo parameter is only used to get access to the buffer_pool_alloc function

References vcdplayer_s::b_opened, BUF_DEMUX_BLOCK, fifo_buffer_s::buffer_pool_alloc, buf_element_s::content, dbg_print, vcdplayer_s::i_still, INPUT_DBG_CALL, INPUT_DBG_STILL, buf_element_s::mem, NULL, READ_BLOCK, READ_END, READ_ERROR, READ_STILL_FRAME, RETURN_NOOP_BUF, SLEEP_AND_HANDLE_EVENTS, STILL_INDEFINITE_WAIT, STILL_READING, buf_element_s::type, vcd_handle_events(), vcdio_open(), vcdplayer_read(), xine_get_param(), XINE_PARAM_VO_DEINTERLACE, and xine_set_param().

Referenced by vcd_class_get_instance(), and vcd_class_get_instance().

◆ vcd_plugin_seek()

static off_t vcd_plugin_seek ( input_plugin_t * this_gen,
off_t offset,
int origin )
static

From xine plugin spec:

seek position, return new position

if seeking failed, -1 is returned

References vcdio_seek().

Referenced by vcd_class_get_instance(), vcd_class_get_instance(), vcd_plugin_get_current_pos(), and vcd_plugin_get_current_pos().

◆ vcd_set_aspect_ratio()

static void vcd_set_aspect_ratio ( void * user_data,
int i_aspect_ratio )
static

◆ vcd_set_meta_info()

static void vcd_set_meta_info ( vcd_input_plugin_t * this)
static

◆ vcd_show_rejected_cb()

static void vcd_show_rejected_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_slider_length_cb()

static void vcd_slider_length_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_title_format_changed_cb()

static void vcd_title_format_changed_cb ( void * this_gen,
xine_cfg_entry_t * entry )
static

Referenced by vcd_init().

◆ vcd_update_title_display()

static void vcd_update_title_display ( void * user_data)
static

◆ XINE_FORMAT_PRINTF()

static int XINE_FORMAT_PRINTF ( 3 ,
4  )
static

Variable Documentation

◆ autoplay2itemtype

const vcdinfo_item_enum_t autoplay2itemtype[]
static
Initial value:
={
VCDINFO_ITEM_TYPE_TRACK,
VCDINFO_ITEM_TYPE_ENTRY,
VCDINFO_ITEM_TYPE_SEGMENT,
VCDINFO_ITEM_TYPE_LID
}

Referenced by vcd_class_get_autoplay_list().

◆ gl_default_cdio_log_handler

cdio_log_handler_t gl_default_cdio_log_handler = NULL
static

◆ gl_default_vcd_log_handler

vcd_log_handler_t gl_default_vcd_log_handler = NULL
static

◆ old_get_length

off_t old_get_length = 0
static

Referenced by vcd_plugin_get_length().

◆ old_play_item

vcdinfo_itemid_t old_play_item = {VCDINFO_ITEM_TYPE_NOTFOUND, 0}
static

From xine plugin spec: return length of input (-1 => unlimited, e.g. stream)

length size is bytes.

Referenced by vcd_plugin_get_length().

◆ old_slider_length

vcdplayer_slider_length_t old_slider_length
static

Referenced by vcd_plugin_get_length().