]> git.sesse.net Git - vlc/blobdiff - src/input/input.c
decoders: use vlc_custom_create, generic objects (except in input)
[vlc] / src / input / input.c
index 3a3cf3c1efdafcdd56a5beb4876730db7d70e220..73b6e83aab65833668e1467dc58411f9027597f5 100644 (file)
@@ -30,9 +30,7 @@
 #endif
 
 #include <vlc_common.h>
-#include <vlc_memory.h>
 
-#include <ctype.h>
 #include <limits.h>
 #include <assert.h>
 #include <errno.h>
@@ -314,6 +312,8 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     if( p_input == NULL )
         return NULL;
 
+    vlc_object_attach( p_input, p_parent );
+
     /* Construct a nice name for the input timer */
     char psz_timer_name[255];
     char * psz_name = input_item_GetName( p_item );
@@ -480,9 +480,6 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     /* Set the destructor when we are sure we are initialized */
     vlc_object_set_destructor( p_input, (vlc_destructor_t)Destructor );
 
-    /* Attach only once we are ready */
-    vlc_object_attach( p_input, p_parent );
-
     return p_input;
 }
 
@@ -751,7 +748,9 @@ static void MainLoop( input_thread_t *p_input, bool b_interactive )
                 msg_Dbg( p_input, "waiting decoder fifos to empty" );
                 i_wakeup = mdate() + INPUT_IDLE_SLEEP;
             }
-            else if( b_pause_after_eof )
+            /* Pause after eof only if the input is pausable.
+             * This way we won't trigger timeshifting for nothing */
+            else if( b_pause_after_eof && p_input->p->b_can_pause )
             {
                 msg_Dbg( p_input, "pausing at EOF (pause after each)");
                 val.i_int = PAUSE_S;
@@ -1003,11 +1002,14 @@ static void LoadSubtitles( input_thread_t *p_input )
         var_SetTime( p_input, "spu-delay", (mtime_t)i_delay * 100000 );
 
     /* Look for and add subtitle files */
+    bool b_forced = true;
+
     char *psz_subtitle = var_GetNonEmptyString( p_input, "sub-file" );
     if( psz_subtitle != NULL )
     {
         msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle );
-        SubtitleAdd( p_input, psz_subtitle, true );
+        SubtitleAdd( p_input, psz_subtitle, b_forced );
+        b_forced = false;
     }
 
     if( var_GetBool( p_input, "sub-autodetect-file" ) )
@@ -1019,18 +1021,56 @@ static void LoadSubtitles( input_thread_t *p_input )
 
         for( int i = 0; ppsz_subs && ppsz_subs[i]; i++ )
         {
-            /* Try to autoselect the first autodetected subtitles file
-             * if no subtitles file was specified */
-            bool b_forced = i == 0 && !psz_subtitle;
-
             if( !psz_subtitle || strcmp( psz_subtitle, ppsz_subs[i] ) )
+            {
                 SubtitleAdd( p_input, ppsz_subs[i], b_forced );
+                b_forced = false;
+            }
 
             free( ppsz_subs[i] );
         }
         free( ppsz_subs );
     }
     free( psz_subtitle );
+
+    /* Load subtitles from attachments */
+    int i_attachment = 0;
+    input_attachment_t **pp_attachment = NULL;
+
+    vlc_mutex_lock( &p_input->p->p_item->lock );
+    for( int i = 0; i < p_input->p->i_attachment; i++ )
+    {
+        const input_attachment_t *a = p_input->p->attachment[i];
+        if( !strcmp( a->psz_mime, "application/x-srt" ) )
+            TAB_APPEND( i_attachment, pp_attachment,
+                        vlc_input_attachment_New( a->psz_name, NULL,
+                                                  a->psz_description, NULL, 0 ) );
+    }
+    vlc_mutex_unlock( &p_input->p->p_item->lock );
+
+    if( i_attachment > 0 )
+        var_Create( p_input, "sub-description", VLC_VAR_STRING );
+    for( int i = 0; i < i_attachment; i++ )
+    {
+        input_attachment_t *a = pp_attachment[i];
+        if( !a )
+            continue;
+        char *psz_mrl;
+        if( a->psz_name[i] &&
+            asprintf( &psz_mrl, "attachment://%s", a->psz_name ) >= 0 )
+        {
+            var_SetString( p_input, "sub-description", a->psz_description ? a->psz_description : "");
+
+            SubtitleAdd( p_input, psz_mrl, b_forced );
+
+            b_forced = false;
+            free( psz_mrl );
+        }
+        vlc_input_attachment_Delete( a );
+    }
+    free( pp_attachment );
+    if( i_attachment > 0 )
+        var_Destroy( p_input, "sub-description" );
 }
 
 static void LoadSlaves( input_thread_t *p_input )
@@ -2157,7 +2197,7 @@ static bool Control( input_thread_t *p_input,
             else if( bookmark.i_byte_offset >= 0 &&
                      p_input->p->input.p_stream )
             {
-                const int64_t i_size = stream_Size( p_input->p->input.p_stream );
+                const uint64_t i_size = stream_Size( p_input->p->input.p_stream );
                 if( i_size > 0 && bookmark.i_byte_offset <= i_size )
                 {
                     val.f_float = (double)bookmark.i_byte_offset / i_size;
@@ -2347,7 +2387,7 @@ static int InputSourceInit( input_thread_t *p_input,
     input_SplitMRL( &psz_access, &psz_demux, &psz_path, psz_dup );
 
     /* FIXME: file:// handling plugins do not support URIs properly...
-     * So we pre-decoded the URI to a path for them. Note that we do not do it
+     * So we pre-decode the URI to a path for them. Note that we do not do it
      * for non-standard VLC-specific schemes. */
     if( !strcmp( psz_access, "file" ) )
     {
@@ -2746,18 +2786,21 @@ static void InputSourceMeta( input_thread_t *p_input,
     /* XXX Remember that checking against p_item->p_meta->i_status & ITEM_PREPARSED
      * is a bad idea */
 
+    bool has_meta;
+
     /* Read access meta */
-    if( p_access )
-        access_Control( p_access, ACCESS_GET_META, p_meta );
+    has_meta = p_access && !access_Control( p_access, ACCESS_GET_META, p_meta );
 
     /* Read demux meta */
-    demux_Control( p_demux, DEMUX_GET_META, p_meta );
+    has_meta |= !demux_Control( p_demux, DEMUX_GET_META, p_meta );
 
-    /* If the demux report unsupported meta data, try an external "meta reader" */
-    bool b_bool;
-    if( demux_Control( p_demux, DEMUX_HAS_UNSUPPORTED_META, &b_bool ) )
-        return;
-    if( !b_bool )
+    bool has_unsupported;
+    if( demux_Control( p_demux, DEMUX_HAS_UNSUPPORTED_META, &has_unsupported ) )
+        has_unsupported = true;
+
+    /* If the demux report unsupported meta data, or if we don't have meta data
+     * try an external "meta reader" */
+    if( has_meta && !has_unsupported )
         return;
 
     demux_meta_t *p_demux_meta =
@@ -2766,6 +2809,7 @@ static void InputSourceMeta( input_thread_t *p_input,
     if( !p_demux_meta )
         return;
     p_demux_meta->p_demux = p_demux;
+    p_demux_meta->p_item = p_input->p->p_item;
 
     module_t *p_id3 = module_need( p_demux_meta, "meta reader", NULL, false );
     if( p_id3 )
@@ -2926,9 +2970,8 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta
     input_attachment_t **attachment = *ppp_attachment;
     int i;
 
-    attachment = realloc_or_free( attachment,
+    attachment = xrealloc( attachment,
                     sizeof(input_attachment_t**) * ( i_attachment + i_new ) );
-    assert( attachment );
     for( i = 0; i < i_new; i++ )
         attachment[i_attachment++] = pp_new[i];
     free( pp_new );
@@ -3084,8 +3127,8 @@ void input_SplitMRL( const char **ppsz_access, const char **ppsz_demux, char **p
     {
         psz_path = psz_dup;
     }
-    *ppsz_access = psz_access ? psz_access : (char*)"";
-    *ppsz_demux = psz_demux ? psz_demux : (char*)"";
+    *ppsz_access = psz_access ? psz_access : "";
+    *ppsz_demux = psz_demux ? psz_demux : "";
     *ppsz_path = psz_path;
 }