vlc_access.h 9.01 KB
Newer Older
1
/*****************************************************************************
2
 * vlc_access.h: Access descriptor, queries and methods
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
4
 * Copyright (C) 1999-2006 VLC authors and VideoLAN
5
 * $Id$
6 7 8
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
9 10 11
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
12 13 14 15
 * (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
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
16 17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
18
 *
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
19 20 21
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 23
 *****************************************************************************/

24 25
#ifndef VLC_ACCESS_H
#define VLC_ACCESS_H 1
26

Clément Stenac's avatar
Clément Stenac committed
27 28
#include <vlc_block.h>

29 30
/**
 * \defgroup access Access
31 32
 * \ingroup input
 * Raw input byte streams
33
 * @{
34 35
 * \file
 * Input byte stream modules interface
36 37 38 39 40
 */

enum access_query_e
{
    /* capabilities */
41 42 43 44
    ACCESS_CAN_SEEK,        /* arg1= bool*    cannot fail */
    ACCESS_CAN_FASTSEEK,    /* arg1= bool*    cannot fail */
    ACCESS_CAN_PAUSE,       /* arg1= bool*    cannot fail */
    ACCESS_CAN_CONTROL_PACE,/* arg1= bool*    cannot fail */
45
    ACCESS_GET_SIZE=6,      /* arg1= uin64_t* */
46
    ACCESS_IS_DIRECTORY,    /* arg1= bool *, arg2= bool *, res=can fail */
47 48

    /* */
49
    ACCESS_GET_PTS_DELAY = 0x101,/* arg1= int64_t*       cannot fail */
50 51 52
    ACCESS_GET_TITLE_INFO,  /* arg1=input_title_t*** arg2=int*  res=can fail */
    ACCESS_GET_TITLE,       /* arg1=unsigned * res=can fail */
    ACCESS_GET_SEEKPOINT,   /* arg1=unsigned * res=can fail */
53

54
    /* Meta data */
55
    ACCESS_GET_META,        /* arg1= vlc_meta_t * res=can fail */
56
    ACCESS_GET_CONTENT_TYPE,/* arg1=char **ppsz_content_type res=can fail */
57 58 59 60

    ACCESS_GET_SIGNAL,      /* arg1=double *pf_quality, arg2=double *pf_strength   res=can fail */

    /* */
61
    ACCESS_SET_PAUSE_STATE = 0x200, /* arg1= bool           can fail */
62 63 64 65 66 67 68

    /* */
    ACCESS_SET_TITLE,       /* arg1= int            can fail */
    ACCESS_SET_SEEKPOINT,   /* arg1= int            can fail */

    /* Special mode for access/demux communication
     * XXX: avoid to use it unless you can't */
69 70 71
    ACCESS_SET_PRIVATE_ID_STATE = 0x1000, /* arg1= int i_private_data, bool b_selected    res=can fail */
    ACCESS_SET_PRIVATE_ID_CA,             /* arg1= int i_program_number, uint16_t i_vpid, uint16_t i_apid1, uint16_t i_apid2, uint16_t i_apid3, uint8_t i_length, uint8_t *p_data */
    ACCESS_GET_PRIVATE_ID_STATE,          /* arg1=int i_private_data arg2=bool *          res=can fail */
72 73 74 75 76 77 78 79 80
};

struct access_t
{
    VLC_COMMON_MEMBERS

    /* Module properties */
    module_t    *p_module;

81 82 83 84

    char        *psz_access; /**< Access name (empty if non forced) */
    char        *psz_url; /**< Full URL or MRL */
    const char  *psz_location; /**< Location (URL with the scheme stripped) */
85
    char        *psz_filepath; /**< Local file path (if applicable) */
86

87
    /* pf_read/pf_block/pf_readdir is used to read data.
88
     * XXX A access should set one and only one of them */
89 90
    ssize_t     (*pf_read)   ( access_t *, uint8_t *, size_t );  /* Return -1 if no data yet, 0 if no more data, else real data read */
    block_t    *(*pf_block)  ( access_t * );                     /* Return a block of data in his 'natural' size, NULL if not yet data or eof */
Thomas Guillem's avatar
Thomas Guillem committed
91 92 93 94 95

    /* pf_readdir: Read the next input_item_t from the directory stream. It
     * returns the next input item on success or NULL in case of error or end
     * of stream. The item must be released with input_item_Release. */
    input_item_t *(*pf_readdir)( access_t * );
96 97 98

    /* Called for each seek.
     * XXX can be null */
99
    int         (*pf_seek) ( access_t *, uint64_t );         /* can be null if can't seek */
100

101
    /* Used to retrieve and configure the access
102 103 104 105 106 107
     * XXX mandatory. look at access_query_e to know what query you *have to* support */
    int         (*pf_control)( access_t *, int i_query, va_list args);

    /* Access has to maintain them uptodate */
    struct
    {
108
        bool         b_eof;     /* idem */
109 110
    } info;
    access_sys_t *p_sys;
111 112 113

    /* Weak link to parent input */
    input_thread_t *p_input;
114 115
};

116 117 118 119 120 121 122 123 124
/**
 * Special redirection error code.
 *
 * In case of redirection, the access open function should clean up (as in
 * normal failure case), store the heap-allocated redirection URL in
 * access_t.psz_url, and return this value.
 */
#define VLC_ACCESS_REDIRECT VLC_ETIMEOUT

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
/**
 * Opens a new read-only byte stream.
 *
 * This function might block.
 * The initial offset is of course always zero.
 *
 * \param obj parent VLC object
 * \param mrl media resource location to read
 * \return a new access object on success, NULL on failure
 */
VLC_API access_t *vlc_access_NewMRL(vlc_object_t *obj, const char *mrl);

/**
 * Closes a byte stream.
 * \param access byte stream to close
 */
VLC_API void vlc_access_Delete(access_t *access);

/**
 * Sets the read byte offset.
 */
static inline int vlc_access_Seek(access_t *access, uint64_t offset)
{
    if (access->pf_seek == NULL)
        return VLC_EGENERIC;
    return access->pf_seek(access, offset);
}

/**
 * Checks if end-of-stream is reached.
 */
static inline bool vlc_access_Eof(const access_t *access)
{
    return access->info.b_eof;
}

/**
 * Reads a byte stream.
 *
 * This function waits for some data to be available (if necessary) and returns
 * available data (up to the requested size). Not all byte streams support
 * this. Some streams must be read with vlc_access_Block() instead.
 *
 * \note
 * A short read does <b>not</b> imply the end of the stream. It merely implies
 * that enough data is not immediately available.
 * To detect the end of the stream, either check if the function returns zero,
 * or call vlc_access_Eof().
 *
 * \note
 * The function may return a negative value spuriously. Negative error values
 * should be ignored; they do not necessarily indicate a fatal error.
 *
 * \param buf buffer to read data into
 * \param len size of the buffer in bytes
 * \return the number of bytes read (possibly less than requested),
 *         zero at end-of-stream, or -1 on <b>transient</b> errors
  */
static inline ssize_t vlc_access_Read(access_t *access, void *buf, size_t len)
{
    if (access->pf_read == NULL)
        return -1;
    return access->pf_read(access, (unsigned char *)buf, len);
}

/**
 * Dequeues one block of data.
 *
 * This function waits for a block of data to be available (if necessary) and
 * returns a reference to it. Not all byte streams support this. Some streams
 * must be read with vlc_access_Read() instead.
 *
 * \note
 * The returned block may be of any size. The size is dependent on the
 * underlying implementation of the byte stream.
 *
 * \note
 * The function may return NULL spuriously. A NULL return is not indicative of
 * a fatal error.
 *
 * \return a data block (free with block_Release()) or NULL
 */
static inline block_t *vlc_access_Block(access_t *access)
{
    if (access->pf_block == NULL)
        return NULL;
    return access->pf_block(access);
}

214
static inline int access_vaControl( access_t *p_access, int i_query, va_list args )
215
{
216
    if( !p_access ) return VLC_EGENERIC;
217
    return p_access->pf_control( p_access, i_query, args );
218
}
Clément Stenac's avatar
Clément Stenac committed
219

220
static inline int access_Control( access_t *p_access, int i_query, ... )
221 222 223 224 225
{
    va_list args;
    int     i_result;

    va_start( args, i_query );
226
    i_result = access_vaControl( p_access, i_query, args );
227 228 229 230
    va_end( args );
    return i_result;
}

231
static inline int access_GetSize( access_t *p_access, uint64_t *size )
232
{
233
    return access_Control( p_access, ACCESS_GET_SIZE, size );
234 235
}

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
236
static inline void access_InitFields( access_t *p_a )
237
{
238
    p_a->info.b_eof = false;
239 240
}

241 242 243 244 245
/**
 * Default pf_control callback for directory accesses.
 */
VLC_API int access_vaDirectoryControlHelper( access_t *p_access, int i_query, va_list args );

246 247 248 249 250 251 252 253 254 255 256 257
#define ACCESS_SET_CALLBACKS( read, block, control, seek ) \
    do { \
        p_access->pf_read = (read); \
        p_access->pf_block = (block); \
        p_access->pf_control = (control); \
        p_access->pf_seek = (seek); \
    } while(0)

#define STANDARD_READ_ACCESS_INIT \
    do { \
        access_InitFields( p_access ); \
        ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek ); \
258
        p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) ); \
259 260 261 262 263 264 265
        if( !p_sys ) return VLC_ENOMEM;\
    } while(0);

#define STANDARD_BLOCK_ACCESS_INIT \
    do { \
        access_InitFields( p_access ); \
        ACCESS_SET_CALLBACKS( NULL, Block, Control, Seek ); \
266
        p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) ); \
267 268
        if( !p_sys ) return VLC_ENOMEM; \
    } while(0);
269

270 271 272 273
/**
 * @}
 */

274
#endif