Commit 41c38426 authored by Laurent Aimar's avatar Laurent Aimar

* all: begin to introduce access_t (nothing working yet).

parent 6cdc9671
......@@ -300,6 +300,7 @@ struct input_thread_t
int (* pf_set_program )( input_thread_t *, pgrm_descriptor_t * );
int (* pf_set_area )( input_thread_t *, input_area_t * );
void (* pf_seek ) ( input_thread_t *, off_t );
int (* pf_access_control )( input_thread_t *, int, va_list );
access_sys_t * p_access_data;
size_t i_mtu;
int i_pts_delay; /* internal caching */
......
......@@ -51,10 +51,15 @@ enum es_out_query_e
ES_OUT_SET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t */
ES_OUT_GET_ES_STATE,/* arg1= es_out_id_t* arg2=vlc_bool_t* */
/* XXX XXX XXX Don't use them YET !!! */
/* PCR handling, by default dts/pts will be automatically computed using thoses PCR */
ES_OUT_SET_PCR, /* arg1=int64_t i_pcr(microsecond!) (using default group 0)*/
ES_OUT_SET_GROUP_PCR, /* arg1= int i_group, arg2=int64_t i_pcr(microsecond!)*/
ES_OUT_RESET_PCR /* no arg */
ES_OUT_RESET_PCR, /* no arg */
/* ByBass automatic stream timestamp to absolute timestamp using pcr (and disable the automatic mode XXX:for all groups) */
ES_OUT_CONVERT_TIMESTAMP, /* arg1=int64_t *pi_ts(microsecond!) */
ES_OUT_CONVERT_GROUP_TIMESTAMP, /* arg1=int i_group, arg2=int64_t *pi_ts(microsecond!)*/
};
struct es_out_t
......@@ -95,6 +100,71 @@ static inline int es_out_Control( es_out_t *out, int i_query, ... )
va_end( args );
return i_result;
}
/**
* \defgroup access Access
* @{
*/
enum access_query_e
{
/* capabilities */
ACCESS_CAN_FASTSEEK, /* arg1= vlc_bool_t* cannot fail */
ACCESS_CAN_PAUSE, /* arg1= vlc_bool_t* cannot fail */
ACCESS_CAN_CONTROL_PACE,/* arg1= vlc_bool_t* cannot fail */
/* */
ACCESS_GET_MTU, /* arg1= int* cannot fail (0 if no sense) */
ACCESS_GET_SIZE, /* arg1= int64_t* cannot fail (0 if unknown) */
ACCESS_GET_POS, /* arg1= int64_t* cannot fail */
/* */
ACCESS_SET_PAUSE_STATE /* arg1= vlc_bool_t can fail if unsuported */
};
struct access_t
{
VLC_COMMON_MEMBERS
/* Module properties */
module_t *p_module;
/* Access name (empty if non forced) */
char *psz_access;
char *psz_path;
/* Access can fill this entry to force a deluxer */
char *psz_demux;
/* set by access (only one of pf_read/pf_block may be filled) */
int (*pf_read) ( access_t *, uint8_t *, int ); /* 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 */
int (*pf_seek) ( access_t *, int64_t );
int (*pf_control)( access_t *, int i_query, va_list args);
access_sys_t *p_sys;
};
#define access2_New( a, b, c, d ) __acess2_New(VLC_OBJECT(a), b, c, d)
VLC_EXPORT( demux_t *, __access2_New, ( vlc_object_t *p_obj, char *psz_mrl, stream_t *s, es_out_t *out ) );
VLC_EXPORT( void, access2_Delete, ( demux_t * ) );
static inline int access2_vaControl( access_t *p_access, int i_query, va_list args )
{
return p_access->pf_control( p_access, i_query, args );
}
static inline int access2_Control( access_t *p_access, int i_query, ... )
{
va_list args;
int i_result;
va_start( args, i_query );
i_result = access2_vaControl( p_access, i_query, args );
va_end( args );
return i_result;
}
/**
* @}
*/
/**
* \defgroup stream Stream
......@@ -328,8 +398,12 @@ VLC_EXPORT( int, demux_Control, ( input_thread_t *, int i_query, ... )
VLC_EXPORT( int, demux_vaControlDefault, ( input_thread_t *, int i_query, va_list ) );
/* Access */
VLC_EXPORT( int, access_vaControl, ( input_thread_t *, int i_query, va_list ) );
VLC_EXPORT( int, access_Control, ( input_thread_t *, int i_query, ... ) );
VLC_EXPORT( int, access_vaControlDefault,( input_thread_t *, int i_query, va_list ) );
/* New demux arch: don't touch that */
/* stream_t *s could be null and then it mean a access+demux in one */
#define demux2_New( a, b, c, d ) __demux2_New(VLC_OBJECT(a), b, c, d)
VLC_EXPORT( demux_t *, __demux2_New, ( vlc_object_t *p_obj, char *psz_mrl, stream_t *s, es_out_t *out ) );
......
......@@ -240,6 +240,7 @@ typedef struct es_out_t es_out_t;
typedef struct es_out_id_t es_out_id_t;
typedef struct es_out_sys_t es_out_sys_t;
typedef struct demux_t demux_t;
typedef struct access_t access_t;
/* Audio */
typedef struct aout_instance_t aout_instance_t;
......
......@@ -50,6 +50,7 @@
#define VLC_OBJECT_VLM (-16)
#define VLC_OBJECT_ANNOUNCE (-17)
#define VLC_OBJECT_DEMUX (-18)
#define VLC_OBJECT_ACCESS (-19)
#define VLC_OBJECT_GENERIC (-666)
......
/*****************************************************************************
* access.c
*****************************************************************************
* Copyright (C) 1999-2004 VideoLAN
* $Id: demux.c 7546 2004-04-29 13:53:29Z gbazin $
*
* Author: 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
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <stdlib.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include "ninput.h"
int access_vaControl( input_thread_t *p_input, int i_query, va_list args )
{
if( p_input->pf_access_control )
{
return p_input->pf_access_control( p_input, i_query, args );
}
return VLC_EGENERIC;
}
int access_Control( input_thread_t *p_input, int i_query, ... )
{
va_list args;
int i_result;
va_start( args, i_query );
i_result = access_vaControl( p_input, i_query, args );
va_end( args );
return i_result;
}
int access_vaControlDefault( input_thread_t *p_input, int i_query, va_list args )
{
return VLC_EGENERIC;
}
/*****************************************************************************
* access2_New:
*****************************************************************************/
access_t *__access2_New( vlc_object_t *p_obj,
char *psz_mrl, stream_t *s, es_out_t *out )
{
msg_Err( p_obj, "access2_New not yet implemented" );
return NULL;
#if 0
access_t *p_access = vlc_object_create( p_obj, VLC_OBJECT_ACCESS );
char *psz_dup = strdup( psz_mrl ? psz_mrl : "" );
char *psz = strchr( psz_dup, ':' );
char *psz_module;
if( p_demux == NULL )
{
free( psz_dup );
return NULL;
}
/* Parse URL */
p_demux->psz_access = NULL;
p_demux->psz_demux = NULL;
p_demux->psz_path = NULL;
if( psz )
{
*psz++ = '\0';
if( psz[0] == '/' && psz[1] == '/' )
{
psz += 2;
}
p_demux->psz_path = strdup( psz );
psz = strchr( psz_dup, '/' );
if( psz )
{
*psz++ = '\0';
p_demux->psz_access = strdup( psz_dup );
p_demux->psz_demux = strdup( psz );
}
}
else
{
p_demux->psz_path = strdup( psz_mrl );
}
free( psz_dup );
if( p_demux->psz_access == NULL )
{
p_demux->psz_access = strdup( "" );
}
if( p_demux->psz_demux == NULL )
{
p_demux->psz_demux = strdup( "" );
}
if( p_demux->psz_path == NULL )
{
p_demux->psz_path = strdup( "" );
}
msg_Dbg( p_obj, "demux2_New: '%s' -> access='%s' demux='%s' path='%s'",
psz_mrl,
p_demux->psz_access, p_demux->psz_demux, p_demux->psz_path );
p_demux->s = s;
p_demux->out = out;
p_demux->pf_demux = NULL;
p_demux->pf_control = NULL;
p_demux->p_sys = NULL;
psz_module = p_demux->psz_demux;
if( *psz_module == '\0' && strrchr( p_demux->psz_path, '.' ) )
{
/* XXX: add only file without any problem here and with strong detection.
* - no .mp3, .a52, ... (aac is added as it works only by file ext anyway
* - wav can't be added 'cause of a52 and dts in them as raw audio
*/
static struct { char *ext; char *demux; } exttodemux[] =
{
{ "aac", "aac" },
{ "aiff", "aiff" },
{ "asf", "asf" }, { "wmv", "asf" }, { "wma", "asf" },
{ "avi", "avi" },
{ "au", "au" },
{ "flac", "flac" },
{ "dv", "dv" },
{ "m3u", "m3u" },
{ "mkv", "mkv" }, { "mka", "mkv" }, { "mks", "mkv" },
{ "mp4", "mp4" }, { "m4a", "mp4" }, { "mov", "mp4" }, { "moov", "mp4" },
{ "mod", "mod" }, { "xm", "mod" },
{ "nsv", "nsv" },
{ "ogg", "ogg" }, { "ogm", "ogg" },
{ "pva", "pva" },
{ "rm", "rm" },
{ "", "" },
};
char *psz_ext = strrchr( p_demux->psz_path, '.' ) + 1;
int i;
for( i = 0; exttodemux[i].ext != NULL; i++ )
{
if( !strcasecmp( psz_ext, exttodemux[i].ext ) )
{
psz_module = exttodemux[i].demux;
break;
}
}
}
/* Before module_Need (for var_Create...) */
vlc_object_attach( p_demux, p_obj );
p_demux->p_module =
module_Need( p_demux, "demux2", psz_module,
!strcmp( psz_module, p_demux->psz_demux ) ? VLC_TRUE : VLC_FALSE );
if( p_demux->p_module == NULL )
{
vlc_object_detach( p_demux );
free( p_demux->psz_path );
free( p_demux->psz_demux );
free( p_demux->psz_access );
vlc_object_destroy( p_demux );
return NULL;
}
return p_demux;
#endif
}
/*****************************************************************************
* demux2_Delete:
*****************************************************************************/
void access2_Delete( access_t *p_access )
{
module_Unneed( p_access, p_access->p_module );
vlc_object_detach( p_access );
free( p_access->psz_access );
free( p_access->psz_path );
free( p_access->psz_demux );
vlc_object_destroy( p_access );
}
......@@ -46,7 +46,7 @@ struct es_out_id_t
struct es_out_sys_t
{
input_thread_t *p_input;
vlc_bool_t b_pcr_set;
vlc_bool_t b_convert_ts_auto; /* automatically convert TimeStamp */
/* all es */
int i_id;
......@@ -99,7 +99,7 @@ es_out_t *input_EsOutNew( input_thread_t *p_input )
out->p_sys = p_sys;
p_sys->p_input = p_input;
p_sys->b_pcr_set = VLC_FALSE;
p_sys->b_convert_ts_auto = VLC_TRUE;
p_sys->b_active = VLC_FALSE;
p_sys->i_mode = ES_OUT_MODE_AUTO;
......@@ -159,7 +159,7 @@ void input_EsOutDelete( es_out_t *out )
static pgrm_descriptor_t *EsOutAddProgram( es_out_t *out, int i_group )
{
input_thread_t *p_input = out->p_sys->p_input;
pgrm_descriptor_t *p_prgm;
pgrm_descriptor_t *p_pgrm;
es_descriptor_t *p_pmt;
/* FIXME we should use a object variable but a lot of place in src/input
......@@ -167,23 +167,23 @@ static pgrm_descriptor_t *EsOutAddProgram( es_out_t *out, int i_group )
int i_select = config_GetInt( p_input, "program" );
/* create it */
p_prgm = input_AddProgram( p_input, i_group, 0 );
p_pgrm = input_AddProgram( p_input, i_group, 0 );
/* XXX welcome to kludge, add a dummy es, if you want to understand
* why have a look at input_SetProgram. Basicaly, it assume the first
* es to be the PMT, how that is stupid, nevertheless it is needed for
* the old ts demuxer */
p_pmt = input_AddES( p_input, p_prgm, 0, UNKNOWN_ES, NULL, 0 );
p_pmt = input_AddES( p_input, p_pgrm, 0, UNKNOWN_ES, NULL, 0 );
p_pmt->i_fourcc = VLC_FOURCC( 'n', 'u', 'l', 'l' );
/* Select i_select or the first by default */
if( p_input->stream.p_selected_program == NULL &&
( i_select <= 0 || i_select == i_group ) )
{
p_input->stream.p_selected_program = p_prgm;
p_input->stream.p_selected_program = p_pgrm;
}
return p_prgm;
return p_pgrm;
}
/**
......@@ -297,7 +297,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
es_out_sys_t *p_sys = out->p_sys;
input_thread_t *p_input = p_sys->p_input;
es_out_id_t *es = malloc( sizeof( es_out_id_t ) );
pgrm_descriptor_t *p_prgm = NULL;
pgrm_descriptor_t *p_pgrm = NULL;
char psz_cat[sizeof( _("Stream ") ) + 10];
char *psz_description;
......@@ -305,12 +305,12 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
if( fmt->i_group >= 0 )
{
/* search program */
p_prgm = input_FindProgram( p_input, fmt->i_group );
p_pgrm = input_FindProgram( p_input, fmt->i_group );
if( p_prgm == NULL )
if( p_pgrm == NULL )
{
/* Create it */
p_prgm = EsOutAddProgram( out, fmt->i_group );
p_pgrm = EsOutAddProgram( out, fmt->i_group );
}
}
if( fmt->i_id < 0 )
......@@ -319,7 +319,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
}
psz_description = LanguageGetName( fmt->psz_language );
es->p_es = input_AddES( p_input, p_prgm, fmt->i_id + 1,
es->p_es = input_AddES( p_input, p_pgrm, fmt->i_id + 1,
fmt->i_cat, psz_description, 0 );
es->p_es->i_stream_id = fmt->i_id;
es->p_es->i_fourcc = fmt->i_codec;
......@@ -451,7 +451,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
{
es_out_sys_t *p_sys = out->p_sys;
if( p_sys->b_pcr_set )
if( p_sys->b_convert_ts_auto )
{
pgrm_descriptor_t *p_pgrm = es->p_es->p_pgrm;
input_thread_t *p_input = p_sys->p_input;
......@@ -665,31 +665,30 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
case ES_OUT_SET_PCR:
case ES_OUT_SET_GROUP_PCR:
{
pgrm_descriptor_t *p_prgm = NULL;
pgrm_descriptor_t *p_pgrm = NULL;
int64_t i_pcr;
if( i_query == ES_OUT_SET_PCR )
{
p_prgm = p_sys->p_input->stream.p_selected_program;
p_pgrm = p_sys->p_input->stream.p_selected_program;
}
else
{
int i_group = (int)va_arg( args, int );
p_prgm = input_FindProgram( p_sys->p_input, i_group );
if( p_prgm == NULL )
p_pgrm = input_FindProgram( p_sys->p_input, i_group );
if( p_pgrm == NULL )
{
/* we create the requested program */
p_prgm = EsOutAddProgram( out, i_group );
p_pgrm = EsOutAddProgram( out, i_group );
}
}
i_pcr = (int64_t)va_arg( args, int64_t );
/* search program */
if( p_prgm )
if( p_pgrm )
{
/* 11 is a vodoo trick to avoid non_pcr*9/100 to be null */
input_ClockManageRef( p_sys->p_input, p_prgm, (i_pcr + 11 ) * 9 / 100);
input_ClockManageRef( p_sys->p_input, p_pgrm, (i_pcr + 11 ) * 9 / 100);
}
p_sys->b_pcr_set = VLC_TRUE;
return VLC_SUCCESS;
}
......@@ -700,9 +699,32 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args )
SYNCHRO_REINIT;
p_sys->p_input->stream.pp_programs[i]->last_pts = 0;
}
p_sys->b_pcr_set = VLC_TRUE;
return VLC_SUCCESS;
case ES_OUT_CONVERT_TIMESTAMP:
case ES_OUT_CONVERT_GROUP_TIMESTAMP:
{
pgrm_descriptor_t *p_pgrm = NULL;
if( i_query == ES_OUT_CONVERT_TIMESTAMP )
{
p_pgrm = p_sys->p_input->stream.p_selected_program;
}
else
{
int i_group = (int)va_arg( args, int );
p_pgrm = input_FindProgram( p_sys->p_input, i_group );
}
if( p_pgrm )
{
int64_t *pi_ts = (int64_t*)va_arg( args, int64_t* );
*pi_ts = input_ClockGetTS( p_sys->p_input, p_pgrm, ( *pi_ts + 11 ) * 9 / 100 );
}
p_sys->b_convert_ts_auto = VLC_FALSE;
return VLC_SUCCESS;
}
default:
msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
return VLC_EGENERIC;
......
......@@ -496,6 +496,7 @@ static void PrintMsg ( vlc_object_t * p_this, msg_item_t * p_item )
case VLC_OBJECT_VLM: psz_object = "vlm"; break;
case VLC_OBJECT_ANNOUNCE: psz_object = "announce handler"; break;
case VLC_OBJECT_DEMUX: psz_object = "demuxer"; break;
case VLC_OBJECT_ACCESS: psz_object = "access"; break;
}
#ifdef UNDER_CE
......
......@@ -132,6 +132,10 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type )
i_size = sizeof(demux_t);
psz_type = "demux";
break;
case VLC_OBJECT_ACCESS:
i_size = sizeof(access_t);
psz_type = "access";
break;
case VLC_OBJECT_DECODER:
i_size = sizeof(decoder_t);
psz_type = "decoder";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment