/*****************************************************************************
* demux.c
*****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
+ * Copyright (C) 1999-2004 VLC authors and VideoLAN
* $Id$
*
* 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
+ * 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
* (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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
return path;
}
-
+#undef demux_New
/*****************************************************************************
* demux_New:
* if s is NULL then load a access_demux
*****************************************************************************/
-demux_t *__demux_New( vlc_object_t *p_obj, input_thread_t *p_parent_input,
- const char *psz_access, const char *psz_demux,
- const char *psz_location,
- stream_t *s, es_out_t *out, bool b_quick )
+demux_t *demux_New( vlc_object_t *p_obj, input_thread_t *p_parent_input,
+ const char *psz_access, const char *psz_demux,
+ const char *psz_location,
+ stream_t *s, es_out_t *out, bool b_quick )
{
demux_t *p_demux = vlc_custom_create( p_obj, sizeof( *p_demux ), "demux" );
- const char *psz_module;
-
- if( p_demux == NULL ) return NULL;
+ if( unlikely(p_demux == NULL) )
+ return NULL;
p_demux->p_input = p_parent_input;
-
- /* Parse URL */
p_demux->psz_access = strdup( psz_access );
- p_demux->psz_demux = strdup( psz_demux );
+
+ if( psz_demux[0] == '\0' )
+ /* Take into account "demux" to be able to do :demux=dump */
+ p_demux->psz_demux = var_InheritString( p_obj, "demux" );
+ else
+ p_demux->psz_demux = strdup( psz_demux );
+
p_demux->psz_location = strdup( psz_location );
- p_demux->psz_file = get_path( psz_location );
+ p_demux->psz_file = get_path( psz_location ); /* parse URL */
- /* Take into account "demux" to be able to do :demux=dump */
- if( *p_demux->psz_demux == '\0' )
- {
- free( p_demux->psz_demux );
- p_demux->psz_demux = var_GetNonEmptyString( p_obj, "demux" );
- if( p_demux->psz_demux == NULL )
- p_demux->psz_demux = strdup( "" );
- }
+ if( unlikely(p_demux->psz_access == NULL
+ || p_demux->psz_demux == NULL
+ || p_demux->psz_location == NULL) )
+ goto error;
if( !b_quick )
msg_Dbg( p_obj, "creating demux: access='%s' demux='%s' "
p_demux->info.i_title = 0;
p_demux->info.i_seekpoint = 0;
- if( s ) psz_module = p_demux->psz_demux;
- else psz_module = p_demux->psz_access;
-
- const char *psz_ext;
-
- if( s && *psz_module == '\0'
- && p_demux->psz_file != NULL
- && (psz_ext = strrchr( p_demux->psz_file, '.' )) )
+ /* NOTE: Add only file without any problems here and with strong detection:
+ * - no .mp3, .a52, ...
+ * - wav can't be added 'cause of a52 and dts in them as raw audio
+ */
+ static const struct { char ext[5]; char demux[9]; } exttodemux[] =
{
- /* 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 const struct { char ext[5]; char demux[9]; } exttodemux[] =
- {
- { "aac", "aac" },
- { "aiff", "aiff" },
- { "asf", "asf" }, { "wmv", "asf" }, { "wma", "asf" },
- { "avi", "avi" },
- { "au", "au" },
- { "flac", "flac" },
- { "dv", "dv" },
- { "drc", "dirac" },
- { "m3u", "m3u" },
- { "m3u8", "m3u8" },
- { "mkv", "mkv" }, { "mka", "mkv" }, { "mks", "mkv" },
- { "mp4", "mp4" }, { "m4a", "mp4" }, { "mov", "mp4" }, { "moov", "mp4" },
- { "nsv", "nsv" },
- { "ogg", "ogg" }, { "ogm", "ogg" }, /* legacy Ogg */
- { "oga", "ogg" }, { "spx", "ogg" }, { "ogv", "ogg" },
- { "ogx", "ogg" }, /*RFC5334*/
- { "pva", "pva" },
- { "rm", "rm" },
- { "m4v", "m4v" },
- { "h264", "h264" },
- { "voc", "voc" },
- { "mid", "smf" }, { "rmi", "smf" },
- { "", "" },
- };
- /* Here, we don't mind if it does not work, it must be quick */
- static const struct { char ext[4]; char demux[5]; } exttodemux_quick[] =
- {
- { "mp3", "mpga" },
- { "ogg", "ogg" },
- { "wma", "asf" },
- { "", "" }
- };
+ { "aiff", "aiff" },
+ { "asf", "asf" }, { "wmv", "asf" }, { "wma", "asf" },
+ { "avi", "avi" },
+ { "au", "au" },
+ { "flac", "flac" },
+ { "dv", "dv" },
+ { "drc", "dirac" },
+ { "m3u", "m3u" },
+ { "m3u8", "m3u8" },
+ { "mkv", "mkv" }, { "mka", "mkv" }, { "mks", "mkv" },
+ { "mp4", "mp4" }, { "m4a", "mp4" }, { "mov", "mp4" }, { "moov", "mp4" },
+ { "nsv", "nsv" },
+ { "ogg", "ogg" }, { "ogm", "ogg" }, /* legacy Ogg */
+ { "oga", "ogg" }, { "spx", "ogg" }, { "ogv", "ogg" },
+ { "ogx", "ogg" }, /*RFC5334*/
+ { "opus", "ogg" }, /*draft-terriberry-oggopus-01*/
+ { "pva", "pva" },
+ { "rm", "avformat" },
+ { "m4v", "m4v" },
+ { "h264", "h264" },
+ { "voc", "voc" },
+ { "mid", "smf" }, { "rmi", "smf" }, { "kar", "smf" },
+ { "", "" },
+ };
+ /* Here, we don't mind if it does not work, it must be quick */
+ static const struct { char ext[4]; char demux[5]; } exttodemux_quick[] =
+ {
+ { "mp3", "mpga" },
+ { "ogg", "ogg" },
+ { "wma", "asf" },
+ { "", "" }
+ };
- psz_ext++; // skip '.'
+ if( s != NULL )
+ {
+ const char *psz_ext;
+ const char *psz_module = p_demux->psz_demux;
- if( !b_quick )
+ if( !strcmp(psz_module, "any") && p_demux->psz_file != NULL
+ && (psz_ext = strrchr( p_demux->psz_file, '.' )) != NULL )
{
- for( unsigned i = 0; exttodemux[i].ext[0]; i++ )
+ psz_ext++; // skip '.'
+
+ if( !b_quick )
{
- if( !strcasecmp( psz_ext, exttodemux[i].ext ) )
+ for( unsigned i = 0; exttodemux[i].ext[0]; i++ )
{
- psz_module = exttodemux[i].demux;
- break;
+ if( !strcasecmp( psz_ext, exttodemux[i].ext ) )
+ {
+ psz_module = exttodemux[i].demux;
+ break;
+ }
}
}
- }
- else
- {
- for( unsigned i = 0; exttodemux_quick[i].ext[0]; i++ )
+ else
{
- if( !strcasecmp( psz_ext, exttodemux_quick[i].ext ) )
+ for( unsigned i = 0; exttodemux_quick[i].ext[0]; i++ )
{
- psz_module = exttodemux_quick[i].demux;
- break;
+ if( !strcasecmp( psz_ext, exttodemux_quick[i].ext ) )
+ {
+ psz_module = exttodemux_quick[i].demux;
+ break;
+ }
}
}
-
}
- }
- if( s )
- {
/* ID3/APE tags will mess-up demuxer probing so we skip it here.
* ID3/APE parsers will called later on in the demuxer to access the
* skipped info. */
- if( !SkipID3Tag( p_demux ) )
- SkipAPETag( p_demux );
+ while (SkipID3Tag( p_demux ))
+ ;
+ SkipAPETag( p_demux );
p_demux->p_module =
module_need( p_demux, "demux", psz_module,
else
{
p_demux->p_module =
- module_need( p_demux, "access_demux", psz_module,
- !strcmp( psz_module, p_demux->psz_access ) );
+ module_need( p_demux, "access_demux", p_demux->psz_access, true );
}
if( p_demux->p_module == NULL )
- {
- free( p_demux->psz_file );
- free( p_demux->psz_location );
- free( p_demux->psz_demux );
- free( p_demux->psz_access );
- vlc_object_release( p_demux );
- return NULL;
- }
+ goto error;
return p_demux;
+error:
+ free( p_demux->psz_file );
+ free( p_demux->psz_location );
+ free( p_demux->psz_demux );
+ free( p_demux->psz_access );
+ vlc_object_release( p_demux );
+ return NULL;
}
/*****************************************************************************
*****************************************************************************/
void demux_Delete( demux_t *p_demux )
{
- module_unneed( p_demux, p_demux->p_module );
+ stream_t *s;
+ module_unneed( p_demux, p_demux->p_module );
free( p_demux->psz_file );
free( p_demux->psz_location );
free( p_demux->psz_demux );
free( p_demux->psz_access );
+ s = p_demux->s;
vlc_object_release( p_demux );
+ if( s != NULL )
+ stream_Delete( s );
}
/*****************************************************************************
}
return VLC_EGENERIC;
+ case DEMUX_GET_META:
+ return stream_vaControl( s, STREAM_GET_META, args );
+
+ case DEMUX_IS_PLAYLIST:
+ return stream_vaControl(s, STREAM_IS_DIRECTORY, args );
+
case DEMUX_GET_PTS_DELAY:
case DEMUX_GET_FPS:
- case DEMUX_GET_META:
case DEMUX_HAS_UNSUPPORTED_META:
case DEMUX_SET_NEXT_DEMUX_TIME:
case DEMUX_GET_TITLE_INFO:
case DEMUX_SET_GROUP:
+ case DEMUX_SET_ES:
case DEMUX_GET_ATTACHMENTS:
case DEMUX_CAN_RECORD:
case DEMUX_SET_RECORD_STATE:
+ case DEMUX_GET_SIGNAL:
return VLC_EGENERIC;
default:
i_size += 10;
/* Skip the entire tag */
- stream_Read( p_demux->s, NULL, i_size );
+ if( stream_Read( p_demux->s, NULL, i_size ) < i_size )
+ return false;
msg_Dbg( p_demux, "ID3v2.%d revision %d tag found, skipping %d bytes",
version, revision, i_size );
i_size = GetDWLE( &p_peek[8+4] ) + ( (flags&(1<<30)) ? 32 : 0 );
/* Skip the entire tag */
- stream_Read( p_demux->s, NULL, i_size );
+ if( stream_Read( p_demux->s, NULL, i_size ) < i_size )
+ return false;
msg_Dbg( p_demux, "AP2 v%d tag found, skipping %d bytes",
i_version/1000, i_size );