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

24 25 26 27
#if defined(__PLUGIN__) || defined(__BUILTIN__) || !defined(__LIBVLC__)
# error This header file can only be included from LibVLC.
#endif

Laurent Aimar's avatar
Laurent Aimar committed
28 29 30
#ifndef _INPUT_INTERNAL_H
#define _INPUT_INTERNAL_H 1

Clément Stenac's avatar
Clément Stenac committed
31 32 33
#include <vlc_access.h>
#include <vlc_demux.h>
#include <vlc_input.h>
34
#include <libvlc.h>
Clément Stenac's avatar
Clément Stenac committed
35 36 37 38

/*****************************************************************************
 *  Private input fields
 *****************************************************************************/
39 40 41

#define INPUT_CONTROL_FIFO_SIZE    100

Clément Stenac's avatar
Clément Stenac committed
42 43 44 45 46 47 48 49 50 51 52 53
/* input_source_t: gathers all information per input source */
typedef struct
{
    /* Input item description */
    input_item_t *p_item;

    /* Access/Stream/Demux plugins */
    access_t *p_access;
    stream_t *p_stream;
    demux_t  *p_demux;

    /* Title infos for that input */
Antoine Cellerier's avatar
Antoine Cellerier committed
54
    bool         b_title_demux; /* Titles/Seekpoints provided by demux */
Clément Stenac's avatar
Clément Stenac committed
55 56 57 58 59 60 61 62 63 64 65 66
    int          i_title;
    input_title_t **title;

    int i_title_offset;
    int i_seekpoint_offset;

    int i_title_start;
    int i_title_end;
    int i_seekpoint_start;
    int i_seekpoint_end;

    /* Properties */
67 68 69
    bool b_can_pause;
    bool b_can_pace_control;
    bool b_can_rate_control;
70
    bool b_can_stream_record;
71
    bool b_rescale_ts;
72

Antoine Cellerier's avatar
Antoine Cellerier committed
73
    bool       b_eof;   /* eof of demuxer */
74
    double     f_fps;
Clément Stenac's avatar
Clément Stenac committed
75 76 77 78 79 80 81 82 83

    /* Clock average variation */
    int     i_cr_average;

} input_source_t;

/** Private input fields */
struct input_thread_private_t
{
84 85 86
    /* Object's event manager */
    vlc_event_manager_t event_manager;

Clément Stenac's avatar
Clément Stenac committed
87
    /* Global properties */
Antoine Cellerier's avatar
Antoine Cellerier committed
88 89
    bool        b_can_pause;
    bool        b_can_rate_control;
Clément Stenac's avatar
Clément Stenac committed
90 91

    int         i_rate;
92
    bool        b_recording;
Clément Stenac's avatar
Clément Stenac committed
93 94 95
    /* */
    int64_t     i_start;    /* :start-time,0 by default */
    int64_t     i_stop;     /* :stop-time, 0 if none */
96
    int64_t     i_run;      /* :run-time, 0 if none */
Clément Stenac's avatar
Clément Stenac committed
97 98 99 100 101 102 103 104 105 106 107 108

    /* Title infos FIXME multi-input (not easy) ? */
    int          i_title;
    input_title_t **title;

    int i_title_offset;
    int i_seekpoint_offset;

    /* User bookmarks FIXME won't be easy with multiples input */
    int         i_bookmark;
    seekpoint_t **bookmark;

109 110 111 112
    /* Input attachment */
    int i_attachment;
    input_attachment_t **attachment;

Clément Stenac's avatar
Clément Stenac committed
113
    /* Output */
Antoine Cellerier's avatar
Antoine Cellerier committed
114
    es_out_t        *p_es_out;
115
    es_out_t        *p_es_out_display;
Clément Stenac's avatar
Clément Stenac committed
116
    sout_instance_t *p_sout;            /* XXX Move it to es_out ? */
Antoine Cellerier's avatar
Antoine Cellerier committed
117
    bool            b_out_pace_control; /*     idem ? */
Clément Stenac's avatar
Clément Stenac committed
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

    /* Main input properties */
    input_source_t input;
    /* Slave demuxers (subs, and others) */
    int            i_slave;
    input_source_t **slave;

    /* Stats counters */
    struct {
        counter_t *p_read_packets;
        counter_t *p_read_bytes;
        counter_t *p_input_bitrate;
        counter_t *p_demux_read;
        counter_t *p_demux_bitrate;
        counter_t *p_decoded_audio;
        counter_t *p_decoded_video;
        counter_t *p_decoded_sub;
        counter_t *p_sout_sent_packets;
        counter_t *p_sout_sent_bytes;
        counter_t *p_sout_send_bitrate;
        counter_t *p_played_abuffers;
        counter_t *p_lost_abuffers;
        counter_t *p_displayed_pictures;
        counter_t *p_lost_pictures;
        vlc_mutex_t counters_lock;
    } counters;

    /* Buffer of pending actions */
    vlc_mutex_t lock_control;
147
    vlc_cond_t  wait_control;
Clément Stenac's avatar
Clément Stenac committed
148 149 150
    int i_control;
    struct
    {
151 152
        /* XXX for string value you have to allocate it before calling
         * input_ControlPush */
Clément Stenac's avatar
Clément Stenac committed
153 154 155 156 157 158 159 160
        int         i_type;
        vlc_value_t val;
    } control[INPUT_CONTROL_FIFO_SIZE];
};

/***************************************************************************
 * Internal control helpers
 ***************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
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
enum input_control_e
{
    INPUT_CONTROL_SET_DIE,

    INPUT_CONTROL_SET_STATE,

    INPUT_CONTROL_SET_RATE,
    INPUT_CONTROL_SET_RATE_SLOWER,
    INPUT_CONTROL_SET_RATE_FASTER,

    INPUT_CONTROL_SET_POSITION,
    INPUT_CONTROL_SET_POSITION_OFFSET,

    INPUT_CONTROL_SET_TIME,
    INPUT_CONTROL_SET_TIME_OFFSET,

    INPUT_CONTROL_SET_PROGRAM,

    INPUT_CONTROL_SET_TITLE,
    INPUT_CONTROL_SET_TITLE_NEXT,
    INPUT_CONTROL_SET_TITLE_PREV,

    INPUT_CONTROL_SET_SEEKPOINT,
    INPUT_CONTROL_SET_SEEKPOINT_NEXT,
    INPUT_CONTROL_SET_SEEKPOINT_PREV,

    INPUT_CONTROL_SET_BOOKMARK,

    INPUT_CONTROL_SET_ES,
190
    INPUT_CONTROL_RESTART_ES,
191 192 193

    INPUT_CONTROL_SET_AUDIO_DELAY,
    INPUT_CONTROL_SET_SPU_DELAY,
194 195

    INPUT_CONTROL_ADD_SLAVE,
196

197 198
    INPUT_CONTROL_ADD_SUBTITLE,

199
    INPUT_CONTROL_SET_RECORD_STATE,
200 201

    INPUT_CONTROL_SET_FRAME_NEXT,
Laurent Aimar's avatar
Laurent Aimar committed
202 203 204 205 206 207
};

/* Internal helpers */
static inline void input_ControlPush( input_thread_t *p_input,
                                      int i_type, vlc_value_t *p_val )
{
Clément Stenac's avatar
Clément Stenac committed
208
    vlc_mutex_lock( &p_input->p->lock_control );
Laurent Aimar's avatar
Laurent Aimar committed
209 210 211
    if( i_type == INPUT_CONTROL_SET_DIE )
    {
        /* Special case, empty the control */
Clément Stenac's avatar
Clément Stenac committed
212 213 214
        p_input->p->i_control = 1;
        p_input->p->control[0].i_type = i_type;
        memset( &p_input->p->control[0].val, 0, sizeof( vlc_value_t ) );
Laurent Aimar's avatar
Laurent Aimar committed
215
    }
216
    else if( p_input->p->i_control >= INPUT_CONTROL_FIFO_SIZE )
217 218 219 220 221
    {
        msg_Err( p_input, "input control fifo overflow, trashing type=%d",
                 i_type );
    }
    else
Laurent Aimar's avatar
Laurent Aimar committed
222
    {
Clément Stenac's avatar
Clément Stenac committed
223
        p_input->p->control[p_input->p->i_control].i_type = i_type;
Laurent Aimar's avatar
Laurent Aimar committed
224
        if( p_val )
Clément Stenac's avatar
Clément Stenac committed
225
            p_input->p->control[p_input->p->i_control].val = *p_val;
Laurent Aimar's avatar
Laurent Aimar committed
226
        else
Clément Stenac's avatar
Clément Stenac committed
227
            memset( &p_input->p->control[p_input->p->i_control].val, 0,
Laurent Aimar's avatar
Laurent Aimar committed
228 229
                    sizeof( vlc_value_t ) );

Clément Stenac's avatar
Clément Stenac committed
230
        p_input->p->i_control++;
Laurent Aimar's avatar
Laurent Aimar committed
231
    }
232
    vlc_cond_signal( &p_input->p->wait_control );
Clément Stenac's avatar
Clément Stenac committed
233
    vlc_mutex_unlock( &p_input->p->lock_control );
Laurent Aimar's avatar
Laurent Aimar committed
234 235
}

236 237 238
/** Stuff moved out of vlc_input.h -- FIXME: should probably not be inline
 * anyway. */

239
static inline void input_item_SetPreparsed( input_item_t *p_i, bool preparsed )
240
{
241
    bool send_event = false;
242 243 244 245 246 247 248 249 250 251

    if( !p_i->p_meta )
        p_i->p_meta = vlc_meta_New();

    vlc_mutex_lock( &p_i->lock );
    int new_status;
    if( preparsed )
        new_status = p_i->p_meta->i_status | ITEM_PREPARSED;
    else
        new_status = p_i->p_meta->i_status & ~ITEM_PREPARSED;
252
    if( p_i->p_meta->i_status != new_status )
253 254
    {
        p_i->p_meta->i_status = new_status;
255
        send_event = true;
256 257 258 259
    }

    vlc_mutex_unlock( &p_i->lock );

260
    if( send_event )
261 262 263 264 265 266 267 268
    {
        vlc_event_t event;
        event.type = vlc_InputItemPreparsedChanged;
        event.u.input_item_preparsed_changed.new_status = new_status;
        vlc_event_send( &p_i->event_manager, &event );
    }
}

269
static inline void input_item_SetArtNotFound( input_item_t *p_i, bool notfound )
270 271 272 273 274 275 276 277 278 279
{
    if( !p_i->p_meta )
        p_i->p_meta = vlc_meta_New();

    if( notfound )
        p_i->p_meta->i_status |= ITEM_ART_NOTFOUND;
    else
        p_i->p_meta->i_status &= ~ITEM_ART_NOTFOUND;
}

280
static inline void input_item_SetArtFetched( input_item_t *p_i, bool artfetched )
281 282 283 284 285 286 287 288 289 290
{
    if( !p_i->p_meta )
        p_i->p_meta = vlc_meta_New();

    if( artfetched )
        p_i->p_meta->i_status |= ITEM_ART_FETCHED;
    else
        p_i->p_meta->i_status &= ~ITEM_ART_FETCHED;
}

291
void input_item_SetHasErrorWhenReading( input_item_t *p_i, bool error );
292

Clément Stenac's avatar
Clément Stenac committed
293 294 295 296 297 298 299
/**********************************************************************
 * Item metadata
 **********************************************************************/
typedef struct playlist_album_t
{
    char *psz_artist;
    char *psz_album;
300
    char *psz_arturl;
301
    bool b_found;
Clément Stenac's avatar
Clément Stenac committed
302 303 304 305 306
} playlist_album_t;

int         input_ArtFind       ( playlist_t *, input_item_t * );
int         input_DownloadAndCacheArt ( playlist_t *, input_item_t * );

307 308 309
/* Becarefull; p_item lock HAS to be taken */
void input_ExtractAttachmentAndCacheArt( input_thread_t *p_input );

Clément Stenac's avatar
Clément Stenac committed
310 311 312 313
/***************************************************************************
 * Internal prototypes
 ***************************************************************************/

314 315 316
/* misc/stats.c */
input_stats_t *stats_NewInputStats( input_thread_t *p_input );

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
317
/* input.c */
318 319 320
#define input_CreateThreadExtended(a,b,c,d) __input_CreateThreadExtended(VLC_OBJECT(a),b,c,d)
input_thread_t *__input_CreateThreadExtended ( vlc_object_t *, input_item_t *, const char *, sout_instance_t * );

321
sout_instance_t * input_DetachSout( input_thread_t *p_input );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
322

Laurent Aimar's avatar
Laurent Aimar committed
323 324
/* var.c */
void input_ControlVarInit ( input_thread_t * );
325
void input_ControlVarStop( input_thread_t * );
Laurent Aimar's avatar
Laurent Aimar committed
326 327 328 329 330 331
void input_ControlVarNavigation( input_thread_t * );
void input_ControlVarTitle( input_thread_t *, int i_title );

void input_ConfigVarInit ( input_thread_t * );

/* Subtitles */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
332
char **subtitles_Detect( input_thread_t *, char* path, const char *fname );
333 334
int subtitles_Filter( const char *);

335 336 337
/* Helpers FIXME to export without input_ prefix */
char *input_CreateFilename( vlc_object_t *p_obj, const char *psz_path, const char *psz_prefix, const char *psz_extension );

338
#define INPUT_RECORD_PREFIX "vlc-record-%Y-%m-%d-%H:%M:%S-$ N-$ p"
339

340
#endif