Пример #1
0
static void vlc_vidsplit_Close(vout_display_t *vd)
{
    vout_display_sys_t *sys = vd->sys;
    int n = sys->splitter.i_output;

    for (int i = 0; i < n; i++) {
        struct vlc_vidsplit_part *part = &sys->parts[i];
        vout_display_t *display;

        vlc_sem_wait(&part->lock);
        display = part->display;
        part->display = NULL;
        vlc_sem_post(&part->lock);

        if (display != NULL)
            vout_display_Delete(display);

        vout_window_Disable(part->window);
        vout_window_Delete(part->window);
        vlc_sem_destroy(&part->lock);
    }

    module_unneed(&sys->splitter, sys->splitter.p_module);
    video_format_Clean(&sys->splitter.fmt);
    vlc_mutex_destroy(&sys->lock);
    vlc_object_release(&sys->splitter);
}
Пример #2
0
void playlist_preparser_Delete( playlist_preparser_t *p_preparser )
{
    vlc_mutex_lock( &p_preparser->lock );
    /* Remove pending item to speed up preparser thread exit */
    while( p_preparser->i_waiting > 0 )
    {
        preparser_entry_t *p_entry = p_preparser->pp_waiting[0];
        vlc_gc_decref( p_entry->p_item );
        free( p_entry );
        REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 );
    }

    vlc_sem_post( &p_preparser->item_done );

    while( p_preparser->b_live )
        vlc_cond_wait( &p_preparser->wait, &p_preparser->lock );
    vlc_mutex_unlock( &p_preparser->lock );

    /* Destroy the item preparser */
    vlc_sem_destroy( &p_preparser->item_done );
    vlc_cond_destroy( &p_preparser->wait );
    vlc_mutex_destroy( &p_preparser->lock );

    if( p_preparser->p_fetcher != NULL )
        playlist_fetcher_Delete( p_preparser->p_fetcher );
    free( p_preparser );
}
Пример #3
0
/* Open Interface */
static int Open( vlc_object_t *p_this, bool isDialogProvider )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;

#ifdef Q_WS_X11
    if( !vlc_xlib_init( p_this ) )
        return VLC_EGENERIC;

    char *display = var_CreateGetNonEmptyString( p_intf, "x11-display" );
    Display *p_display = XOpenDisplay( x11_display );
    if( !p_display )
    {
        msg_Err( p_intf, "Could not connect to X server" );
        free (display);
        return VLC_EGENERIC;
    }
    XCloseDisplay( p_display );
#else
    char *display = NULL;
#endif

    QMutexLocker locker (&lock);
    if (busy)
    {
        msg_Err (p_this, "cannot start Qt4 multiple times");
        free (display);
        return VLC_EGENERIC;
    }

    /* Allocations of p_sys */
    intf_sys_t *p_sys = p_intf->p_sys = new intf_sys_t;
    p_intf->p_sys->b_isDialogProvider = isDialogProvider;
    p_sys->p_mi = NULL;
    p_sys->p_playlist = pl_Get( p_intf );

    /* */
#ifdef Q_WS_X11
    x11_display = display;
#endif
    vlc_sem_init (&ready, 0);
    if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )
    {
        delete p_sys;
        free (display);
        return VLC_ENOMEM;
    }

    /* */
    vlc_sem_wait (&ready);
    vlc_sem_destroy (&ready);
    busy = active = true;

    if( !p_sys->b_isDialogProvider )
    {
        playlist_t *pl = pl_Get(p_this);
        var_Create (pl, "qt4-iface", VLC_VAR_ADDRESS);
        var_SetAddress (pl, "qt4-iface", p_this);
    }
    return VLC_SUCCESS;
}
Пример #4
0
/**
 * Close the module
 * @param p_this: the filter object
 */
static void Close( vlc_object_t *p_this )
{
    filter_t     *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = p_filter->p_sys;

    /* Stop the thread
     * XXX vlc_cleanup_push does not seems to work with C++ so no
     * vlc_cancel()... */
    vlc_mutex_lock( &p_sys->lock );
    p_sys->b_quit = true;
    vlc_mutex_unlock( &p_sys->lock );

    vlc_join( p_sys->thread, NULL );

    /* Free the ressources */
    vlc_sem_destroy( &p_sys->ready );
    vlc_mutex_destroy( &p_sys->lock );
    free( p_sys->p_buffer );
#ifndef HAVE_PROJECTM2
    free( p_sys->psz_config );
#else
    free( p_sys->psz_preset_path );
    free( p_sys->psz_title_font );
    free( p_sys->psz_menu_font );
#endif
    free( p_sys );
}
Пример #5
0
/*****************************************************************************
 * Close: close the ALSA device
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys = p_aout->output.p_sys;
    int i_snd_rc;

    /* Make sure that the thread will stop once it is waken up */
    vlc_cancel( p_sys->thread );
    vlc_join( p_sys->thread, NULL );
    vlc_sem_destroy( &p_sys->wait );

    /* */
    i_snd_rc = snd_pcm_close( p_sys->p_snd_pcm );

    if( i_snd_rc > 0 )
    {
        msg_Err( p_aout, "failed closing ALSA device (%s)",
                         snd_strerror( i_snd_rc ) );
    }

#ifdef ALSA_DEBUG
    snd_output_close( p_sys->p_snd_stderr );
#endif

    free( p_sys );
}
Пример #6
0
void vlc_join (vlc_thread_t handle, void **result)
{
    vlc_sem_wait (&handle->finished);
    vlc_sem_destroy (&handle->finished);

    int val = pthread_join (handle->thread, result);
    VLC_THREAD_ASSERT ("joining thread");
    clean_detached_thread(handle);
}
Пример #7
0
void vlc_join (vlc_thread_t handle, void **result)
{
    vlc_sem_wait (&handle->finished);
    vlc_sem_destroy (&handle->finished);

    int val = pthread_join (handle->thread, result);
    VLC_THREAD_ASSERT ("joining thread");
    vlc_mutex_destroy(&handle->lock);
    free(handle);
}
Пример #8
0
void libvlc_wait( libvlc_instance_t *p_i )
{
    vlc_sem_t sem;

    vlc_sem_init( &sem, 0 );
    libvlc_set_exit_handler( p_i, libvlc_wait_wakeup, &sem );
    vlc_sem_wait( &sem );
    libvlc_set_exit_handler( p_i, NULL, NULL );
    vlc_sem_destroy( &sem );
}
Пример #9
0
Файл: codec.c Проект: Adatan/vlc
static void CloseDecoder(decoder_t *dec)
{
    decoder_sys_t *sys = dec->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;

    if (!sys)
        return;

    if (sys->component && sys->component->control->is_enabled)
        mmal_port_disable(sys->component->control);

    if (sys->input && sys->input->is_enabled)
        mmal_port_disable(sys->input);

    if (sys->output && sys->output->is_enabled)
        mmal_port_disable(sys->output);

    if (sys->component && sys->component->is_enabled)
        mmal_component_disable(sys->component);

    if (sys->input_pool)
        mmal_pool_destroy(sys->input_pool);

    if (sys->output_format)
        mmal_format_free(sys->output_format);

    /* Free pictures which are decoded but have not yet been sent
     * out to the core */
    while ((buffer = mmal_queue_get(sys->decoded_pictures))) {
        picture_t *pic = (picture_t *)buffer->user_data;
        picture_Release(pic);

        if (sys->output_pool) {
            buffer->user_data = NULL;
            buffer->alloc_size = 0;
            buffer->data = NULL;
            mmal_buffer_header_release(buffer);
        }
    }

    if (sys->decoded_pictures)
        mmal_queue_destroy(sys->decoded_pictures);

    if (sys->output_pool)
        mmal_pool_destroy(sys->output_pool);

    if (sys->component)
        mmal_component_release(sys->component);

    vlc_mutex_destroy(&sys->mutex);
    vlc_sem_destroy(&sys->sem);
    free(sys);

    bcm_host_deinit();
}
Пример #10
0
/**
 * Open the module
 * @param p_this: the filter object
 * @return VLC_SUCCESS or vlc error codes
 */
static int Open( vlc_object_t * p_this )
{
    filter_t     *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys;

    /* Test the audio format */
    if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 ||
        p_filter->fmt_out.audio.i_format != VLC_CODEC_FL32 )
    {
        msg_Warn( p_filter, "bad input or output format" );
        return VLC_EGENERIC;
    }
    if( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, &p_filter->fmt_out.audio ) )
    {
        msg_Warn( p_filter, "input and outut are not similar" );
        return VLC_EGENERIC;
    }

    p_filter->pf_audio_filter = DoWork;

    p_sys = p_filter->p_sys = (filter_sys_t*)malloc( sizeof( *p_sys ) );
    if( !p_sys )
        return VLC_ENOMEM;

    /* Create the object for the thread */
    vlc_sem_init( &p_sys->ready, 0 );
    p_sys->b_error       = false;
    p_sys->b_quit        = false;
    p_sys->i_width       = var_InheritInteger( p_filter, "projectm-width" );
    p_sys->i_height      = var_InheritInteger( p_filter, "projectm-height" );
    p_sys->i_channels    = aout_FormatNbChannels( &p_filter->fmt_in.audio );
    vlc_mutex_init( &p_sys->lock );
    p_sys->p_buffer      = NULL;
    p_sys->i_buffer_size = 0;
    p_sys->i_nb_samples  = 0;

    /* Create the thread */
    if( vlc_clone( &p_sys->thread, Thread, p_filter, VLC_THREAD_PRIORITY_LOW ) )
        goto error;

    vlc_sem_wait( &p_sys->ready );
    if( p_sys->b_error )
    {
        vlc_join( p_sys->thread, NULL );
        goto error;
    }

    return VLC_SUCCESS;

error:
    vlc_sem_destroy( &p_sys->ready );
    free (p_sys );
    return VLC_EGENERIC;
}
Пример #11
0
/**
 * Open the module.
 * @param p_this: the filter object
 * @return VLC_SUCCESS or vlc error codes
 */
static int Open(vlc_object_t * p_this)
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys;

    p_sys = p_filter->p_sys = (filter_sys_t*)malloc(sizeof(*p_sys));
    if (p_sys == NULL)
        return VLC_ENOMEM;

    /* Create the object for the thread */
    vlc_sem_init(&p_sys->ready, 0);
    p_sys->b_error = false;
    p_sys->i_width = var_InheritInteger(p_filter, "glspectrum-width");
    p_sys->i_height = var_InheritInteger(p_filter, "glspectrum-height");
    p_sys->i_channels = aout_FormatNbChannels(&p_filter->fmt_in.audio);
    p_sys->i_prev_nb_samples = 0;
    p_sys->p_prev_s16_buff = NULL;

    p_sys->f_rotationAngle = 0;
    p_sys->f_rotationIncrement = ROTATION_INCREMENT;

    /* Fetch the FFT window parameters */
    window_get_param( VLC_OBJECT( p_filter ), &p_sys->wind_param );

    /* Create the FIFO for the audio data. */
    p_sys->fifo = block_FifoNew();
    if (p_sys->fifo == NULL)
        goto error;

    /* Create the thread */
    if (vlc_clone(&p_sys->thread, Thread, p_filter,
                  VLC_THREAD_PRIORITY_VIDEO))
        goto error;

    /* Wait for the displaying thread to be ready. */
    vlc_sem_wait(&p_sys->ready);
    if (p_sys->b_error)
    {
        vlc_join(p_sys->thread, NULL);
        goto error;
    }

    p_filter->fmt_in.audio.i_format = VLC_CODEC_FL32;
    p_filter->fmt_out.audio = p_filter->fmt_in.audio;
    p_filter->pf_audio_filter = DoWork;

    return VLC_SUCCESS;

error:
    vlc_sem_destroy(&p_sys->ready);
    free(p_sys);
    return VLC_EGENERIC;
}
Пример #12
0
/**
 * Open the module
 * @param p_this: the filter object
 * @return VLC_SUCCESS or vlc error codes
 */
static int Open( vlc_object_t * p_this )
{
    filter_t     *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys;

    /* Test the audio format */
    if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 )
    {
        msg_Warn( p_filter, "bad input format" );
        return VLC_EGENERIC;
    }

    p_sys = p_filter->p_sys = (filter_sys_t*)malloc( sizeof( *p_sys ) );
    if( unlikely( !p_sys ) )
    {
        return VLC_ENOMEM;
    }

    /* Create the object for the thread */
    vlc_sem_init( &p_sys->ready, 0 );
    p_sys->b_error       = false;
    p_sys->b_quit        = false;
    p_sys->i_width       = var_InheritInteger( p_filter, "vsxu-width" );
    p_sys->i_height      = var_InheritInteger( p_filter, "vsxu-height" );
    p_sys->i_channels    = aout_FormatNbChannels( &p_filter->fmt_in.audio );
    vlc_mutex_init( &p_sys->lock );
    vlc_mutex_init( &p_sys->cyclic_block_mutex );
    p_sys->vsxu_cyclic_buffer = new cyclic_block_queue();


    /* Create the thread */
    if( vlc_clone( &p_sys->thread, Thread, p_filter, VLC_THREAD_PRIORITY_LOW ) )
        goto error;


    vlc_sem_wait( &p_sys->ready );
    if( p_sys->b_error )
    {
        vlc_join( p_sys->thread, NULL );
        goto error;
    }

    p_filter->fmt_out.audio = p_filter->fmt_in.audio;
    p_filter->pf_audio_filter = DoWork;

    return VLC_SUCCESS;

error:
    vlc_sem_destroy( &p_sys->ready );
    free (p_sys );
    return VLC_EGENERIC;
}
Пример #13
0
/**
 * Close the module
 * @param p_this: the filter object
 */
static void Close( vlc_object_t *p_this )
{
    filter_t  *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = p_filter->p_sys;

    vlc_mutex_lock( &p_sys->lock );
    p_sys->b_quit = true;
    vlc_mutex_unlock( &p_sys->lock );

    vlc_join( p_sys->thread, NULL );

    /* Free the ressources */
    vlc_sem_destroy( &p_sys->ready );
    vlc_mutex_destroy( &p_sys->lock );
    delete p_sys->vsxu_cyclic_buffer;
    free( p_sys );
}
Пример #14
0
static void
media_parse_sync(libvlc_media_t *p_m)
{
    vlc_sem_t sem;
    vlc_sem_init(&sem, 0);

    libvlc_event_manager_t *p_em = libvlc_media_event_manager(p_m);
    libvlc_event_attach(p_em, libvlc_MediaParsedChanged, finished_event, &sem);

    int i_ret = libvlc_media_parse_with_options(p_m, libvlc_media_parse_local);
    assert(i_ret == 0);

    vlc_sem_wait (&sem);

    libvlc_event_detach(p_em, libvlc_MediaParsedChanged, finished_event, &sem);

    vlc_sem_destroy (&sem);
}
Пример #15
0
/**
 * Close the module.
 * @param p_this: the filter object
 */
static void Close(vlc_object_t *p_this)
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = p_filter->p_sys;

    /* Terminate the thread. */
    vlc_cancel(p_sys->thread);
    vlc_join(p_sys->thread, NULL);

    /* Free the ressources */
    vout_DeleteDisplay(p_sys->p_vd, NULL);
    vlc_object_release(p_sys->p_vout);

    block_FifoRelease(p_sys->fifo);
    free(p_sys->p_prev_s16_buff);

    vlc_sem_destroy(&p_sys->ready);
    free(p_sys);
}
Пример #16
0
/*****************************************************************************
 * Module callbacks
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    intf_sys_t *p_sys;
    vlc_value_t val;

    if( !vlc_xlib_init( p_this ) )
        return VLC_EGENERIC;

    /* Allocate instance and initialize some members */
    p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) );
    if( p_intf->p_sys == NULL )
        return VLC_ENOMEM;

    p_sys->p_playlist = pl_Get( p_intf );
    p_sys->p_input = NULL;

    p_sys->p_main_window = NULL;
    p_sys->p_video_window = NULL;
    p_sys->p_control_window = NULL;
    p_sys->b_fullscreen = false;
    p_sys->i_event = 0;

    vlc_spin_init( &p_sys->event_lock );

    /* Create separate thread for main interface */
    vlc_sem_init (&p_sys->ready, 0);
    if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )
    {
        free (p_sys);
        return VLC_ENOMEM;
    }

    /* Wait for interface thread to be fully initialised */
    vlc_sem_wait (&p_sys->ready);
    vlc_sem_destroy (&p_sys->ready);

    var_Create (p_this->p_libvlc, "hildon-iface", VLC_VAR_ADDRESS);
    val.p_address = p_this;
    var_Set (p_this->p_libvlc, "hildon-iface", val);

    return VLC_SUCCESS;
}
Пример #17
0
Файл: video.c Проект: bobwxb/vlc
/*****************************************************************************
 * EndVideo: decoder destruction
 *****************************************************************************
 * This function is called when the thread ends after a successful
 * initialization.
 *****************************************************************************/
void EndVideoDec( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    post_mt( p_sys );

    /* do not flush buffers if codec hasn't been opened (theora/vorbis/VC1) */
    if( p_sys->p_context->codec )
        avcodec_flush_buffers( p_sys->p_context );

    wait_mt( p_sys );

    ffmpeg_CloseCodec( p_dec );

    if( p_sys->p_va )
        vlc_va_Delete( p_sys->p_va, p_sys->p_context );

    vlc_sem_destroy( &p_sys->sem_mt );
}
Пример #18
0
/**
 * Close the module
 * @param p_this: the filter object
 */
static void Close( vlc_object_t *p_this )
{
    filter_t  *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = p_filter->p_sys;

    /* Stop the thread
     * XXX vlc_cleanup_push does not seems to work with C++ so no
     * vlc_cancel()... */
    vlc_mutex_lock( &p_sys->lock );
    p_sys->b_quit = true;
    vlc_mutex_unlock( &p_sys->lock );

    vlc_join( p_sys->thread, NULL );

    /* Free the ressources */
    vlc_sem_destroy( &p_sys->ready );
    vlc_mutex_destroy( &p_sys->lock );
    free( p_sys->p_buffer );
    free( p_sys );
}
Пример #19
0
static void test_media_subitems_media(libvlc_media_t *media, bool play)
{
    libvlc_media_add_option(media, ":ignore-filetypes= ");

    bool subitems_found[TEST_SUBITEMS_COUNT] = { 0 };
    vlc_sem_t sem;
    vlc_sem_init (&sem, 0);

    libvlc_event_manager_t *em = libvlc_media_event_manager (media);
    libvlc_event_attach (em, libvlc_MediaSubItemTreeAdded, subitem_tree_added, &sem);
    libvlc_event_attach (em, libvlc_MediaSubItemAdded, subitem_added, subitems_found);

    if (play)
    {
        /* XXX: libvlc_media_parse_async won't work with fd, since it won't be
         * preparsed because fd:// is an unknown type, so play the file to
         * force parsing. */
        libvlc_media_player_t *mp = libvlc_media_player_new_from_media (media);
        assert (mp);
        assert (libvlc_media_player_play (mp) != -1);
        vlc_sem_wait (&sem);
        libvlc_media_player_release (mp);
    }
    else
    {
        libvlc_media_parse_async (media);
        vlc_sem_wait (&sem);
    }

    vlc_sem_destroy (&sem);

    for (unsigned i = 0; i < TEST_SUBITEMS_COUNT; ++i)
    {
        log ("test if %s was added\n", test_media_subitems_list[i].file);
        assert (subitems_found[i]);
    }
}
Пример #20
0
static void test_media_preparsed(const char** argv, int argc)
{
    // We use this image file because "empty.voc" has no track.
    const char * file = SRCDIR"/samples/image.jpg";

    log ("Testing set_media\n");

    libvlc_instance_t *vlc = libvlc_new (argc, argv);
    assert (vlc != NULL);

    libvlc_media_t *media = libvlc_media_new_path (vlc, file);
    assert (media != NULL);

    vlc_sem_t sem;
    vlc_sem_init (&sem, 0);

    // Check to see if we are properly receiving the event.
    libvlc_event_manager_t *em = libvlc_media_event_manager (media);
    libvlc_event_attach (em, libvlc_MediaParsedChanged, preparsed_changed, &sem);

    // Parse the media. This is synchronous.
    libvlc_media_parse_async(media);

    // Wait for preparsed event
    vlc_sem_wait (&sem);
    vlc_sem_destroy (&sem);

    // We are good, now check Elementary Stream info.
    libvlc_media_track_t **tracks;
    unsigned nb_tracks = libvlc_media_tracks_get (media, &tracks);
    assert (nb_tracks == 1);
    assert (tracks[0]->i_type == libvlc_track_video);
    libvlc_media_tracks_release (tracks, nb_tracks);

    libvlc_media_release (media);
    libvlc_release (vlc);
}
Пример #21
0
static void
mediaplayer_play_sync(libvlc_media_player_t *p_mp)
{
    vlc_sem_t sem;
    vlc_sem_init(&sem, 0);

    libvlc_event_manager_t *p_em = libvlc_media_player_event_manager(p_mp);
    libvlc_event_attach(p_em, libvlc_MediaPlayerPlaying, finished_event, &sem);
    libvlc_event_attach(p_em, libvlc_MediaPlayerEndReached, finished_event, &sem);
    libvlc_event_attach(p_em, libvlc_MediaPlayerEncounteredError, finished_event, &sem);

    int i_ret = libvlc_media_player_play(p_mp);
    assert(i_ret == 0);

    vlc_sem_wait (&sem);

    libvlc_event_detach(p_em, libvlc_MediaPlayerPlaying, finished_event, &sem);
    libvlc_event_detach(p_em, libvlc_MediaPlayerEndReached, finished_event, &sem);
    libvlc_event_detach(p_em, libvlc_MediaPlayerEncounteredError, finished_event, &sem);

    libvlc_media_player_stop(p_mp);

    vlc_sem_destroy (&sem);
}
Пример #22
0
static void Close(filter_t *filter)
{
    filter_sys_t *sys = filter->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;

    if (!sys)
        return;

    if (sys->component && sys->component->control->is_enabled)
        mmal_port_disable(sys->component->control);

    if (sys->input && sys->input->is_enabled)
        mmal_port_disable(sys->input);

    if (sys->output && sys->output->is_enabled)
        mmal_port_disable(sys->output);

    if (sys->component && sys->component->is_enabled)
        mmal_component_disable(sys->component);

    while ((buffer = mmal_queue_get(sys->filtered_pictures))) {
        picture_t *pic = (picture_t *)buffer->user_data;
        picture_Release(pic);
    }

    if (sys->filtered_pictures)
        mmal_queue_destroy(sys->filtered_pictures);

    if (sys->component)
        mmal_component_release(sys->component);

    vlc_sem_destroy(&sys->sem);
    free(sys);

    bcm_host_deinit();
}
Пример #23
0
Upnp_i11e_cb::~Upnp_i11e_cb()
{
    vlc_mutex_destroy( &m_lock );
    vlc_sem_destroy( &m_sem );
}
Пример #24
0
/*****************************************************************************
 * InitVideo: initialize the video decoder
 *****************************************************************************
 * the ffmpeg codec will be opened, some memory allocated. The vout is not yet
 * opened (done after the first decoded frame).
 *****************************************************************************/
int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
{
    decoder_sys_t *p_sys;
    int i_val;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(decoder_sys_t) ) ) == NULL )
        return VLC_ENOMEM;

    p_codec->type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_type = AVMEDIA_TYPE_VIDEO;
    p_context->codec_id = i_codec_id;
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
    p_sys->p_ff_pic = avcodec_alloc_frame();
    p_sys->b_delayed_open = true;
    p_sys->p_va = NULL;
    vlc_sem_init( &p_sys->sem_mt, 0 );

    /* ***** Fill p_context with init values ***** */
    p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ? p_dec->fmt_in.i_original_fourcc : p_dec->fmt_in.i_codec );			// sunqueen modify

    /*  ***** Get configuration of ffmpeg plugin ***** */
    p_sys->p_context->workaround_bugs =
        var_InheritInteger( p_dec, "avcodec-workaround-bugs" );
    p_sys->p_context->err_recognition =
        var_InheritInteger( p_dec, "avcodec-error-resilience" );

    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;

    /* ***** Output always the frames ***** */
#if LIBAVCODEC_VERSION_CHECK(55, 23, 1, 40, 101)
    p_sys->p_context->flags |= CODEC_FLAG_OUTPUT_CORRUPT;
#endif

    i_val = var_CreateGetInteger( p_dec, "avcodec-vismv" );
    if( i_val ) p_sys->p_context->debug_mv = i_val;

    i_val = var_CreateGetInteger( p_dec, "avcodec-skiploopfilter" );
    if( i_val >= 4 ) p_sys->p_context->skip_loop_filter = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_loop_filter = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONREF;

    if( var_CreateGetBool( p_dec, "avcodec-fast" ) )
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;

    /* ***** libavcodec frame skipping ***** */
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "avcodec-hurry-up" );

    i_val = var_CreateGetInteger( p_dec, "avcodec-skip-frame" );
    if( i_val >= 4 ) p_sys->p_context->skip_frame = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_frame = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_frame = AVDISCARD_NONREF;
    else if( i_val == -1 ) p_sys->p_context->skip_frame = AVDISCARD_NONE;
    else p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
    p_sys->i_skip_frame = p_sys->p_context->skip_frame;

    i_val = var_CreateGetInteger( p_dec, "avcodec-skip-idct" );
    if( i_val >= 4 ) p_sys->p_context->skip_idct = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_idct = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_idct = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_idct = AVDISCARD_NONREF;
    else if( i_val == -1 ) p_sys->p_context->skip_idct = AVDISCARD_NONE;
    else p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
    p_sys->i_skip_idct = p_sys->p_context->skip_idct;

    /* ***** libavcodec direct rendering ***** */
    p_sys->b_direct_rendering = false;
    p_sys->i_direct_rendering_used = -1;
    if( var_CreateGetBool( p_dec, "avcodec-dr" ) &&
       (p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
        /* No idea why ... but this fixes flickering on some TSCC streams */
        p_sys->i_codec_id != AV_CODEC_ID_TSCC && p_sys->i_codec_id != AV_CODEC_ID_CSCD &&
        p_sys->i_codec_id != AV_CODEC_ID_CINEPAK &&
        !p_sys->p_context->debug_mv )
    {
        /* Some codecs set pix_fmt only after the 1st frame has been decoded,
         * so we need to do another check in ffmpeg_GetFrameBuf() */
        p_sys->b_direct_rendering = true;
    }

    /* libavcodec doesn't properly release old pictures when frames are skipped */
    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
    if( p_sys->b_direct_rendering )
    {
        msg_Dbg( p_dec, "trying to use direct rendering" );
        p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;
    }
    else
    {
        msg_Dbg( p_dec, "direct rendering is disabled" );
    }

    p_sys->p_context->get_format = ffmpeg_GetFormat;
    /* Always use our get_buffer wrapper so we can calculate the
     * PTS correctly */
#if LIBAVCODEC_VERSION_MAJOR >= 55
    p_sys->p_context->get_buffer2 = lavc_GetFrame;
#else
    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
    p_sys->p_context->reget_buffer = avcodec_default_reget_buffer;
    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
#endif
    p_sys->p_context->opaque = p_dec;

#ifdef HAVE_AVCODEC_MT
    int i_thread_count = var_InheritInteger( p_dec, "avcodec-threads" );
    if( i_thread_count <= 0 )
    {
        i_thread_count = vlc_GetCPUCount();
        if( i_thread_count > 1 )
            i_thread_count++;

        //FIXME: take in count the decoding time
        i_thread_count = __MIN( i_thread_count, 4 );
    }
    i_thread_count = __MIN( i_thread_count, 16 );
    msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
    p_sys->p_context->thread_count = i_thread_count;
    p_sys->p_context->thread_safe_callbacks = true;

    switch( i_codec_id )
    {
        case AV_CODEC_ID_MPEG4:
        case AV_CODEC_ID_H263:
            p_sys->p_context->thread_type = 0;
            break;
        case AV_CODEC_ID_MPEG1VIDEO:
        case AV_CODEC_ID_MPEG2VIDEO:
            p_sys->p_context->thread_type &= ~FF_THREAD_SLICE;
            /* fall through */
# if (LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 1, 0))
        case AV_CODEC_ID_H264:
        case AV_CODEC_ID_VC1:
        case AV_CODEC_ID_WMV3:
            p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
# endif
    }

    /* Workaround: frame multithreading is not compatible with
     * DXVA2. When a frame is being copied to host memory, the frame
     * is locked and cannot be used as a reference frame
     * simultaneously and thus decoding fails for some frames. This
     * causes major image corruption. */
# if defined(_WIN32)
    char *avcodec_hw = var_InheritString( p_dec, "avcodec-hw" );
    if( avcodec_hw == NULL || strcasecmp( avcodec_hw, "none" ) )
    {
        msg_Warn( p_dec, "threaded frame decoding is not compatible with DXVA2, disabled" );
        p_sys->p_context->thread_type &= ~FF_THREAD_FRAME;
    }
    free( avcodec_hw );
# endif

    if( p_sys->p_context->thread_type & FF_THREAD_FRAME )
        p_dec->i_extra_picture_buffers = 2 * p_sys->p_context->thread_count;
#endif

    /* ***** misc init ***** */
    p_sys->i_pts = VLC_TS_INVALID;
    p_sys->b_has_b_frames = false;
    p_sys->b_first_frame = true;
    p_sys->b_flush = false;
    p_sys->i_late_frames = 0;

    /* Set output properties */
    p_dec->fmt_out.i_cat = VIDEO_ES;
    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS )
    {
        /* we are doomed. but not really, because most codecs set their pix_fmt later on */
        p_dec->fmt_out.i_codec = VLC_CODEC_I420;
    }
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;

    p_dec->fmt_out.video.orientation = p_dec->fmt_in.video.orientation;

#if LIBAVCODEC_VERSION_MAJOR < 54
    /* Setup palette */
    memset( &p_sys->palette, 0, sizeof(p_sys->palette) );
    if( p_dec->fmt_in.video.p_palette )
    {
        p_sys->palette.palette_changed = 1;

        for( int i = 0; i < __MIN( AVPALETTE_COUNT, p_dec->fmt_in.video.p_palette->i_entries ); i++ )
        {
            union {
                uint32_t u;
                uint8_t a[4];
            } c;
            c.a[0] = p_dec->fmt_in.video.p_palette->palette[i][0];
            c.a[1] = p_dec->fmt_in.video.p_palette->palette[i][1];
            c.a[2] = p_dec->fmt_in.video.p_palette->palette[i][2];
            c.a[3] = p_dec->fmt_in.video.p_palette->palette[i][3];

            p_sys->palette.palette[i] = c.u;
        }
        p_sys->p_context->palctrl = &p_sys->palette;

        p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) );
        if( p_dec->fmt_out.video.p_palette )
            *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette;
    }
    else if( p_sys->i_codec_id != CODEC_ID_MSVIDEO1 && p_sys->i_codec_id != CODEC_ID_CINEPAK )
    {
        p_sys->p_context->palctrl = &p_sys->palette;
    }
#else
    if( p_dec->fmt_in.video.p_palette ) {
        p_sys->palette_sent = false;
        p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) );
        if( p_dec->fmt_out.video.p_palette )
            *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette;
    } else
        p_sys->palette_sent = true;
#endif

    /* ***** init this codec with special data ***** */
    ffmpeg_InitCodec( p_dec );

    /* ***** Open the codec ***** */
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        avcodec_free_frame( &p_sys->p_ff_pic );
        vlc_sem_destroy( &p_sys->sem_mt );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if ( p_dec->fmt_in.i_codec == VLC_CODEC_VP9 )
        p_dec->b_need_packetized = true;

    return VLC_SUCCESS;
}
Пример #25
0
/*****************************************************************************
 * Open: create a handle and open an alsa device
 *****************************************************************************
 * This function opens an alsa device, through the alsa API.
 *
 * Note: the only heap-allocated string is psz_device. All the other pointers
 * are references to psz_device or to stack-allocated data.
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    struct aout_sys_t * p_sys;
    vlc_value_t val;

    char psz_default_iec_device[128]; /* Buffer used to store the default
                                         S/PDIF device */
    char * psz_device, * psz_iec_device; /* device names for PCM and S/PDIF
                                            output */

    int i_vlc_pcm_format; /* Audio format for VLC's data */
    int i_snd_pcm_format; /* Audio format for ALSA's data */

    snd_pcm_uframes_t i_buffer_size = 0;
    snd_pcm_uframes_t i_period_size = 0;
    int i_channels = 0;

    snd_pcm_hw_params_t *p_hw;
    snd_pcm_sw_params_t *p_sw;

    int i_snd_rc = -1;
    unsigned int i_old_rate;
    bool b_retry = true;

    /* Allocate structures */
    p_aout->output.p_sys = p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;

    /* Get device name */
    if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL )
    {
        msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" );
        dialog_Fatal( p_aout, _("No Audio Device"), "%s",
                        _("No audio device name was given. You might want to " \
                          "enter \"default\".") );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Choose the IEC device for S/PDIF output:
       if the device is overriden by the user then it will be the one
       otherwise we compute the default device based on the output format. */
    if( AOUT_FMT_NON_LINEAR( &p_aout->output.output )
        && !strcmp( psz_device, DEFAULT_ALSA_DEVICE ) )
    {
        snprintf( psz_default_iec_device, sizeof(psz_default_iec_device),
                  "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
                  IEC958_AES0_CON_EMPHASIS_NONE | IEC958_AES0_NONAUDIO,
                  IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
                  0,
                  ( p_aout->output.output.i_rate == 48000 ?
                    IEC958_AES3_CON_FS_48000 :
                    ( p_aout->output.output.i_rate == 44100 ?
                      IEC958_AES3_CON_FS_44100 : IEC958_AES3_CON_FS_32000 ) ) );
        psz_iec_device = psz_default_iec_device;
    }
    else if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
    {
        psz_iec_device = psz_device;
    }
    else
    {
        psz_iec_device = NULL;
    }

    /* Choose the linear PCM format (read the comment above about FPU
       and float32) */
    if( HAVE_FPU )
    {
        i_vlc_pcm_format = VLC_CODEC_FL32;
        i_snd_pcm_format = SND_PCM_FORMAT_FLOAT;
    }
    else
    {
        i_vlc_pcm_format = VLC_CODEC_S16N;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
    }

    /* If the variable doesn't exist then it's the first time we're called
       and we have to probe the available audio formats and channels */
    if ( var_Type( p_aout, "audio-device" ) == 0 )
    {
        Probe( p_aout, psz_device, psz_iec_device, &i_snd_pcm_format );
    }

    if ( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

    p_aout->output.output.i_format = i_vlc_pcm_format;
    if ( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
               | AOUT_CHAN_LFE;
        free( psz_device );
        psz_device = strdup( "surround51" );
    }
    else if ( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
        free( psz_device );
        psz_device = strdup( "surround40" );
    }
    else if ( val.i_int == AOUT_VAR_STEREO )
    {
        p_aout->output.output.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }
    else if ( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else if( val.i_int != AOUT_VAR_SPDIF )
    {
        /* This should not happen ! */
        msg_Err( p_aout, "internal: can't find audio-device (%i)", val.i_int );
        free( p_sys );
        free( psz_device );
        return VLC_EGENERIC;
    }

#ifdef ALSA_DEBUG
    snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 );
#endif

    /* Open the device */
    if ( val.i_int == AOUT_VAR_SPDIF )
    {
        if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_iec_device,
                            SND_PCM_STREAM_PLAYBACK, 0 ) ) < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_iec_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_iec_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }
        i_buffer_size = ALSA_SPDIF_BUFFER_SIZE;
        i_snd_pcm_format = SND_PCM_FORMAT_S16;
        i_channels = 2;

        i_vlc_pcm_format = VLC_CODEC_SPDIFL;
        p_aout->output.i_nb_samples = i_period_size = ALSA_SPDIF_PERIOD_SIZE;
        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->output.output.i_frame_length = A52_FRAME_NB;

        aout_VolumeNoneInit( p_aout );
    }
    else
    {
        int i;

        msg_Dbg( p_aout, "opening ALSA device `%s'", psz_device );

        /* Since it seems snd_pcm_close hasn't really released the device at
          the time it returns, probe if the device is available in loop for 1s.
          We cannot use blocking mode since the we would wait indefinitely when
          switching from a dmx device to surround51. */

        for( i = 10; i >= 0; i-- )
        {
            if ( ( i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device,
                   SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) == -EBUSY )
            {
                if( i ) msleep( 100000 /* 100ms */ );
                else
                {
                    msg_Err( p_aout, "audio device: %s is already in use",
                              psz_device );
                    dialog_Fatal( p_aout, _("Audio output failed"),
                                    _("The audio device \"%s\" is already in use."),
                                    psz_device );
                }
                continue;
            }
            break;
        }
        if( i_snd_rc < 0 )
        {
            msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
                             psz_device, snd_strerror( i_snd_rc ) );
            dialog_Fatal( p_aout, _("Audio output failed"),
                            _("VLC could not open the ALSA device \"%s\" (%s)."),
                            psz_device, snd_strerror( i_snd_rc ) );
            free( p_sys );
            free( psz_device );
            return VLC_EGENERIC;
        }

        /* We want blocking mode */
        snd_pcm_nonblock( p_sys->p_snd_pcm, 0 );

        i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE;
        i_channels = aout_FormatNbChannels( &p_aout->output.output );

        p_aout->output.i_nb_samples = i_period_size = ALSA_DEFAULT_PERIOD_SIZE;

        aout_VolumeSoftInit( p_aout );
    }

    /* Free psz_device so that all the remaining data is stack-allocated */
    free( psz_device );

    p_aout->output.pf_play = Play;

    snd_pcm_hw_params_alloca(&p_hw);
    snd_pcm_sw_params_alloca(&p_sw);

    /* Due to some bugs in alsa with some drivers, we need to retry in s16l
       if snd_pcm_hw_params fails in fl32 */
    while ( b_retry )
    {
        b_retry = false;

        /* Get Initial hardware parameters */
        if ( ( i_snd_rc = snd_pcm_hw_params_any( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            msg_Err( p_aout, "unable to retrieve initial hardware parameters (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set format. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm, p_hw,
                                                    i_snd_pcm_format ) ) < 0 )
        {
            if( i_snd_pcm_format != SND_PCM_FORMAT_S16 )
            {
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                i_snd_rc = snd_pcm_hw_params_set_format( p_sys->p_snd_pcm,
                                                     p_hw, i_snd_pcm_format );
            }
            if ( i_snd_rc < 0 )
            {
                msg_Err( p_aout, "unable to set stream sample size and "
                     "word order (%s)", snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
        if( i_vlc_pcm_format != VLC_CODEC_SPDIFL )
        switch( i_snd_pcm_format )
        {
        case SND_PCM_FORMAT_FLOAT:
            i_vlc_pcm_format = VLC_CODEC_FL32;
            break;
        case SND_PCM_FORMAT_S16:
            i_vlc_pcm_format = VLC_CODEC_S16N;
            break;
        }
        p_aout->output.output.i_format = i_vlc_pcm_format;

        if ( ( i_snd_rc = snd_pcm_hw_params_set_access( p_sys->p_snd_pcm, p_hw,
                                    SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set interleaved stream format (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set channels. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_channels( p_sys->p_snd_pcm, p_hw,
                                                      i_channels ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set number of output channels (%s)",
                             snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Set rate. */
        i_old_rate = p_aout->output.output.i_rate;
        i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw,
                                                &p_aout->output.output.i_rate,
                                                NULL );
        if( i_snd_rc < 0 || p_aout->output.output.i_rate != i_old_rate )
        {
            msg_Warn( p_aout, "The rate %d Hz is not supported by your " \
                "hardware. Using %d Hz instead.\n", i_old_rate, \
                p_aout->output.output.i_rate );
        }

        /* Set period size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_period_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_period_size, NULL ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set period size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }
        p_aout->output.i_nb_samples = i_period_size;

/* Set buffer size. */
        if ( ( i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm,
                                    p_hw, &i_buffer_size ) ) < 0 )
        {
            msg_Err( p_aout, "unable to set buffer size (%s)",
                         snd_strerror( i_snd_rc ) );
            goto error;
        }

        /* Commit hardware parameters. */
        if ( ( i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ) ) < 0 )
        {
            if ( b_retry == false &&
                                i_snd_pcm_format == SND_PCM_FORMAT_FLOAT)
            {
                b_retry = true;
                i_snd_pcm_format = SND_PCM_FORMAT_S16;
                p_aout->output.output.i_format = VLC_CODEC_S16N;
                msg_Warn( p_aout, "unable to commit hardware configuration "
                                  "with fl32 samples. Retrying with s16l (%s)",                                     snd_strerror( i_snd_rc ) );
            }
            else
            {
                msg_Err( p_aout, "unable to commit hardware configuration (%s)",
                         snd_strerror( i_snd_rc ) );
                goto error;
            }
        }
    }

    if( ( i_snd_rc = snd_pcm_hw_params_get_period_time( p_hw,
                                    &p_sys->i_period_time, NULL ) ) < 0 )
    {
        msg_Err( p_aout, "unable to get period time (%s)",
                         snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Get Initial software parameters */
    snd_pcm_sw_params_current( p_sys->p_snd_pcm, p_sw );

    i_snd_rc = snd_pcm_sw_params_set_sleep_min( p_sys->p_snd_pcm, p_sw, 0 );

    i_snd_rc = snd_pcm_sw_params_set_avail_min( p_sys->p_snd_pcm, p_sw,
                                                p_aout->output.i_nb_samples );
    /* start playing when one period has been written */
    i_snd_rc = snd_pcm_sw_params_set_start_threshold( p_sys->p_snd_pcm, p_sw,
                                                      ALSA_DEFAULT_PERIOD_SIZE);
    if( i_snd_rc < 0 )
    {
        msg_Err( p_aout, "unable to set start threshold (%s)",
                          snd_strerror( i_snd_rc ) );
        goto error;
    }

    /* Commit software parameters. */
    if ( snd_pcm_sw_params( p_sys->p_snd_pcm, p_sw ) < 0 )
    {
        msg_Err( p_aout, "unable to set software configuration" );
        goto error;
    }

#ifdef ALSA_DEBUG
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA hardware setup:\n\n" );
    snd_pcm_dump_hw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\nALSA software setup:\n\n" );
    snd_pcm_dump_sw_setup( p_sys->p_snd_pcm, p_sys->p_snd_stderr );
    snd_output_printf( p_sys->p_snd_stderr, "\n" );
#endif

    p_sys->start_date = 0;
    vlc_sem_init( &p_sys->wait, 0 );

    /* Create ALSA thread and wait for its readiness. */
    if( vlc_clone( &p_sys->thread, ALSAThread, p_aout,
                   VLC_THREAD_PRIORITY_OUTPUT ) )
    {
        msg_Err( p_aout, "cannot create ALSA thread (%m)" );
        vlc_sem_destroy( &p_sys->wait );
        goto error;
    }

    return 0;

error:
    snd_pcm_close( p_sys->p_snd_pcm );
#ifdef ALSA_DEBUG
    snd_output_close( p_sys->p_snd_stderr );
#endif
    free( p_sys );
    return VLC_EGENERIC;
}
Пример #26
0
/* Open Interface */
static int Open( vlc_object_t *p_this, bool isDialogProvider )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;

#if defined (QT5_HAS_X11) || defined (Q_WS_X11)
    if( !vlc_xlib_init( p_this ) )
        return VLC_EGENERIC;

    Display *p_display = XOpenDisplay( NULL );
    if( !p_display )
    {
        msg_Err( p_intf, "Could not connect to X server" );
        return VLC_EGENERIC;
    }
    XCloseDisplay( p_display );
#endif

    QMutexLocker locker (&lock);
    if (busy)
    {
        msg_Err (p_this, "cannot start Qt multiple times");
        return VLC_EGENERIC;
    }

    /* Allocations of p_sys */
    intf_sys_t *p_sys = p_intf->p_sys = new intf_sys_t;
    p_intf->p_sys->b_isDialogProvider = isDialogProvider;
    p_sys->p_mi = NULL;
    p_sys->pl_model = NULL;

    /* set up the playlist to work on */
    if( isDialogProvider )
        p_intf->p_sys->p_playlist = pl_Get( (intf_thread_t *)p_intf->p_parent );
    else
        p_intf->p_sys->p_playlist = pl_Get( p_intf );

    /* */
    vlc_sem_init (&ready, 0);
#ifdef Q_OS_MAC
    /* Run mainloop on the main thread as Cocoa requires */
    libvlc_SetExitHandler( p_intf->p_libvlc, Abort, p_intf );
    Thread( (void *)p_intf );
#else
    if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) )
    {
        delete p_sys;
        return VLC_ENOMEM;
    }
#endif

    /* Wait for the interface to be ready. This prevents the main
     * LibVLC thread from starting video playback before we can create
     * an embedded video window. */
    vlc_sem_wait (&ready);
    vlc_sem_destroy (&ready);
    busy = active = true;

#ifndef Q_OS_MAC
    if( !isDialogProvider )
        RegisterIntf( p_intf );
#endif

    return VLC_SUCCESS;
}
Пример #27
0
/*****************************************************************************
 * InitVideo: initialize the video decoder
 *****************************************************************************
 * the ffmpeg codec will be opened, some memory allocated. The vout is not yet
 * opened (done after the first decoded frame).
 *****************************************************************************/
int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
{
    decoder_sys_t *p_sys;
    int i_val;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = calloc( 1, sizeof(decoder_sys_t) ) ) == NULL )
        return VLC_ENOMEM;

    p_codec->type = CODEC_TYPE_VIDEO;
    p_context->codec_type = CODEC_TYPE_VIDEO;
    p_context->codec_id = i_codec_id;
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
    p_sys->p_ff_pic = avcodec_alloc_frame();
    p_sys->b_delayed_open = true;
    p_sys->p_va = NULL;
    vlc_sem_init( &p_sys->sem_mt, 0 );

    /* ***** Fill p_context with init values ***** */
    p_sys->p_context->codec_tag = ffmpeg_CodecTag( p_dec->fmt_in.i_original_fourcc ?: p_dec->fmt_in.i_codec );

    /*  ***** Get configuration of ffmpeg plugin ***** */
    p_sys->p_context->workaround_bugs =
        var_InheritInteger( p_dec, "ffmpeg-workaround-bugs" );
    p_sys->p_context->error_recognition =
        var_InheritInteger( p_dec, "ffmpeg-error-resilience" );

    if( var_CreateGetBool( p_dec, "grayscale" ) )
        p_sys->p_context->flags |= CODEC_FLAG_GRAY;

    i_val = var_CreateGetInteger( p_dec, "ffmpeg-vismv" );
    if( i_val ) p_sys->p_context->debug_mv = i_val;

    i_val = var_CreateGetInteger( p_dec, "ffmpeg-lowres" );
    if( i_val > 0 && i_val <= 2 ) p_sys->p_context->lowres = i_val;

    i_val = var_CreateGetInteger( p_dec, "ffmpeg-skiploopfilter" );
    if( i_val >= 4 ) p_sys->p_context->skip_loop_filter = AVDISCARD_ALL;
    else if( i_val == 3 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONKEY;
    else if( i_val == 2 ) p_sys->p_context->skip_loop_filter = AVDISCARD_BIDIR;
    else if( i_val == 1 ) p_sys->p_context->skip_loop_filter = AVDISCARD_NONREF;

    if( var_CreateGetBool( p_dec, "ffmpeg-fast" ) )
        p_sys->p_context->flags2 |= CODEC_FLAG2_FAST;

    /* ***** ffmpeg frame skipping ***** */
    p_sys->b_hurry_up = var_CreateGetBool( p_dec, "ffmpeg-hurry-up" );

    switch( var_CreateGetInteger( p_dec, "ffmpeg-skip-frame" ) )
    {
        case -1:
            p_sys->p_context->skip_frame = AVDISCARD_NONE;
            break;
        case 0:
            p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
            break;
        case 1:
            p_sys->p_context->skip_frame = AVDISCARD_BIDIR;
            break;
        case 2:
            p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
            break;
        case 3:
            p_sys->p_context->skip_frame = AVDISCARD_ALL;
            break;
        default:
            p_sys->p_context->skip_frame = AVDISCARD_NONE;
            break;
    }
    p_sys->i_skip_frame = p_sys->p_context->skip_frame;

    switch( var_CreateGetInteger( p_dec, "ffmpeg-skip-idct" ) )
    {
        case -1:
            p_sys->p_context->skip_idct = AVDISCARD_NONE;
            break;
        case 0:
            p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
            break;
        case 1:
            p_sys->p_context->skip_idct = AVDISCARD_BIDIR;
            break;
        case 2:
            p_sys->p_context->skip_idct = AVDISCARD_NONKEY;
            break;
        case 3:
            p_sys->p_context->skip_idct = AVDISCARD_ALL;
            break;
        default:
            p_sys->p_context->skip_idct = AVDISCARD_NONE;
            break;
    }
    p_sys->i_skip_idct = p_sys->p_context->skip_idct;

    /* ***** ffmpeg direct rendering ***** */
    p_sys->b_direct_rendering = false;
    p_sys->i_direct_rendering_used = -1;
    if( var_CreateGetBool( p_dec, "ffmpeg-dr" ) &&
       (p_sys->p_codec->capabilities & CODEC_CAP_DR1) &&
        /* No idea why ... but this fixes flickering on some TSCC streams */
        p_sys->i_codec_id != CODEC_ID_TSCC &&
        !p_sys->p_context->debug_mv )
    {
        /* Some codecs set pix_fmt only after the 1st frame has been decoded,
         * so we need to do another check in ffmpeg_GetFrameBuf() */
        p_sys->b_direct_rendering = true;
    }

    /* ffmpeg doesn't properly release old pictures when frames are skipped */
    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = false;
    if( p_sys->b_direct_rendering )
    {
        msg_Dbg( p_dec, "trying to use direct rendering" );
        p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;
    }
    else
    {
        msg_Dbg( p_dec, "direct rendering is disabled" );
    }

    /* Always use our get_buffer wrapper so we can calculate the
     * PTS correctly */
    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
    p_sys->p_context->reget_buffer = ffmpeg_ReGetFrameBuf;
    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
    p_sys->p_context->opaque = p_dec;

#ifdef HAVE_AVCODEC_MT
    int i_thread_count = var_InheritInteger( p_dec, "ffmpeg-threads" );
    if( i_thread_count <= 0 )
        i_thread_count = vlc_GetCPUCount();
    msg_Dbg( p_dec, "allowing %d thread(s) for decoding", i_thread_count );
    p_sys->p_context->thread_count = i_thread_count;
#endif

#ifdef HAVE_AVCODEC_VA
    const bool b_use_hw = var_CreateGetBool( p_dec, "ffmpeg-hw" );
    if( b_use_hw )
    {
#ifdef HAVE_AVCODEC_MT
        msg_Err( p_dec, "ffmpeg-hw is not compatible with ffmpeg-mt" );
#else
        p_sys->p_context->get_format = ffmpeg_GetFormat;
#endif
    }
#endif

    /* ***** misc init ***** */
    p_sys->i_pts = VLC_TS_INVALID;
    p_sys->b_has_b_frames = false;
    p_sys->b_first_frame = true;
    p_sys->b_flush = false;
    p_sys->i_late_frames = 0;

    /* Set output properties */
    p_dec->fmt_out.i_cat = VIDEO_ES;
    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS )
    {
        /* we are doomed. but not really, because most codecs set their pix_fmt later on */
        p_dec->fmt_out.i_codec = VLC_CODEC_I420;
    }
    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;

    /* Setup palette */
    memset( &p_sys->palette, 0, sizeof(p_sys->palette) );
    if( p_dec->fmt_in.video.p_palette )
    {
        p_sys->palette.palette_changed = 1;

        for( int i = 0; i < __MIN( AVPALETTE_COUNT, p_dec->fmt_in.video.p_palette->i_entries ); i++ )
        {
            union {
                uint32_t u;
                uint8_t a[4];
            } c;
            c.a[0] = p_dec->fmt_in.video.p_palette->palette[i][0];
            c.a[1] = p_dec->fmt_in.video.p_palette->palette[i][1];
            c.a[2] = p_dec->fmt_in.video.p_palette->palette[i][2];
            c.a[3] = p_dec->fmt_in.video.p_palette->palette[i][3];

            p_sys->palette.palette[i] = c.u;
        }
        p_sys->p_context->palctrl = &p_sys->palette;

        p_dec->fmt_out.video.p_palette = malloc( sizeof(video_palette_t) );
        if( p_dec->fmt_out.video.p_palette )
            *p_dec->fmt_out.video.p_palette = *p_dec->fmt_in.video.p_palette;
    }
    else if( p_sys->i_codec_id != CODEC_ID_MSVIDEO1 && p_sys->i_codec_id != CODEC_ID_CINEPAK )
    {
        p_sys->p_context->palctrl = &p_sys->palette;
    }

    /* ***** init this codec with special data ***** */
    ffmpeg_InitCodec( p_dec );

    /* ***** Open the codec ***** */
    if( ffmpeg_OpenCodec( p_dec ) < 0 )
    {
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
        av_free( p_sys->p_ff_pic );
        vlc_sem_destroy( &p_sys->sem_mt );
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
Пример #28
0
int main(void)
{
    struct vlc_h2_output *out;

    /* Dummy */
    out = vlc_h2_output_create(NULL, false);
    assert(out != NULL);
    vlc_h2_output_destroy(out);

    vlc_sem_init(&rx, 0);
    out = vlc_h2_output_create(NULL, expect_hello = true);
    assert(out != NULL);
    vlc_h2_output_destroy(out);
    vlc_sem_destroy(&rx);

    /* Success */
    vlc_sem_init(&rx, 0);
    out = vlc_h2_output_create(NULL, false);
    assert(out != NULL);
    assert(vlc_h2_output_send_prio(out, NULL) == -1);
    assert(vlc_h2_output_send_prio(out, frame(0)) == 0);
    assert(vlc_h2_output_send_prio(out, frame(1)) == 0);
    assert(vlc_h2_output_send(out, NULL) == -1);
    assert(vlc_h2_output_send(out, frame(2)) == 0);
    assert(vlc_h2_output_send(out, frame(3)) == 0);
    assert(vlc_h2_output_send(out, frame_list(frame(4), frame(5),
                                              frame(6), NULL)) == 0);
    assert(vlc_h2_output_send(out, frame(7)) == 0);
    for (unsigned i = 0; i < 8; i++)
        vlc_sem_wait(&rx);

    assert(vlc_h2_output_send_prio(out, frame(8)) == 0);
    assert(vlc_h2_output_send(out, frame(9)) == 0);

    vlc_h2_output_destroy(out);
    vlc_sem_destroy(&rx);

    /* Failure */
    send_failure = true;

    vlc_sem_init(&rx, 0);
    counter = 10;
    out = vlc_h2_output_create(NULL, false);
    assert(out != NULL);

    assert(vlc_h2_output_send(out, frame(10)) == 0);
    for (unsigned char i = 11; vlc_h2_output_send(out, frame(i)) == 0; i++)
        msleep(CLOCK_FREQ/10); /* eventually, it should start failing */
    assert(vlc_h2_output_send(out, frame(0)) == -1);
    assert(vlc_h2_output_send_prio(out, frame(0)) == -1);
    vlc_h2_output_destroy(out);
    vlc_sem_destroy(&rx);

    /* Failure during hello */
    vlc_sem_init(&rx, 0);
    counter = 0;
    out = vlc_h2_output_create(NULL, expect_hello = true);
    assert(out != NULL);
    vlc_sem_wait(&rx);

    for (unsigned char i = 1; vlc_h2_output_send_prio(out, frame(i)) == 0; i++)
        msleep(CLOCK_FREQ/10);
    assert(vlc_h2_output_send(out, frame(0)) == -1);
    assert(vlc_h2_output_send_prio(out, frame(0)) == -1);
    vlc_h2_output_destroy(out);
    vlc_sem_destroy(&rx);

    return 0;
}