~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to src/input/subtitles.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * subtitles.c
3
3
 *****************************************************************************
4
4
 * Copyright (C) 2003-2006 the VideoLAN team
5
 
 * $Id: 3efc30729b4fdc4fd15db4d0da64de9df461b5d5 $
 
5
 * $Id: 0ad27d3b82238d4d81fc79b9f759d1ed1c0790f6 $
6
6
 *
7
7
 * Authors: Derk-Jan Hartman <hartman at videolan.org>
8
8
 * This is adapted code from the GPL'ed MPlayer (http://mplayerhq.hu)
27
27
 *  This file contains functions to dectect subtitle files.
28
28
 */
29
29
 
30
 
#include <stdlib.h>
31
 
#include <vlc/vlc.h>
32
 
#include <vlc/input.h>
33
 
#include "charset.h"
 
30
#ifdef HAVE_CONFIG_H
 
31
# include "config.h"
 
32
#endif
 
33
 
 
34
#include <vlc_common.h>
 
35
#include <vlc_input.h>
 
36
#include <vlc_charset.h>
34
37
 
35
38
#ifdef HAVE_DIRENT_H
36
39
#   include <dirent.h>
37
40
#endif
38
41
 
39
 
#ifdef HAVE_LIMITS_H
40
 
#   include <limits.h>
41
 
#endif
 
42
#include <limits.h>
42
43
 
43
44
#ifdef HAVE_UNISTD_H
44
45
#   include <unistd.h>
45
46
#endif
 
47
#include <sys/stat.h>
46
48
 
47
49
#include <ctype.h>
48
 
 
49
 
/**
50
 
 * What's between a directory and a filename?
51
 
 */
52
 
#if defined( WIN32 )
53
 
    #define DIRECTORY_SEPARATOR '\\'
54
 
#else
55
 
    #define DIRECTORY_SEPARATOR '/'
56
 
#endif
 
50
#include "input_internal.h"
57
51
 
58
52
/**
59
53
 * We are not going to autodetect more subtitle files than this.
64
58
/**
65
59
 * The possible extensions for subtitle files we support
66
60
 */
67
 
static const char * sub_exts[] = {  "utf", "utf8", "utf-8", "sub", "srt", "smi", "txt", "ssa", "idx", NULL };
68
 
/* extensions from unsupported types */
69
 
/* rt, aqt, jss, js, ass */
 
61
static const char const sub_exts[][6] = {
 
62
    "idx", "sub",  "srt",
 
63
    "ssa", "ass",  "smi",
 
64
    "utf", "utf8", "utf-8",
 
65
    "txt", "rt",   "aqt",
 
66
    "usf", "jss",  "cdg",
 
67
    "psb", "mpsub","mpl2",
 
68
    "pjs", "dks",
 
69
    ""
 
70
};
70
71
 
71
 
static void strcpy_trim( char *d, char *s )
 
72
static void strcpy_trim( char *d, const char *s )
72
73
{
73
74
    /* skip leading whitespace */
74
75
    while( *s && !isalnum(*s) )
95
96
    *d = 0;
96
97
}
97
98
 
98
 
static void strcpy_strip_ext( char *d, char *s )
 
99
static void strcpy_strip_ext( char *d, const char *s )
99
100
{
100
 
    char *tmp = strrchr(s, '.');
 
101
    const char *tmp = strrchr(s, '.');
101
102
    if( !tmp )
102
103
    {
103
104
        strcpy(d, s);
112
113
    }
113
114
}
114
115
 
115
 
static void strcpy_get_ext( char *d, char *s )
 
116
static void strcpy_get_ext( char *d, const char *s )
116
117
{
117
 
    char *tmp = strrchr(s, '.');
 
118
    const char *tmp = strrchr(s, '.');
118
119
    if( !tmp )
119
 
    {
120
120
        strcpy(d, "");
121
 
        return;
122
 
    } else strcpy( d, tmp + 1 );
 
121
    else
 
122
        strcpy( d, tmp + 1 );
123
123
}
124
124
 
125
 
static int whiteonly( char *s )
 
125
static int whiteonly( const char *s )
126
126
{
127
 
  while ( *s )
128
 
  {
129
 
        if( isalnum( *s ) ) return 0;
 
127
    while( *s )
 
128
    {
 
129
        if( isalnum( *s ) )
 
130
            return 0;
130
131
        s++;
131
 
  }
132
 
  return 1;
 
132
    }
 
133
    return 1;
133
134
}
134
135
 
135
 
typedef struct _subfn
 
136
enum
 
137
{
 
138
    SUB_PRIORITY_NONE = 0,
 
139
    SUB_PRIORITY_MATCH_NONE = 1,
 
140
    SUB_PRIORITY_MATCH_RIGHT = 2,
 
141
    SUB_PRIORITY_MATCH_LEFT = 3,
 
142
    SUB_PRIORITY_MATCH_ALL = 4,
 
143
};
 
144
typedef struct
136
145
{
137
146
    int priority;
138
147
    char *psz_fname;
139
148
    char *psz_ext;
140
 
} subfn;
 
149
} vlc_subfn_t;
141
150
 
142
151
static int compare_sub_priority( const void *a, const void *b )
143
152
{
144
 
    if (((subfn*)a)->priority > ((subfn*)b)->priority)
145
 
    {
 
153
    const vlc_subfn_t *p0 = a;
 
154
    const vlc_subfn_t *p1 = b;
 
155
 
 
156
    if( p0->priority > p1->priority )
146
157
        return -1;
147
 
    }
148
158
 
149
 
    if (((subfn*)a)->priority < ((subfn*)b)->priority)
150
 
    {
 
159
    if( p0->priority < p1->priority )
151
160
        return 1;
152
 
    }
153
161
 
154
162
#ifndef UNDER_CE
155
 
    return strcoll(((subfn*)a)->psz_fname, ((subfn*)b)->psz_fname);
 
163
    return strcoll( p0->psz_fname, p1->psz_fname);
156
164
#else
157
 
    return strcmp(((subfn*)a)->psz_fname, ((subfn*)b)->psz_fname);
 
165
    return strcmp( p0->psz_fname, p1->psz_fname);
158
166
#endif
159
167
}
160
168
 
164
172
int subtitles_Filter( const char *psz_dir_content )
165
173
{
166
174
    const char *tmp = strrchr( psz_dir_content, '.');
167
 
    if( tmp == NULL )
 
175
    int i;
 
176
 
 
177
    if( !tmp )
168
178
        return 0;
169
 
    else
170
 
    {
171
 
        int i;
172
 
        tmp++;
 
179
    tmp++;
173
180
 
174
 
        for( i = 0; sub_exts[i]; i++ )
175
 
            if( strcmp( sub_exts[i], tmp ) == 0 )
176
 
                return 1;
177
 
    }
 
181
    for( i = 0; sub_exts[i][0]; i++ )
 
182
        if( strcasecmp( sub_exts[i], tmp ) == 0 )
 
183
            return 1;
178
184
    return 0;
179
185
}
180
186
 
182
188
/**
183
189
 * Convert a list of paths separated by ',' to a char**
184
190
 */
185
 
static char **paths_to_list( char *psz_dir, char *psz_path )
 
191
static char **paths_to_list( const char *psz_dir, char *psz_path )
186
192
{
187
193
    unsigned int i, k, i_nb_subdirs;
188
194
    char **subdirs; /* list of subdirectories to look in */
189
 
 
190
 
    if( !psz_dir ) return NULL;
191
 
    if( !psz_path ) return NULL;
192
 
 
193
 
    i_nb_subdirs = 1;
194
 
    for( k = 0; k < strlen( psz_path ); k++ )
 
195
    char *psz_parser = psz_path;
 
196
 
 
197
    if( !psz_dir || !psz_path )
 
198
        return NULL;
 
199
 
 
200
    for( k = 0, i_nb_subdirs = 1; psz_path[k] != '\0'; k++ )
195
201
    {
196
202
        if( psz_path[k] == ',' )
197
 
        {
198
203
            i_nb_subdirs++;
199
 
        }
200
204
    }
201
205
 
202
 
    if( i_nb_subdirs > 0 )
 
206
    subdirs = calloc( i_nb_subdirs + 1, sizeof(char*) );
 
207
    if( !subdirs )
 
208
        return NULL;
 
209
 
 
210
    for( i = 0; psz_parser && *psz_parser != '\0' ; )
203
211
    {
204
 
        char *psz_parser = NULL, *psz_temp = NULL;
205
 
 
206
 
        subdirs = (char**)malloc( sizeof(char*) * ( i_nb_subdirs + 1 ) );
207
 
        memset( subdirs, 0, sizeof(char*) * ( i_nb_subdirs + 1 ) );
208
 
        i = 0;
209
 
        psz_parser = psz_path;
210
 
        while( psz_parser && *psz_parser )
 
212
        char *psz_subdir = psz_parser;
 
213
        psz_parser = strchr( psz_subdir, ',' );
 
214
        if( psz_parser )
211
215
        {
212
 
            char *psz_subdir;
213
 
            psz_subdir = psz_parser;
214
 
            psz_parser = strchr( psz_subdir, ',' );
215
 
            if( psz_parser )
216
 
            {
217
 
                *psz_parser = '\0';
 
216
            *psz_parser++ = '\0';
 
217
            while( *psz_parser == ' ' )
218
218
                psz_parser++;
219
 
                while( *psz_parser == ' ' )
220
 
                {
221
 
                    psz_parser++;
222
 
                }
223
 
            }
224
 
            if( strlen( psz_subdir ) > 0 )
225
 
            {
226
 
                psz_temp = (char *)malloc( strlen(psz_dir)
227
 
                                           + strlen(psz_subdir) + 2 );
228
 
                if( psz_temp )
229
 
                {
230
 
                    sprintf( psz_temp, "%s%s%c",
231
 
                             psz_subdir[0] == '.' ? psz_dir : "",
232
 
                             psz_subdir,
233
 
                             psz_subdir[strlen(psz_subdir) - 1] ==
234
 
                              DIRECTORY_SEPARATOR ? '\0' : DIRECTORY_SEPARATOR );
235
 
                    subdirs[i] = psz_temp;
236
 
                    i++;
237
 
                }
238
 
            }
239
219
        }
240
 
        subdirs[i] = NULL;
241
 
    }
242
 
    else
243
 
    {
244
 
        subdirs = NULL;
245
 
    }
 
220
        if( *psz_subdir == '\0' )
 
221
            continue;
 
222
 
 
223
        if( asprintf( &subdirs[i++], "%s%s%c",
 
224
                  psz_subdir[0] == '.' ? psz_dir : "",
 
225
                  psz_subdir,
 
226
                  psz_subdir[strlen(psz_subdir) - 1] == DIR_SEP_CHAR ?
 
227
                                           '\0' : DIR_SEP_CHAR ) == -1 )
 
228
            break;
 
229
    }
 
230
    subdirs[i] = NULL;
 
231
 
246
232
    return subdirs;
247
233
}
248
234
 
263
249
 * The array contains max MAX_SUBTITLE_FILES items and you need to free it after use.
264
250
 */
265
251
char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
266
 
                         char *psz_name )
 
252
                         const char *psz_name_org )
267
253
{
268
254
    vlc_value_t fuzzy;
269
 
    int j, i_result2, i_sub_count = 0, i_fname_len = 0;
 
255
    int j, i_result2, i_sub_count, i_fname_len;
270
256
    char *f_dir = NULL, *f_fname = NULL, *f_fname_noext = NULL, *f_fname_trim = NULL;
271
257
    char *tmp = NULL;
272
258
 
273
 
    char **tmp_subdirs, **subdirs; /* list of subdirectories to look in */
 
259
    char **subdirs; /* list of subdirectories to look in */
274
260
 
275
 
    subfn *result = NULL; /* unsorted results */
 
261
    vlc_subfn_t *result = NULL; /* unsorted results */
276
262
    char **result2; /* sorted results */
277
 
 
278
 
    char *psz_fname_original = strdup( psz_name );
279
 
    char *psz_fname = psz_fname_original;
280
 
 
281
 
    if( psz_fname == NULL ) return NULL;
 
263
    const char *psz_fname = psz_name_org;
 
264
 
 
265
    if( !psz_fname )
 
266
        return NULL;
282
267
 
283
268
    if( !strncmp( psz_fname, "file://", 7 ) )
284
 
    {
285
269
        psz_fname += 7;
286
 
    }
287
270
 
288
271
    /* extract filename & dirname from psz_fname */
289
 
    tmp = strrchr( psz_fname, DIRECTORY_SEPARATOR );
 
272
    tmp = strrchr( psz_fname, DIR_SEP_CHAR );
290
273
    if( tmp )
291
274
    {
292
 
        int dirlen = 0;
293
 
 
294
 
        f_fname = malloc( strlen(tmp) );
295
 
        if( f_fname )
296
 
            strcpy( f_fname, tmp+1 ); // we skip the separator, so it will still fit in the allocated space
297
 
        dirlen = strlen(psz_fname) - strlen(tmp) + 2; // add the separator
298
 
        f_dir = malloc( dirlen + 1 );
299
 
        if( f_dir != NULL )
300
 
            strlcpy( f_dir, psz_fname, dirlen );
 
275
        const int i_dirlen = strlen(psz_fname)-strlen(tmp)+1; /* include the separator */
 
276
        f_fname = strdup( &tmp[1] );    /* skip the separator */
 
277
        f_dir = strndup( psz_fname, i_dirlen );
301
278
    }
302
279
    else
303
280
    {
 
281
#ifdef HAVE_UNISTD_H
304
282
        /* Get the current working directory */
305
 
        int dirlen;
306
 
#ifdef HAVE_UNISTD_H
307
 
        f_dir = getcwd( NULL, 0 );
 
283
        char *psz_cwd = getcwd( NULL, 0 );
 
284
#else
 
285
        char *psz_cwd = NULL;
308
286
#endif
309
 
        if( f_dir == NULL )
310
 
        {
311
 
            if( psz_fname_original ) free( psz_fname_original );
 
287
        if( !psz_cwd )
312
288
            return NULL;
313
 
        }
314
 
        dirlen = strlen( f_dir );
315
 
        f_dir = (char *)realloc(f_dir, dirlen +2 );
316
 
        f_dir[dirlen] = DIRECTORY_SEPARATOR;
317
 
        f_dir[dirlen+1] = '\0';
318
 
        f_fname = FromLocaleDup( psz_fname );
 
289
 
 
290
        f_fname = strdup( psz_fname );
 
291
        if( asprintf( &f_dir, "%s%c", psz_cwd, DIR_SEP_CHAR ) == -1 )
 
292
            f_dir = NULL; /* Assure that function will return in next test */
 
293
        free( psz_cwd );
 
294
    }
 
295
    if( !f_fname || !f_dir )
 
296
    {
 
297
        free( f_fname );
 
298
        free( f_dir );
 
299
        return NULL;
319
300
    }
320
301
 
321
302
    i_fname_len = strlen( f_fname );
 
303
 
322
304
    f_fname_noext = malloc(i_fname_len + 1);
323
305
    f_fname_trim = malloc(i_fname_len + 1 );
 
306
    if( !f_fname_noext || !f_fname_trim )
 
307
    {
 
308
        free( f_fname );
 
309
        free( f_dir );
 
310
        free( f_fname_noext );
 
311
        free( f_fname_trim );
 
312
        return NULL;
 
313
    }
324
314
 
325
315
    strcpy_strip_ext( f_fname_noext, f_fname );
326
316
    strcpy_trim( f_fname_trim, f_fname_noext );
327
317
 
328
 
    result = (subfn*)malloc( sizeof(subfn) * MAX_SUBTITLE_FILES );
329
 
    if( result )
330
 
        memset( result, 0, sizeof(subfn) * MAX_SUBTITLE_FILES );
331
 
 
332
318
    var_Get( p_this, "sub-autodetect-fuzzy", &fuzzy );
333
319
 
334
 
    tmp_subdirs = paths_to_list( f_dir, psz_path );
335
 
    subdirs = tmp_subdirs;
336
 
 
337
 
    for( j = -1; (j == -1) || ( (j >= 0) && (subdirs != NULL) &&
338
 
        (*subdirs != NULL) ); j++)
 
320
    result = calloc( MAX_SUBTITLE_FILES+1, sizeof(vlc_subfn_t) ); /* We check it later (simplify code) */
 
321
    subdirs = paths_to_list( f_dir, psz_path );
 
322
    for( j = -1, i_sub_count = 0; (j == -1) || ( j >= 0 && subdirs != NULL && subdirs[j] != NULL ); j++ )
339
323
    {
340
 
        const char *psz_dir = j < 0 ? f_dir : *subdirs;
 
324
        const char *psz_dir = j < 0 ? f_dir : subdirs[j];
341
325
        char **ppsz_dir_content;
342
326
        int i_dir_content;
 
327
        int a;
343
328
 
344
 
        if( psz_dir == NULL )
 
329
        if( psz_dir == NULL || ( j >= 0 && !strcmp( psz_dir, f_dir ) ) )
345
330
            continue;
346
331
 
347
332
        /* parse psz_src dir */
348
333
        i_dir_content = utf8_scandir( psz_dir, &ppsz_dir_content,
349
334
                                      subtitles_Filter, NULL );
 
335
        if( i_dir_content < 0 )
 
336
            continue;
350
337
 
351
 
        if( i_dir_content != -1 )
 
338
        msg_Dbg( p_this, "looking for a subtitle file in %s", psz_dir );
 
339
        for( a = 0; a < i_dir_content && i_sub_count < MAX_SUBTITLE_FILES ; a++ )
352
340
        {
353
 
            int a;
354
 
 
355
 
            msg_Dbg( p_this, "looking for a subtitle file in %s", psz_dir );
356
 
            for( a = 0; a < i_dir_content; a++ )
357
 
            {
358
 
                char *psz_name = vlc_fix_readdir_charset( p_this,
359
 
                                                          ppsz_dir_content[a] );
360
 
                char tmp_fname_noext[strlen( psz_name ) + 1];
361
 
                char tmp_fname_trim[strlen( psz_name ) + 1];
362
 
                char tmp_fname_ext[strlen( psz_name ) + 1];
363
 
 
364
 
                int i_prio = 0;
365
 
 
366
 
                if( psz_name == NULL )
 
341
            char *psz_name = ppsz_dir_content[a];
 
342
            char tmp_fname_noext[strlen( psz_name ) + 1];
 
343
            char tmp_fname_trim[strlen( psz_name ) + 1];
 
344
            char tmp_fname_ext[strlen( psz_name ) + 1];
 
345
 
 
346
            int i_prio;
 
347
 
 
348
            if( psz_name == NULL )
 
349
                continue;
 
350
 
 
351
            /* retrieve various parts of the filename */
 
352
            strcpy_strip_ext( tmp_fname_noext, psz_name );
 
353
            strcpy_get_ext( tmp_fname_ext, psz_name );
 
354
            strcpy_trim( tmp_fname_trim, tmp_fname_noext );
 
355
 
 
356
            i_prio = SUB_PRIORITY_NONE;
 
357
            if( i_prio == SUB_PRIORITY_NONE && !strcmp( tmp_fname_trim, f_fname_trim ) )
 
358
            {
 
359
                /* matches the movie name exactly */
 
360
                i_prio = SUB_PRIORITY_MATCH_ALL;
 
361
            }
 
362
            if( i_prio == SUB_PRIORITY_NONE &&
 
363
                ( tmp = strstr( tmp_fname_trim, f_fname_trim ) ) )
 
364
            {
 
365
                /* contains the movie name */
 
366
                tmp += strlen( f_fname_trim );
 
367
                if( whiteonly( tmp ) )
 
368
                {
 
369
                    /* chars in front of the movie name */
 
370
                    i_prio = SUB_PRIORITY_MATCH_RIGHT;
 
371
                }
 
372
                else
 
373
                {
 
374
                    /* chars after (and possibly in front of)
 
375
                     * the movie name */
 
376
                    i_prio = SUB_PRIORITY_MATCH_LEFT;
 
377
                }
 
378
            }
 
379
            if( i_prio == SUB_PRIORITY_NONE &&
 
380
                j == 0 )
 
381
            {
 
382
                /* doesn't contain the movie name, prefer files in f_dir over subdirs */
 
383
                i_prio = SUB_PRIORITY_MATCH_NONE;
 
384
            }
 
385
            if( i_prio >= fuzzy.i_int )
 
386
            {
 
387
                char psz_path[strlen( psz_dir ) + strlen( psz_name ) + 1];
 
388
                struct stat st;
 
389
 
 
390
                sprintf( psz_path, "%s%s", psz_dir, psz_name );
 
391
                if( !strcmp( psz_path, psz_fname ) )
367
392
                    continue;
368
393
 
369
 
                /* retrieve various parts of the filename */
370
 
                strcpy_strip_ext( tmp_fname_noext, psz_name );
371
 
                strcpy_get_ext( tmp_fname_ext, psz_name );
372
 
                strcpy_trim( tmp_fname_trim, tmp_fname_noext );
373
 
 
374
 
                if( !i_prio && !strcmp( tmp_fname_trim, f_fname_trim ) )
375
 
                {
376
 
                    /* matches the movie name exactly */
377
 
                    i_prio = 4;
378
 
                }
379
 
                if( !i_prio &&
380
 
                    ( tmp = strstr( tmp_fname_trim, f_fname_trim ) ) )
381
 
                {
382
 
                    /* contains the movie name */
383
 
                    tmp += strlen( f_fname_trim );
384
 
                    if( whiteonly( tmp ) )
385
 
                    {
386
 
                        /* chars in front of the movie name */
387
 
                        i_prio = 2;
388
 
                    }
389
 
                    else
390
 
                    {
391
 
                        /* chars after (and possibly in front of)
392
 
                         * the movie name */
393
 
                        i_prio = 3;
394
 
                    }
395
 
                }
396
 
                if( !i_prio )
397
 
                {
398
 
                    /* doesn't contain the movie name */
399
 
                    if( j == 0 ) i_prio = 1;
400
 
                }
401
 
                if( i_prio >= fuzzy.i_int )
402
 
                {
403
 
                    FILE *f;
404
 
                    char psz_path[strlen( psz_dir ) + strlen( psz_name ) + 1];
405
 
 
406
 
                    sprintf( psz_path, "%s%s", psz_dir, psz_name );
 
394
                if( !utf8_stat( psz_path, &st ) && S_ISREG( st.st_mode ) && result )
 
395
                {
407
396
                    msg_Dbg( p_this,
408
 
                                "autodetected subtitle: %s with priority %d",
409
 
                                psz_path, i_prio );
410
 
                    /* FIXME: a portable wrapper for stat() or access() would be more suited */
411
 
                    if( ( f = utf8_fopen( psz_path, "rt" ) ) )
412
 
                    {
413
 
                        fclose( f );
414
 
                        msg_Dbg( p_this,
415
 
                                "autodetected subtitle: %s with priority %d",
416
 
                                psz_path, i_prio );
417
 
                        result[i_sub_count].priority = i_prio;
418
 
                        result[i_sub_count].psz_fname = strdup( psz_path );
419
 
                        result[i_sub_count].psz_ext = strdup(tmp_fname_ext);
420
 
                        i_sub_count++;
421
 
                    }
422
 
                    else
423
 
                    {
424
 
                        msg_Dbg( p_this, "fopen failed" );
425
 
                    }
426
 
                }
427
 
                if( i_sub_count >= MAX_SUBTITLE_FILES ) break;
428
 
                free( psz_name );
 
397
                            "autodetected subtitle: %s with priority %d",
 
398
                            psz_path, i_prio );
 
399
                    result[i_sub_count].priority = i_prio;
 
400
                    result[i_sub_count].psz_fname = strdup( psz_path );
 
401
                    result[i_sub_count].psz_ext = strdup(tmp_fname_ext);
 
402
                    i_sub_count++;
 
403
                }
 
404
                else
 
405
                {
 
406
                    msg_Dbg( p_this, "stat failed (autodetecting subtitle: %s with priority %d)",
 
407
                             psz_path, i_prio );
 
408
                }
429
409
            }
 
410
        }
 
411
        if( ppsz_dir_content )
 
412
        {
430
413
            for( a = 0; a < i_dir_content; a++ )
431
414
                free( ppsz_dir_content[a] );
432
 
            if( ppsz_dir_content ) free( ppsz_dir_content );
 
415
            free( ppsz_dir_content );
433
416
        }
434
 
        if( j >= 0 ) if( *subdirs ) free( *subdirs++ );
435
 
    }
436
 
 
437
 
    if( tmp_subdirs )   free( tmp_subdirs );
438
 
    if( f_fname_trim )  free( f_fname_trim );
439
 
    if( f_fname_noext ) free( f_fname_noext );
440
 
    if( f_fname ) free( f_fname );
441
 
    if( f_dir )   free( f_dir );
442
 
 
443
 
    qsort( result, i_sub_count, sizeof( subfn ), compare_sub_priority );
444
 
 
445
 
    result2 = (char**)malloc( sizeof(char*) * ( i_sub_count + 1 ) );
446
 
    if( result2 )
447
 
        memset( result2, 0, sizeof(char*) * ( i_sub_count + 1 ) );
448
 
    i_result2 = 0;
449
 
 
450
 
    for( j = 0; j < i_sub_count; j++ )
451
 
    {
452
 
        if( result[j].psz_ext && !strcasecmp( result[j].psz_ext, "sub" ) )
 
417
    }
 
418
    if( subdirs )
 
419
    {
 
420
        for( j = 0; subdirs[j]; j++ )
 
421
            free( subdirs[j] );
 
422
        free( subdirs );
 
423
    }
 
424
    free( f_fname );
 
425
    free( f_dir );
 
426
    free( f_fname_trim );
 
427
    free( f_fname_noext );
 
428
 
 
429
    if( !result )
 
430
        return NULL;
 
431
 
 
432
    qsort( result, i_sub_count, sizeof(vlc_subfn_t), compare_sub_priority );
 
433
 
 
434
    result2 = calloc( i_sub_count + 1, sizeof(char*) );
 
435
 
 
436
    for( j = 0, i_result2 = 0; j < i_sub_count && result2 != NULL; j++ )
 
437
    {
 
438
        bool b_reject = false;
 
439
 
 
440
        if( !result[j].psz_fname || !result[j].psz_ext ) /* memory out */
 
441
            break;
 
442
 
 
443
        if( !strcasecmp( result[j].psz_ext, "sub" ) )
453
444
        {
454
445
            int i;
455
446
            for( i = 0; i < i_sub_count; i++ )
456
447
            {
457
 
                if( result[i].psz_fname && result[j].psz_fname &&
 
448
                if( result[i].psz_fname && result[i].psz_ext &&
458
449
                    !strncasecmp( result[j].psz_fname, result[i].psz_fname,
459
 
                                sizeof( result[j].psz_fname) - 4 ) &&
 
450
                                  strlen( result[j].psz_fname) - 3 ) &&
460
451
                    !strcasecmp( result[i].psz_ext, "idx" ) )
461
452
                    break;
462
453
            }
463
 
            if( i >= i_sub_count )
464
 
            {
465
 
                result2[i_result2] = result[j].psz_fname;
466
 
                i_result2++;
467
 
            }
 
454
            if( i < i_sub_count )
 
455
                b_reject = true;
468
456
        }
469
 
        else
 
457
        else if( !strcasecmp( result[j].psz_ext, "cdg" ) )
470
458
        {
471
 
            result2[i_result2] = result[j].psz_fname;
472
 
            i_result2++;
 
459
            if( result[j].priority < SUB_PRIORITY_MATCH_ALL )
 
460
                b_reject = true;
473
461
        }
474
 
    }
475
 
 
476
 
    if( psz_fname_original ) free( psz_fname_original );
477
 
    if( result ) free( result );
 
462
 
 
463
        /* */
 
464
        if( !b_reject )
 
465
            result2[i_result2++] = strdup( result[j].psz_fname );
 
466
    }
 
467
 
 
468
    for( j = 0; j < i_sub_count; j++ )
 
469
    {
 
470
        free( result[j].psz_fname );
 
471
        free( result[j].psz_ext );
 
472
    }
 
473
    free( result );
 
474
 
478
475
    return result2;
479
476
}
 
477