Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
7f819953
Commit
7f819953
authored
Jun 28, 2003
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* m3u: clean up and fix .m3u parsing. Please *test*.
parent
00eecb8d
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
177 additions
and
270 deletions
+177
-270
modules/demux/m3u.c
modules/demux/m3u.c
+177
-270
No files found.
modules/demux/m3u.c
View file @
7f819953
...
...
@@ -2,7 +2,7 @@
* m3u.c: a meta demux to parse pls, m3u, asx et b4s playlists
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: m3u.c,v 1.2
0 2003/06/27 10:31:02 zorglub
Exp $
* $Id: m3u.c,v 1.2
1 2003/06/28 19:19:55 fenrir
Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
* Gildas Bazin <gbazin@netcourrier.com>
...
...
@@ -12,7 +12,7 @@
* 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
...
...
@@ -27,15 +27,11 @@
* Preamble
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <string.h>
/* strdup() */
#include <errno.h>
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc_playlist.h>
#include <sys/types.h>
/*****************************************************************************
* Constants and structures
*****************************************************************************/
...
...
@@ -48,13 +44,6 @@
#define TYPE_PLS 4
#define TYPE_B4S 5
struct
item_t
{
char
*
psz_name
;
char
*
psz_uri
;
};
struct
demux_sys_t
{
int
i_type
;
/* playlist type (m3u/asx) */
...
...
@@ -88,9 +77,8 @@ static int Activate( vlc_object_t * p_this )
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
char
*
psz_ext
;
demux_sys_t
*
p_m3u
;
int
i_type
=
0
;
int
i_type2
=
0
;
int
i_type
=
TYPE_UNKNOWN
;
int
i_type2
=
TYPE_UNKNOWN
;
/* Initialize access plug-in structures. */
if
(
p_input
->
i_mtu
==
0
)
...
...
@@ -135,6 +123,7 @@ static int Activate( vlc_object_t * p_this )
* at the content. This is useful for .asp, .php and similar files
* that are actually html. Also useful for som asx files that have
* another extention */
/* XXX we double check for file != m3u as some asx ... are just m3u file */
if
(
i_type
!=
TYPE_M3U
)
{
byte_t
*
p_peek
;
...
...
@@ -144,7 +133,7 @@ static int Activate( vlc_object_t * p_this )
while
(
i_size
&&
strncasecmp
(
p_peek
,
"[playlist]"
,
sizeof
(
"[playlist]"
)
-
1
)
&&
strncasecmp
(
p_peek
,
"<html>"
,
sizeof
(
"<html>"
)
-
1
)
&&
strncasecmp
(
p_peek
,
"<asx"
,
sizeof
(
"<asx"
)
-
1
)
&&
strncasecmp
(
p_peek
,
"<asx"
,
sizeof
(
"<asx"
)
-
1
)
&&
strncasecmp
(
p_peek
,
"<?xml"
,
sizeof
(
"<?xml"
)
-
1
)
)
{
p_peek
++
;
...
...
@@ -170,14 +159,13 @@ static int Activate( vlc_object_t * p_this )
{
i_type2
=
TYPE_B4S
;
}
}
}
if
(
!
i_type
&&
!
i_type2
)
if
(
i_type
==
TYPE_UNKNOWN
&&
i_type2
==
TYPE_UNKNOWN
)
{
return
-
1
;
return
VLC_EGENERIC
;
}
if
(
i_type
&&
!
i_type2
)
if
(
i_type
!=
TYPE_UNKNOWN
&&
i_type2
==
TYPE_UNKNOWN
)
{
i_type
=
TYPE_M3U
;
}
...
...
@@ -187,16 +175,10 @@ static int Activate( vlc_object_t * p_this )
}
/* Allocate p_m3u */
if
(
!
(
p_m3u
=
malloc
(
sizeof
(
demux_sys_t
)
)
)
)
{
msg_Err
(
p_input
,
"out of memory"
);
return
-
1
;
}
p_input
->
p_demux_data
=
p_m3u
;
p_m3u
->
i_type
=
i_type
;
p_input
->
p_demux_data
=
malloc
(
sizeof
(
demux_sys_t
)
);
p_input
->
p_demux_data
->
i_type
=
i_type
;
return
0
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
...
...
@@ -205,63 +187,71 @@ static int Activate( vlc_object_t * p_this )
static
void
Deactivate
(
vlc_object_t
*
p_this
)
{
input_thread_t
*
p_input
=
(
input_thread_t
*
)
p_this
;
demux_sys_t
*
p_m3u
=
(
demux_sys_t
*
)
p_input
->
p_demux_data
;
free
(
p_
m3u
);
free
(
p_
input
->
p_demux_data
);
}
/*****************************************************************************
* XMLSpecialChars: Handle the special chars in a XML file.
* Returns 0 if successful
* XMLSpecialChars: Handle the special chars in a XML file.
* ***************************************************************************/
static
int
XMLSpecialChars
(
char
*
psz_src
,
char
*
psz_dst
)
static
void
XMLSpecialChars
(
char
*
str
)
{
unsigned
int
i
;
unsigned
int
j
=
0
;
char
c_rplc
=
0
;
for
(
i
=
0
;
i
<
strlen
(
psz_src
)
;
i
++
)
char
*
src
=
str
;
char
*
dst
=
str
;
while
(
*
src
)
{
if
(
psz_src
[
i
]
==
'&'
)
if
(
*
src
==
'&'
)
{
if
(
!
strncasecmp
(
&
psz_src
[
i
],
"à"
,
6
)
)
c_rplc
=
''
;
else
if
(
!
strncasecmp
(
&
psz_src
[
i
],
"é"
,
6
)
)
c_rplc
=
''
;
else
if
(
!
strncasecmp
(
&
psz_src
[
i
],
"î"
,
6
)
)
c_rplc
=
''
;
else
if
(
!
strncasecmp
(
&
psz_src
[
i
],
"'"
,
6
)
)
c_rplc
=
'\''
;
else
if
(
!
strncasecmp
(
&
psz_src
[
i
],
"è"
,
6
)
)
c_rplc
=
''
;
else
if
(
!
strncasecmp
(
&
psz_src
[
i
],
"ê"
,
6
)
)
c_rplc
=
''
;
else
if
(
!
strncasecmp
(
&
psz_src
[
i
],
"ê"
,
6
)
)
c_rplc
=
''
;
psz_dst
[
j
]
=
c_rplc
;
j
++
;
i
=
i
+
6
;
if
(
!
strncasecmp
(
src
,
"à"
,
6
)
)
*
dst
++
=
''
;
else
if
(
!
strncasecmp
(
src
,
"î"
,
6
)
)
*
dst
++
=
''
;
else
if
(
!
strncasecmp
(
src
,
"'"
,
6
)
)
*
dst
++
=
'\''
;
else
if
(
!
strncasecmp
(
src
,
"è"
,
6
)
)
*
dst
++
=
''
;
else
if
(
!
strncasecmp
(
src
,
"é"
,
6
)
)
*
dst
++
=
''
;
else
if
(
!
strncasecmp
(
src
,
"ê"
,
6
)
)
*
dst
++
=
''
;
else
{
*
dst
++
=
'?'
;
}
src
+=
6
;
}
psz_dst
[
j
]
=
psz_src
[
i
];
j
++
;
}
psz_dst
[
j
]
=
'\0'
;
return
0
;
else
{
*
dst
++
=
*
src
++
;
}
}
*
dst
=
'\0'
;
}
/*****************************************************************************
* P
rocess
Line: read a "line" from the file and add any entries found
* P
arse
Line: read a "line" from the file and add any entries found
* to the playlist. Returns:
* 0 if nothing was found
* 1 if a URI was found (it is then copied in psz_data)
* 2 if a name was found ( " )
*
* XXX psz_data has the same length that psz_line so no problem if you don't
* expand it
* psz_line is \0 terminated
******************************************************************************/
static
int
ProcessLine
(
input_thread_t
*
p_input
,
demux_sys_t
*
p_m3u
,
playlist_t
*
p_playlist
,
char
psz_line
[
MAX_LINE
],
int
i_position
,
char
*
psz_data
)
static
int
ParseLine
(
input_thread_t
*
p_input
,
char
*
psz_line
,
char
*
psz_data
,
vlc_bool_t
*
pb_next
)
{
demux_sys_t
*
p_m3u
=
p_input
->
p_demux_data
;
char
*
psz_bol
,
*
psz_name
;
psz_bol
=
psz_line
;
*
pb_next
=
VLC_FALSE
;
/* 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
)
{
...
...
@@ -277,8 +267,8 @@ static int ProcessLine ( input_thread_t *p_input , demux_sys_t *p_m3u
if
(
!
psz_bol
)
return
0
;
psz_bol
++
;
/* From now, we have a name line */
str
ncpy
(
psz_data
,
psz_bol
,
strlen
(
psz_bol
)
);
str
cpy
(
psz_data
,
psz_bol
);
return
2
;
}
/* If we don't have a comment, the line is directly the URI */
...
...
@@ -375,62 +365,68 @@ static int ProcessLine ( input_thread_t *p_input , demux_sys_t *p_m3u
else
if
(
p_m3u
->
i_type
==
TYPE_B4S
)
{
char
*
psz_eol
;
/* We are dealing with a B4S file from Winamp 3 */
/* First, search for name *
* <Name>Blabla</Name> */
char
*
psz_eol
;
msg_Dbg
(
p_input
,
"b4s line=%s"
,
psz_line
);
/* We are dealing with a B4S file from Winamp 3 */
if
(
strstr
(
psz_bol
,
"<Name>"
)
)
{
/* We have a name */
/* First, search for name *
* <Name>Blabla</Name> */
if
(
strstr
(
psz_bol
,
"<Name>"
)
)
{
msg_Dbg
(
p_input
,
"###########<Name>"
);
/* We have a name */
while
(
*
psz_bol
&&
strncasecmp
(
psz_bol
,
"Name"
,
sizeof
(
"Name"
)
-
1
)
)
psz_bol
++
;
if
(
!*
psz_bol
)
return
0
;
psz_bol
=
psz_bol
+
5
;
/* We are now at the beginning of the name */
if
(
!
psz_bol
)
return
0
;
psz_eol
=
strchr
(
psz_bol
,
'<'
);
if
(
!
psz_eol
)
return
0
;
*
psz_eol
=
'\0'
;
if
(
XMLSpecialChars
(
psz_bol
,
psz_bol
)
)
return
0
;
strncpy
(
psz_data
,
psz_bol
,
strlen
(
psz_bol
)
);
return
2
;
}
strncasecmp
(
psz_bol
,
"Name"
,
sizeof
(
"Name"
)
-
1
)
)
psz_bol
++
;
if
(
!*
psz_bol
)
return
0
;
psz_bol
=
psz_bol
+
5
;
/* We are now at the beginning of the name */
if
(
!
psz_bol
)
return
0
;
psz_eol
=
strchr
(
psz_bol
,
'<'
);
if
(
!
psz_eol
)
return
0
;
*
psz_eol
=
'\0'
;
XMLSpecialChars
(
psz_bol
);
strcpy
(
psz_data
,
psz_bol
);
return
2
;
}
else
if
(
strstr
(
psz_bol
,
"</entry>"
)
||
strstr
(
psz_bol
,
"</Entry>"
))
{
msg_Dbg
(
p_input
,
"###########<Entry>"
);
*
pb_next
=
VLC_TRUE
;
return
0
;
}
/* We are looking for <entry Playstring="blabla"> */
while
(
*
psz_bol
&&
strncasecmp
(
psz_bol
,
"Playstring"
,
sizeof
(
"Playstring"
)
-
1
)
)
psz_bol
++
;
if
(
!*
psz_bol
)
return
0
;
while
(
*
psz_bol
&&
strncasecmp
(
psz_bol
,
"Playstring"
,
sizeof
(
"Playstring"
)
-
1
)
)
psz_bol
++
;
if
(
!*
psz_bol
)
return
0
;
psz_bol
=
strchr
(
psz_bol
,
'='
);
if
(
!
psz_bol
)
return
0
;
psz_bol
++
;
psz_bol
++
;
psz_bol
+=
2
;
psz_eol
=
strchr
(
psz_bol
,
'"'
);
if
(
!
psz_eol
)
return
0
;
*
psz_eol
=
'\0'
;
/* Handle the XML special characters */
if
(
XMLSpecialChars
(
psz_bol
,
psz_bol
)
)
return
0
;
/* Handle the XML special characters */
XMLSpecialChars
(
psz_bol
);
}
else
{
...
...
@@ -441,6 +437,7 @@ static int ProcessLine ( input_thread_t *p_input , demux_sys_t *p_m3u
/* empty line */
if
(
!*
psz_bol
)
return
0
;
msg_Dbg
(
p_input
,
"############Line=%s"
,
psz_bol
);
/*
* From now on, we know we've got a meaningful line
*/
...
...
@@ -514,12 +511,65 @@ static int ProcessLine ( input_thread_t *p_input , demux_sys_t *p_m3u
psz_name
=
strdup
(
psz_bol
);
}
str
ncpy
(
psz_data
,
psz_name
,
strlen
(
psz_name
)
)
;
str
cpy
(
psz_data
,
psz_name
)
;
free
(
psz_name
);
if
(
p_m3u
->
i_type
!=
TYPE_B4S
)
{
*
pb_next
=
VLC_TRUE
;
}
return
1
;
}
static
void
ProcessLine
(
input_thread_t
*
p_input
,
playlist_t
*
p_playlist
,
char
*
psz_line
,
char
**
ppsz_uri
,
char
**
ppsz_name
)
{
char
psz_data
[
MAX_LINE
];
vlc_bool_t
b_next
;
msg_Dbg
(
p_input
,
"ProcessLine(0): name=%s uri=%s "
,
*
ppsz_name
,
*
ppsz_uri
);
switch
(
ParseLine
(
p_input
,
psz_line
,
psz_data
,
&
b_next
)
)
{
case
1
:
if
(
*
ppsz_uri
)
{
free
(
*
ppsz_uri
);
}
*
ppsz_uri
=
strdup
(
psz_data
);
break
;
case
2
:
if
(
*
ppsz_name
)
{
free
(
*
ppsz_name
);
}
*
ppsz_name
=
strdup
(
psz_data
);
break
;
case
0
:
default:
break
;
}
msg_Dbg
(
p_input
,
"name=%s uri=%s next=%d"
,
*
ppsz_name
,
*
ppsz_uri
,
b_next
);
if
(
b_next
&&
*
ppsz_uri
)
{
playlist_AddName
(
p_playlist
,
*
ppsz_name
?
*
ppsz_name
:
*
ppsz_uri
,
*
ppsz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
if
(
*
ppsz_name
)
{
free
(
*
ppsz_name
);
}
free
(
*
ppsz_uri
);
*
ppsz_name
=
NULL
;
*
ppsz_uri
=
NULL
;
}
msg_Dbg
(
p_input
,
"ProcessLine(1:: name=%s uri=%s "
,
*
ppsz_name
,
*
ppsz_uri
);
}
/*****************************************************************************
* Demux: reads and demuxes data packets
*****************************************************************************
...
...
@@ -527,18 +577,18 @@ static int ProcessLine ( input_thread_t *p_input , demux_sys_t *p_m3u
*****************************************************************************/
static
int
Demux
(
input_thread_t
*
p_input
)
{
demux_sys_t
*
p_m3u
=
p_input
->
p_demux_data
;
data_packet_t
*
p_data
;
char
*
psz_data
=
NULL
;
char
*
p_buf
,
psz_line
[
MAX_LINE
],
eol_tok
;
char
psz_line
[
MAX_LINE
]
;
char
*
p_buf
,
eol_tok
;
int
i_size
,
i_bufpos
,
i_linepos
=
0
;
int
i_return
=
0
;
playlist_t
*
p_playlist
;
int
i_position
;
vlc_bool_t
b_discard
=
VLC_FALSE
;
struct
item_t
*
p_item
;
demux_sys_t
*
p_m3u
=
(
demux_sys_t
*
)
p_input
->
p_demux_data
;
char
*
psz_name
=
NULL
;
char
*
psz_uri
=
NULL
;
p_playlist
=
(
playlist_t
*
)
vlc_object_find
(
p_input
,
VLC_OBJECT_PLAYLIST
,
FIND_ANYWHERE
);
...
...
@@ -548,31 +598,11 @@ static int Demux ( input_thread_t *p_input )
return
-
1
;
}
p_item
=
(
struct
item_t
*
)
malloc
(
sizeof
(
struct
item_t
));
if
(
!
p_item
)
{
msg_Err
(
p_input
,
"No memory left"
)
;
return
VLC_EGENERIC
;
}
p_item
->
psz_uri
=
NULL
;
p_item
->
psz_name
=
NULL
;
psz_data
=
(
char
*
)
malloc
(
MAX_LINE
*
sizeof
(
char
)
);
if
(
!
psz_data
)
{
msg_Err
(
p_input
,
"No memory left"
);
return
VLC_EGENERIC
;
}
p_playlist
->
pp_items
[
p_playlist
->
i_index
]
->
b_autodeletion
=
VLC_TRUE
;
i_position
=
p_playlist
->
i_index
+
1
;
/* Depending on wether we are dealing with an m3u/asf file, the end of
* line token will be different */
if
(
p_m3u
->
i_type
==
TYPE_ASX
||
p_m3u
->
i_type
==
TYPE_HTML
)
// || p_m3u->i_type == TYPE_B4S )
eol_tok
=
'>'
;
else
eol_tok
=
'\n'
;
...
...
@@ -615,78 +645,8 @@ static int Demux ( input_thread_t *p_input )
psz_line
[
i_linepos
]
=
'\0'
;
i_linepos
=
0
;
memset
(
psz_data
,
0
,
MAX_LINE
)
;
i_return
=
ProcessLine
(
p_input
,
p_m3u
,
p_playlist
,
psz_line
,
i_position
,
psz_data
);
i_position
+=
i_return
;
if
(
i_return
==
1
)
/* We got a URI */
{
if
(
!
p_item
->
psz_uri
)
{
p_item
->
psz_uri
=
strdup
(
psz_data
);
}
else
/* We already have the URI !
We have started a new item, so we add this one */
{
if
(
!
p_item
->
psz_name
)
p_item
->
psz_name
=
strdup
(
p_item
->
psz_uri
);
playlist_AddName
(
p_playlist
,
p_item
->
psz_name
,
p_item
->
psz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
p_item
->
psz_name
=
NULL
;
p_item
->
psz_uri
=
NULL
;
}
p_item
->
psz_uri
=
strdup
(
psz_data
);
}
else
if
(
i_return
==
2
)
/* We got a name */
{
/* M3U: if I already have the URI, I can't have a name *
* So we add it now */
if
(
p_m3u
->
i_type
==
TYPE_M3U
&&
p_item
->
psz_uri
&&
!
p_item
->
psz_name
)
{
p_item
->
psz_name
=
strdup
(
p_item
->
psz_uri
);
playlist_AddName
(
p_playlist
,
p_item
->
psz_name
,
p_item
->
psz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
p_item
->
psz_uri
=
NULL
;
p_item
->
psz_name
=
NULL
;
}
if
(
!
p_item
->
psz_name
)
{
p_item
->
psz_name
=
strdup
(
psz_data
);
}
else
/* We already have the name ! */
{
if
(
!
p_item
->
psz_uri
)
{
/* We can't add ! We have no URI */
msg_Info
(
p_input
,
"Unable to add: no URI"
);
}
else
{
playlist_AddName
(
p_playlist
,
p_item
->
psz_name
,
p_item
->
psz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
p_item
->
psz_uri
=
NULL
;
p_item
->
psz_name
=
NULL
;
}
p_item
->
psz_name
=
strdup
(
psz_data
);
}
}
ProcessLine
(
p_input
,
p_playlist
,
psz_line
,
&
psz_uri
,
&
psz_name
);
}
input_DeletePacket
(
p_input
->
p_method_data
,
p_data
);
...
...
@@ -695,78 +655,25 @@ static int Demux ( input_thread_t *p_input )
if
(
i_linepos
&&
b_discard
!=
VLC_TRUE
&&
eol_tok
==
'\n'
)
{
psz_line
[
i_linepos
]
=
'\0'
;
i_linepos
=
0
;
i_return
=
ProcessLine
(
p_input
,
p_m3u
,
p_playlist
,
psz_line
,
i_position
,
psz_data
);
/* FIXME: This copy / past is UGLY */
if
(
i_return
==
1
)
/* We got a URI */
ProcessLine
(
p_input
,
p_playlist
,
psz_line
,
&
psz_uri
,
&
psz_name
);
/* is there a pendding uri without b_next */
if
(
psz_uri
)
{
if
(
!
p_item
->
psz_uri
)
{
p_item
->
psz_uri
=
strdup
(
psz_data
);
}
else
/* We already have the URI !
We have started a new item, so we add this one */
{
if
(
!
p_item
->
psz_name
)
p_item
->
psz_name
=
strdup
(
p_item
->
psz_uri
);
playlist_AddName
(
p_playlist
,
p_item
->
psz_name
,
p_item
->
psz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
p_item
->
psz_name
=
NULL
;
p_item
->
psz_uri
=
NULL
;
}
p_item
->
psz_uri
=
strdup
(
psz_data
);
}
else
if
(
i_return
==
2
)
/* We got a name */
{
if
(
!
p_item
->
psz_name
)
{
p_item
->
psz_name
=
strdup
(
psz_data
);
}
else
/* We already have the name ! */
{
if
(
!
p_item
->
psz_uri
)
{
/* We can't add ! We have no URI */
msg_Info
(
p_input
,
"Unable to add: no URI"
);
}
else
{
playlist_AddName
(
p_playlist
,
p_item
->
psz_name
,
p_item
->
psz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
p_item
->
psz_uri
=
NULL
;
p_item
->
psz_name
=
NULL
;
}
p_item
->
psz_name
=
strdup
(
psz_data
);
}
playlist_Add
(
p_playlist
,
psz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
}
}
/* Check if we have something left */
if
(
p_item
->
psz_uri
)
if
(
psz_uri
)
{
if
(
!
p_item
->
psz_name
)
p_item
->
psz_name
=
strdup
(
p_item
->
psz_uri
);
playlist_AddName
(
p_playlist
,
p_item
->
psz_name
,
p_item
->
psz_uri
,
PLAYLIST_INSERT
,
PLAYLIST_END
);
free
(
psz_uri
);
}
if
(
psz_name
)
{
free
(
psz_name
);
}
vlc_object_release
(
p_playlist
);
if
(
p_item
)
free
(
p_item
);
if
(
psz_data
)
free
(
psz_data
);
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment