Commit 9b11af62 authored by Gildas Bazin's avatar Gildas Bazin

* src/playlist/playlist.c: when autodeleting an item, we don't need to skip
   to the next one.
* modules/demux/m3u.c: added .asx support and changed the autodetection of
   file type to just probe the file extension.
parent eb186219
/***************************************************************************** /*****************************************************************************
* m3u.c: a meta demux to parse m3u playlists * m3u.c: a meta demux to parse m3u and asx playlists
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: m3u.c,v 1.1 2002/11/12 22:18:54 sigmunau Exp $ * $Id: m3u.c,v 1.2 2002/11/13 11:09:56 gbazin Exp $
* *
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
* Gildas Bazin <gbazin@netcourrier.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -35,8 +36,17 @@ ...@@ -35,8 +36,17 @@
#include <sys/types.h> #include <sys/types.h>
/***************************************************************************** /*****************************************************************************
* Constants * Constants and structures
*****************************************************************************/ *****************************************************************************/
#define MAX_LINE 1024
#define TYPE_M3U 1
#define TYPE_ASX 2
struct demux_sys_t
{
int i_type; /* playlist type (m3u/asx) */
};
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -48,7 +58,7 @@ static int Demux ( input_thread_t * ); ...@@ -48,7 +58,7 @@ static int Demux ( input_thread_t * );
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
vlc_module_begin(); vlc_module_begin();
set_description( "m3u metademux" ); set_description( "m3u/asx metademux" );
set_capability( "demux", 10 ); set_capability( "demux", 10 );
set_callbacks( Init, NULL ); set_callbacks( Init, NULL );
vlc_module_end(); vlc_module_end();
...@@ -58,11 +68,10 @@ vlc_module_end(); ...@@ -58,11 +68,10 @@ vlc_module_end();
*****************************************************************************/ *****************************************************************************/
static int Init( vlc_object_t * p_this ) static int Init( vlc_object_t * p_this )
{ {
input_thread_t * p_input = (input_thread_t *)p_this; input_thread_t *p_input = (input_thread_t *)p_this;
byte_t * p_peek; char *psz_ext;
int i_size, i_pos; demux_sys_t *p_m3u;
playlist_t * p_playlist; int i_type = 0;
int b_first = 1;
/* Initialize access plug-in structures. */ /* Initialize access plug-in structures. */
if( p_input->i_mtu == 0 ) if( p_input->i_mtu == 0 )
...@@ -74,67 +83,148 @@ static int Init( vlc_object_t * p_this ) ...@@ -74,67 +83,148 @@ static int Init( vlc_object_t * p_this )
p_input->pf_demux = Demux; p_input->pf_demux = Demux;
p_input->pf_rewind = NULL; p_input->pf_rewind = NULL;
/* Have a peep at the show. */ /* Check for m3u/asx file extension */
if( input_Peek( p_input, &p_peek, 7 ) < 7 ) psz_ext = strrchr ( p_input->psz_name, '.' );
if( !strcasecmp( psz_ext, ".m3u") )
{ {
/* Stream shorter than 7 bytes... */ i_type = TYPE_M3U;
msg_Err( p_input, "cannot peek()" ); }
return( -1 ); else if( !strcasecmp( psz_ext, ".asx") )
{
i_type = TYPE_ASX;
} }
#define MAX_LINE 1024 if( !i_type )
if( !strncmp( p_peek, "#EXTM3U", 7) return -1;
|| ( p_input->psz_demux && !strncmp(p_input->psz_demux, "m3u", 3) ) )
/* Allocate p_m3u */
if( !( p_m3u = malloc( sizeof( demux_sys_t ) ) ) )
{ {
p_playlist = msg_Err( p_input, "out of memory" );
(playlist_t *) vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, return -1;
}
p_input->p_demux_data = p_m3u;
p_m3u->i_type = i_type;
return 0;
}
static int Demux ( input_thread_t *p_input )
{
data_packet_t *p_data;
char *p_buf, psz_line[MAX_LINE], *psz_bol, eol_tok;
int i_size, i_bufpos, i_linepos = 0;
playlist_t *p_playlist;
vlc_bool_t b_discard = VLC_FALSE;
demux_sys_t *p_m3u = (demux_sys_t *)p_input->p_demux_data;
p_playlist = (playlist_t *) vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
FIND_ANYWHERE ); FIND_ANYWHERE );
if( !p_playlist )
{
msg_Err( p_input, "can't find playlist" );
return -1;
}
p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE; p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
i_size = input_Peek( p_input, &p_peek, MAX_LINE );
while ( i_size > 0 ) { /* Depending on wether we are dealing with an m3u/asf file, the end of
i_pos = 0; * line token will be different */
if ( *p_peek == '#' ) {/*line is comment or extended info, if( p_m3u->i_type == TYPE_ASX )
ignored for now */ eol_tok = '>';
while ( *p_peek != '\n' && i_pos < i_size ) else
eol_tok = '\n';
while( ( i_size = input_SplitBuffer( p_input, &p_data, MAX_LINE ) ) > 0 )
{ {
i_bufpos = 0; p_buf = p_data->p_payload_start;
i_pos++; while( i_size )
p_peek++; {
} /* Build a line < MAX_LINE */
i_pos++; while( p_buf[i_bufpos] != eol_tok && i_size )
{
if( i_linepos == MAX_LINE || b_discard == VLC_TRUE )
{
/* line is bigger than MAX_LINE, discard it */
i_linepos = 0;
b_discard = VLC_TRUE;
} }
else else
{ {
byte_t *p_start = p_peek; psz_line[i_linepos] = p_buf[i_bufpos];
char *psz_entry; i_linepos++;
while ( *p_peek != '\n' )
{
i_pos++;
p_peek++;
} }
if ( i_pos ) /*ignore empty lines to */
i_size--; i_bufpos++;
}
/* Check if we need more data */
if( !i_size ) continue;
i_size--; i_bufpos++;
b_discard = VLC_FALSE;
/* Check for empty line */
if( !i_linepos ) continue;
psz_line[i_linepos] = '\0';
psz_bol = psz_line;
i_linepos = 0;
/* Remove unnecessary tabs or spaces at the beginning of line */
while( *psz_bol == ' ' || *psz_bol == '\t' ||
*psz_bol == '\n' || *psz_bol == '\r' )
psz_bol++;
if( p_m3u->i_type == TYPE_M3U )
{ {
psz_entry = malloc( i_pos + 1 ); /* Check for comment line */
memcpy( psz_entry, p_start, i_pos ); if( *psz_bol == '#' )
psz_entry[i_pos] = '\0'; /*line is comment or extended info, ignored for now */
playlist_Add( p_playlist, psz_entry, continue;
PLAYLIST_APPEND ,
PLAYLIST_END );
b_first = 0;
free( psz_entry );
} }
i_pos++; else
{
/* We are dealing with ASX files.
* We are looking for href html markups that begins with
* "mms://" */
char *psz_eol;
while( *psz_bol && strncasecmp( psz_bol, "href",
sizeof("href") - 1 ) )
psz_bol++;
if( !*psz_bol ) continue;
while( *psz_bol && strncasecmp( psz_bol, "mms://",
sizeof("mms://") - 1 ) )
psz_bol++;
if( !*psz_bol ) continue;
psz_eol = strchr( psz_bol, '"');
if( !psz_eol )
continue;
*psz_eol = '\0';
} }
p_input->p_current_data += i_pos;
i_size = input_Peek( p_input, &p_peek, MAX_LINE ); /*
* From now on, we know we've got a meaningful line
*/
playlist_Add( p_playlist, psz_bol,
PLAYLIST_APPEND, PLAYLIST_END );
continue;
} }
p_input->b_eof = VLC_TRUE;
return( 0 ); input_DeletePacket( p_input->p_method_data, p_data );
} }
return( -1 );
}
static int Demux ( input_thread_t *p_intput ) vlc_object_release( p_playlist );
{
return 0; return 0;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* playlist.c : Playlist management functions * playlist.c : Playlist management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: playlist.c,v 1.18 2002/11/12 21:20:36 gbazin Exp $ * $Id: playlist.c,v 1.19 2002/11/13 11:09:56 gbazin Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -307,7 +307,14 @@ static void RunThread ( playlist_t *p_playlist ) ...@@ -307,7 +307,14 @@ static void RunThread ( playlist_t *p_playlist )
/* Check for autodeletion */ /* Check for autodeletion */
if( p_playlist->pp_items[p_playlist->i_index]->b_autodeletion ) if( p_playlist->pp_items[p_playlist->i_index]->b_autodeletion )
{
playlist_Delete( p_playlist, p_playlist->i_index ); playlist_Delete( p_playlist, p_playlist->i_index );
}
else
{
/* Select the next playlist item */
SkipItem( p_playlist, 1 );
}
/* Destroy input */ /* Destroy input */
input_DestroyThread( p_input ); input_DestroyThread( p_input );
...@@ -323,9 +330,6 @@ static void RunThread ( playlist_t *p_playlist ) ...@@ -323,9 +330,6 @@ static void RunThread ( playlist_t *p_playlist )
else if( p_playlist->p_input->b_error else if( p_playlist->p_input->b_error
|| p_playlist->p_input->b_eof ) || p_playlist->p_input->b_eof )
{ {
/* Select the next playlist item */
SkipItem( p_playlist, 1 );
/* Release the playlist lock, because we may get stuck /* Release the playlist lock, because we may get stuck
* in input_StopThread() for some time. */ * in input_StopThread() for some time. */
vlc_mutex_unlock( &p_playlist->object_lock ); vlc_mutex_unlock( &p_playlist->object_lock );
......
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