예제 #1
0
파일: sap.c 프로젝트: forthyen/SDesk
/**
 * Create the SAP handler
 *
 * \param p_announce the parent announce_handler
 * \return the newly created SAP handler or NULL on error
 */
sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce )
{
    sap_handler_t *p_sap;

    p_sap = vlc_object_create( p_announce, sizeof( sap_handler_t ) );

    if( !p_sap )
    {
        msg_Err( p_announce, "out of memory" );
        return NULL;
    }

    vlc_mutex_init( p_sap, &p_sap->object_lock );

    p_sap->pf_add = announce_SAPAnnounceAdd;
    p_sap->pf_del = announce_SAPAnnounceDel;

    p_sap->i_sessions = 0;
    p_sap->i_addresses = 0;
    p_sap->i_current_session = 0;

    p_sap->b_control = config_GetInt( p_sap, "sap-flow-control");

    if( vlc_thread_create( p_sap, "sap handler", RunThread,
                       VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
    {
        msg_Dbg( p_announce, "Unable to spawn SAP handler thread");
        free( p_sap );
        return NULL;
    };
    msg_Dbg( p_announce, "thread created, %i sessions", p_sap->i_sessions);
    return p_sap;
}
예제 #2
0
/*****************************************************************************
 * aout_New: initialize aout structure
 *****************************************************************************/
aout_instance_t * __aout_New( vlc_object_t * p_parent )
{
    aout_instance_t * p_aout;
    vlc_value_t val;

    /* Allocate descriptor. */
    p_aout = vlc_object_create( p_parent, VLC_OBJECT_AOUT );
    if( p_aout == NULL )
    {
        return NULL;
    }

    /* Initialize members. */
    vlc_mutex_init( p_parent, &p_aout->input_fifos_lock );
    vlc_mutex_init( p_parent, &p_aout->mixer_lock );
    vlc_mutex_init( p_parent, &p_aout->output_fifo_lock );
    p_aout->i_nb_inputs = 0;
    p_aout->mixer.f_multiplier = 1.0;
    p_aout->mixer.b_error = 1;
    p_aout->output.b_error = 1;
    p_aout->output.b_starving = 1;

    var_Create( p_aout, "intf-change", VLC_VAR_BOOL );
    val.b_bool = VLC_TRUE;
    var_Set( p_aout, "intf-change", val );

    return p_aout;
}
예제 #3
0
파일: filters.c 프로젝트: forthyen/SDesk
/*****************************************************************************
 * FindFilter: find an audio filter for a specific transformation
 *****************************************************************************/
static aout_filter_t * FindFilter( aout_instance_t * p_aout,
                             const audio_sample_format_t * p_input_format,
                             const audio_sample_format_t * p_output_format )
{
    aout_filter_t * p_filter = vlc_object_create( p_aout,
                                                  sizeof(aout_filter_t) );

    if ( p_filter == NULL ) return NULL;
    vlc_object_attach( p_filter, p_aout );

    memcpy( &p_filter->input, p_input_format, sizeof(audio_sample_format_t) );
    memcpy( &p_filter->output, p_output_format,
            sizeof(audio_sample_format_t) );
    p_filter->p_module = module_Need( p_filter, "audio filter", NULL, 0 );
    if ( p_filter->p_module == NULL )
    {
        vlc_object_detach( p_filter );
        vlc_object_destroy( p_filter );
        return NULL;
    }

    p_filter->b_continuity = VLC_FALSE;

    return p_filter;
}
예제 #4
0
static int Install( addons_storage_t *p_storage, addon_entry_t *p_entry )
{
    vlc_object_t *p_this = VLC_OBJECT( p_storage );
    int i_ret = VLC_EGENERIC;

    if ( ! p_entry->psz_source_module )
        return i_ret;

    /* Query origin module for download path */
    addons_finder_t *p_finder = vlc_object_create( p_this, sizeof( addons_finder_t ) );
    if( !p_finder )
        return VLC_ENOMEM;

    module_t *p_module = module_need( p_finder, "addons finder",
                                      p_entry->psz_source_module, true );
    if( p_module )
    {
        if ( p_finder->pf_retrieve( p_finder, p_entry ) == VLC_SUCCESS )
        {
            /* Do things while retrieved data is here */
            vlc_mutex_lock( &p_entry->lock );
            i_ret = InstallAllFiles( p_storage, p_entry );
            vlc_mutex_unlock( &p_entry->lock );
            /* !Do things while retrieved data is here */
        }

        module_unneed( p_finder, p_module );
    }

    vlc_object_release( p_finder );

    return i_ret;
}
예제 #5
0
파일: d3d11va.c 프로젝트: 0xheart0/vlc
static filter_t *CreateFilter( vlc_object_t *p_this, const es_format_t *p_fmt_in,
                               vlc_fourcc_t fmt_out )
{
    filter_t *p_filter;

    p_filter = vlc_object_create( p_this, sizeof(filter_t) );
    if (unlikely(p_filter == NULL))
        return NULL;

    p_filter->owner.video.buffer_new = (picture_t *(*)(filter_t *))video_new_buffer;

    es_format_InitFromVideo( &p_filter->fmt_in,  &p_fmt_in->video );
    es_format_InitFromVideo( &p_filter->fmt_out, &p_fmt_in->video );
    p_filter->fmt_in.i_codec  = p_filter->fmt_in.video.i_chroma  = VLC_CODEC_D3D11_OPAQUE;
    p_filter->fmt_out.i_codec = p_filter->fmt_out.video.i_chroma = fmt_out;
    p_filter->p_module = module_need( p_filter, "video filter2", NULL, false );

    if( !p_filter->p_module )
    {
        msg_Dbg( p_filter, "no video filter found" );
        DeleteFilter( p_filter );
        return NULL;
    }

    return p_filter;
}
예제 #6
0
/*****************************************************************************
 * Open: open a scope effect plugin
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    aout_filter_t     *p_filter = (aout_filter_t *)p_this;
    aout_filter_sys_t *p_sys;
    galaktos_thread_t *p_thread;

    if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2' )
         || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
    {
        msg_Warn( p_filter, "bad input or output format" );
        return VLC_EGENERIC;
    }
    if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
    {
        msg_Warn( p_filter, "input and output formats are not similar" );
        return VLC_EGENERIC;
    }

    p_filter->pf_do_work = DoWork;
    p_filter->b_in_place = 1;

    /* Allocate structure */
    p_sys = p_filter->p_sys = malloc( sizeof( aout_filter_sys_t ) );

    /* Create galaktos thread */
    p_sys->p_thread = p_thread =
        vlc_object_create( p_filter, sizeof( galaktos_thread_t ) );
    vlc_object_attach( p_thread, p_this );

/*
    var_Create( p_thread, "galaktos-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
    var_Get( p_thread, "galaktos-width", &width );
    var_Create( p_thread, "galaktos-height", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
    var_Get( p_thread, "galaktos-height", &height );
*/
    p_thread->i_cur_sample = 0;
    bzero( p_thread->p_data, 2*2*512 );

    p_thread->i_width = 600;
    p_thread->i_height = 600;
    p_thread->b_fullscreen = 0;
    galaktos_init( p_thread );

    p_thread->i_channels = aout_FormatNbChannels( &p_filter->input );

    p_thread->psz_title = TitleGet( VLC_OBJECT( p_filter ) );

    if( vlc_thread_create( p_thread, "galaktos update thread", Thread,
                           VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
    {
        msg_Err( p_filter, "cannot lauch galaktos thread" );
        if( p_thread->psz_title ) free( p_thread->psz_title );
        vlc_object_detach( p_thread );
        vlc_object_destroy( p_thread );
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
예제 #7
0
bool Dialogs::init()
{
    // Allocate descriptor
    m_pProvider = (intf_thread_t *)vlc_object_create( getIntf(),
                                                    sizeof( intf_thread_t ) );
    if( m_pProvider == NULL )
        return false;

    // Attach the dialogs provider to its parent interface
    vlc_object_attach( m_pProvider, getIntf() );

    m_pModule = module_need( m_pProvider, "dialogs provider", NULL, false );
    if( m_pModule == NULL )
    {
        msg_Err( getIntf(), "no suitable dialogs provider found (hint: compile the qt4 plugin, and make sure it is loaded properly)" );
        vlc_object_release( m_pProvider );
        m_pProvider = NULL;
        return false;
    }

    /* Register callback for the intf-popupmenu variable */
    var_AddCallback( getIntf()->p_libvlc, "intf-popupmenu",
                     PopupMenuCB, this );

    return true;
}
예제 #8
0
/*****************************************************************************
 * Open: initializes demux structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;
    uint8_t     *p_peek;
    vlc_value_t val;

    if( stream_Peek( p_demux->s, &p_peek, 5 ) < 5 ) return VLC_EGENERIC;

    if( p_peek[0] != 0x00 || p_peek[1] != 0x00 ||
        p_peek[2] != 0x00 || p_peek[3] != 0x01 ||
        (p_peek[4]&0x1F) != 7 ) /* SPS */
    {
        if( !p_demux->b_force )
        {
            msg_Warn( p_demux, "h264 module discarded (no startcode)" );
            return VLC_EGENERIC;
        }

        msg_Err( p_demux, "this doesn't look like a H264 ES stream, "
                 "continuing anyway" );
    }

    p_demux->pf_demux  = Demux;
    p_demux->pf_control= Control;
    p_demux->p_sys     = p_sys = malloc( sizeof( demux_sys_t ) );
    p_sys->p_es        = NULL;
    p_sys->i_dts       = 1;
    var_Create( p_demux, "h264-fps", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT );
    var_Get( p_demux, "h264-fps", &val );
    p_sys->f_fps = val.f_float;
    if( val.f_float < 0.001 ) p_sys->f_fps = 0.001;
    msg_Dbg( p_demux, "using %.2f fps", p_sys->f_fps );

    /*
     * Load the mpegvideo packetizer
     */
    p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
    p_sys->p_packetizer->pf_decode_audio = NULL;
    p_sys->p_packetizer->pf_decode_video = NULL;
    p_sys->p_packetizer->pf_decode_sub = NULL;
    p_sys->p_packetizer->pf_packetize = NULL;
    es_format_Init( &p_sys->p_packetizer->fmt_in, VIDEO_ES,
                    VLC_FOURCC( 'h', '2', '6', '4' ) );
    es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
    p_sys->p_packetizer->p_module =
        module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );

    if( p_sys->p_packetizer->p_module == NULL)
    {
        vlc_object_destroy( p_sys->p_packetizer );
        msg_Err( p_demux, "cannot find mp4v packetizer" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
예제 #9
0
파일: qte.cpp 프로젝트: Kafay/vlc
/*****************************************************************************
 * OpenDisplay: create qte applicaton / window
 *****************************************************************************
 * Create a window according to video output given size, and set other
 * properties according to the display properties.
 *****************************************************************************/
static int OpenDisplay( vout_thread_t *p_vout )
{
    /* for displaying the vout in a qt window we need the QtApplication */
    p_vout->p_sys->p_QApplication = NULL;
    p_vout->p_sys->p_VideoWidget = NULL;

    p_vout->p_sys->p_event = (event_thread_t*) vlc_object_create( p_vout, sizeof(event_thread_t) );
    p_vout->p_sys->p_event->p_vout = p_vout;

    /* Initializations */
#if 1 /* FIXME: I need an event queue to handle video output size changes. */
    p_vout->b_fullscreen = true;
#endif

    /* Set main window's size */
    QWidget *desktop = p_vout->p_sys->p_QApplication->desktop();
    p_vout->p_sys->i_width = p_vout->b_fullscreen ? desktop->height() :
                                                    p_vout->i_window_width;
    p_vout->p_sys->i_height = p_vout->b_fullscreen ? desktop->width() :
                                                     p_vout->i_window_height;

#if 0 /* FIXME: I need an event queue to handle video output size changes. */
    /* Update dimensions */
    p_vout->i_changes |= VOUT_SIZE_CHANGE;
    p_vout->i_window_width = p_vout->p_sys->i_width;
    p_vout->i_window_height = p_vout->p_sys->i_height;
#endif

    msg_Dbg( p_vout, "opening display (h=%d,w=%d)",p_vout->p_sys->i_height,p_vout->p_sys->i_width);

    /* create thread to exec the qpe application */
    if ( vlc_thread_create( p_vout->p_sys->p_event, "QT Embedded Thread",
                            RunQtThread,
                            VLC_THREAD_PRIORITY_OUTPUT, true) )
    {
        msg_Err( p_vout, "cannot create QT Embedded Thread" );
        vlc_object_release( p_vout->p_sys->p_event );
        p_vout->p_sys->p_event = NULL;
        return -1;
    }

    if( p_vout->p_sys->p_event->b_error )
    {
        msg_Err( p_vout, "RunQtThread failed" );
        return -1;
    }

    vlc_object_attach( p_vout->p_sys->p_event, p_vout );
    msg_Dbg( p_vout, "RunQtThread running" );

    // just wait until the crew is complete...
    while(p_vout->p_sys->p_VideoWidget == NULL)
    {
        msleep(1);
    }
    return VLC_SUCCESS;
}
예제 #10
0
파일: loadsave.c 프로젝트: 0xheart0/vlc
int playlist_MLLoad( playlist_t *p_playlist )
{
    input_item_t *p_input;

    char *psz_datadir = config_GetUserDir( VLC_DATA_DIR );
    if( !psz_datadir ) /* XXX: This should never happen */
    {
        msg_Err( p_playlist, "no data directory, cannot load media library") ;
        return VLC_EGENERIC;
    }

    char *psz_file;
    if( asprintf( &psz_file, "%s" DIR_SEP "ml.xspf", psz_datadir ) == -1 )
        psz_file = NULL;
    free( psz_datadir );
    if( psz_file == NULL )
        return VLC_ENOMEM;

    /* lousy check for media library file */
    struct stat st;
    if( vlc_stat( psz_file, &st ) )
    {
        free( psz_file );
        return VLC_EGENERIC;
    }

    char *psz_uri = vlc_path2uri( psz_file, "file/xspf-open" );
    free( psz_file );
    if( psz_uri == NULL )
        return VLC_ENOMEM;

    p_input = input_item_New( psz_uri, _("Media Library") );
    free( psz_uri );
    if( p_input == NULL )
        return VLC_EGENERIC;

    PL_LOCK;
    if( p_playlist->p_media_library->p_input )
        vlc_gc_decref( p_playlist->p_media_library->p_input );

    p_playlist->p_media_library->p_input = p_input;

    vlc_event_attach( &p_input->event_manager, vlc_InputItemSubItemTreeAdded,
                        input_item_subitem_tree_added, p_playlist );
    PL_UNLOCK;

    vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof (*dummy) );
    var_Create( dummy, "meta-file", VLC_VAR_VOID );
    input_Read( dummy, p_input );
    vlc_object_release( dummy );

    vlc_event_detach( &p_input->event_manager, vlc_InputItemSubItemTreeAdded,
                        input_item_subitem_tree_added, p_playlist );

    return VLC_SUCCESS;
}
예제 #11
0
파일: blendbench.c 프로젝트: videolan/vlc
/*****************************************************************************
 * Render: displays previously rendered output
 *****************************************************************************/
static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    filter_t *p_blend;

    if( p_sys->b_done )
        return p_pic;

    p_blend = vlc_object_create( p_filter, sizeof(filter_t) );
    if( !p_blend )
    {
        picture_Release( p_pic );
        return NULL;
    }
    p_blend->fmt_out.video = p_sys->p_base_image->format;
    p_blend->fmt_in.video = p_sys->p_blend_image->format;
    p_blend->p_module = module_need( p_blend, "video blending", NULL, false );
    if( !p_blend->p_module )
    {
        picture_Release( p_pic );
        vlc_object_delete(p_blend);
        return NULL;
    }

    vlc_tick_t time = vlc_tick_now();
    for( int i_iter = 0; i_iter < p_sys->i_loops; ++i_iter )
    {
        p_blend->pf_video_blend( p_blend,
                                 p_sys->p_base_image, p_sys->p_blend_image,
                                 0, 0, p_sys->i_alpha );
    }
    time = vlc_tick_now() - time;

    msg_Info( p_filter, "Blended %d images in %f sec", p_sys->i_loops,
              secf_from_vlc_tick(time) );
    msg_Info( p_filter, "Speed is: %f images/second, %f pixels/second",
              (float) p_sys->i_loops / time * CLOCK_FREQ,
              (float) p_sys->i_loops / time * CLOCK_FREQ *
                  p_sys->p_blend_image->p[Y_PLANE].i_visible_pitch *
                  p_sys->p_blend_image->p[Y_PLANE].i_visible_lines );

    module_unneed( p_blend, p_blend->p_module );

    vlc_object_delete(p_blend);

    p_sys->b_done = true;
    return p_pic;
}
예제 #12
0
CThread::CThread(vlc_object_t *pOwner)
{
    m_bTerminated  = ATMO_FALSE;
    m_pAtmoThread = (atmo_thread_t *)vlc_object_create( pOwner,
                                                        sizeof(atmo_thread_t) );
    if(m_pAtmoThread)
    {
        m_pAtmoThread->p_thread = this;
        this->m_pOwner = pOwner;

        vlc_object_attach( m_pAtmoThread, m_pOwner);

        vlc_mutex_init( &m_TerminateLock );
        vlc_cond_init( &m_TerminateCond );
    }
}
예제 #13
0
/**
 * Create the announce handler object
 *
 * \param p_this a vlc_object structure
 * \return the new announce handler or NULL on error
 */
announce_handler_t *__announce_HandlerCreate( vlc_object_t *p_this )
{
    announce_handler_t *p_announce;

    p_announce = vlc_object_create( p_this, VLC_OBJECT_ANNOUNCE );

    if( !p_announce )
    {
        msg_Err( p_this, "out of memory" );
        return NULL;
    }

    p_announce->p_sap = NULL;

    vlc_object_attach( p_announce, p_this->p_vlc);


    return p_announce;
}
예제 #14
0
/*****************************************************************************
 * Open: initialize and create window
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    vlc_value_t lockval;

    /* FIXME: put this in the module (de)initialization ASAP */
    var_Create( p_this->p_libvlc, "gtk", VLC_VAR_MUTEX );

    var_Get( p_this->p_libvlc, "gtk", &lockval );
    vlc_mutex_lock( lockval.p_address );

    if( i_refcount > 0 )
    {
        i_refcount++;
        vlc_mutex_unlock( lockval.p_address );

        return VLC_SUCCESS;
    }

    p_gtk_main = vlc_object_create( p_this, VLC_OBJECT_GENERIC );

    /* Only initialize gthreads if it's the first time we do it */
    if( !g_thread_supported() )
    {
        g_thread_init( NULL );
    }

    /* Launch the gtk_main() thread. It will not return until it has
     * called gdk_threads_enter(), which ensures us thread safety. */
    if( vlc_thread_create( p_gtk_main, "gtk_main", GtkMain,
                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
    {
        vlc_object_destroy( p_gtk_main );
        i_refcount--;
        vlc_mutex_unlock( lockval.p_address );
        var_Destroy( p_this->p_libvlc, "gtk" );
        return VLC_ETHREAD;
    }

    i_refcount++;
    vlc_mutex_unlock( lockval.p_address );

    return VLC_SUCCESS;
}
예제 #15
0
파일: loadsave.c 프로젝트: IAPark/vlc
int playlist_Import( playlist_t *p_playlist, const char *psz_file )
{
    input_item_t *p_input;
    char *psz_uri = vlc_path2uri( psz_file, NULL );

    if( psz_uri == NULL )
        return VLC_EGENERIC;

    p_input = input_item_New( psz_uri, psz_file );
    free( psz_uri );

    playlist_AddInput( p_playlist, p_input, false, true );

    vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof (*dummy) );
    var_Create( dummy, "meta-file", VLC_VAR_VOID );

    int ret = input_Read( dummy, p_input );

    vlc_object_release( dummy );
    return ret;
}
예제 #16
0
/**
 * Create the interface, and prepare it for main loop.
 *
 * \param p_this the calling vlc_object_t
 * \param psz_module a preferred interface module
 * \return a pointer to the created interface thread, NULL on error
 */
intf_thread_t* __intf_Create( vlc_object_t *p_this, const char *psz_module )
{
    intf_thread_t * p_intf;

    /* Allocate structure */
    p_intf = vlc_object_create( p_this, VLC_OBJECT_INTF );
    if( !p_intf )
        return NULL;
    p_intf->b_interaction = false;
#if defined( __APPLE__ ) || defined( WIN32 )
    p_intf->b_should_run_on_first_thread = false;
#endif

    /* Choose the best module */
    p_intf->psz_intf = strdup( psz_module );
    p_intf->p_module = module_Need( p_intf, "interface", psz_module, false );

    if( p_intf->p_module == NULL )
    {
        msg_Err( p_intf, "no suitable interface module" );
        free( p_intf->psz_intf );
        vlc_object_release( p_intf );
        return NULL;
    }

    /* Initialize structure */
    p_intf->b_menu        = false;
    p_intf->b_menu_change = false;

    /* Initialize mutexes */
    vlc_mutex_init( &p_intf->change_lock );

    /* Attach interface to its parent object */
    vlc_object_attach( p_intf, p_this );
    vlc_object_set_destructor( p_intf, intf_Destroy );

    return p_intf;
}
예제 #17
0
파일: gain.c 프로젝트: 12307/VLC-for-VS2010
static int Open( vlc_object_t *p_this )
{
    filter_t *p_filter = (filter_t *)p_this;
    filter_sys_t *p_sys = (filter_sys_t *)vlc_object_create( p_this, sizeof( *p_sys ) );			// sunqueen modify
    if( unlikely( p_sys == NULL ) )
        return VLC_ENOMEM;

    p_filter->p_sys = p_sys;
    p_sys->volume.format = p_filter->fmt_in.audio.i_format;
    p_sys->module = module_need( &p_sys->volume, "audio volume", NULL, false );
    if( p_sys->module == NULL )
    {
        msg_Warn( p_filter, "unsupported format" );
        vlc_object_release( &p_sys->volume );
        return VLC_EGENERIC;
    }

    p_sys->f_gain = var_InheritFloat( p_filter->p_parent, "gain-value" );
    msg_Dbg( p_filter, "gain multiplier sets to %.2fx", p_sys->f_gain );

    p_filter->fmt_out.audio = p_filter->fmt_in.audio;
    p_filter->pf_audio_filter = Process;
    return VLC_SUCCESS;
}
예제 #18
0
/*****************************************************************************
 * Dummy: used by stress-test, creates objects and then do nothing.
 *****************************************************************************/
static void * Dummy( vlc_object_t *p_this )
{
    int i;
    vlc_object_t *pp_objects[MAXOBJ/MAXTH];

    for( i = 0; i < MAXOBJ/MAXTH; i++ )
    {
        pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
    }

    vlc_thread_ready( p_this );

    while( !p_this->b_die )
    {
        msleep( 10000 );
    }

    for( i = MAXOBJ/MAXTH; i--; )
    {
        vlc_object_destroy( pp_objects[i] );
    }

    return NULL;
}
예제 #19
0
파일: instance.c 프로젝트: videolan/vlc
/**
 * Creates a Vulkan surface (and its underlying instance).
 *
 * @param wnd window to use as Vulkan surface
 * @param name module name (or NULL for auto)
 * @return a new context, or NULL on failure
 */
vlc_vk_t *vlc_vk_Create(struct vout_window_t *wnd, const char *name)
{
    vlc_object_t *parent = (vlc_object_t *) wnd;
    struct vlc_vk_t *vk;

    vk = vlc_object_create(parent, sizeof (*vk));
    if (unlikely(vk == NULL))
        return NULL;

    vk->ctx = NULL;
    vk->instance = NULL;
    vk->surface = (VkSurfaceKHR) NULL;

    vk->window = wnd;
    vk->module = module_need(vk, "vulkan", name, true);
    if (vk->module == NULL)
    {
        vlc_object_delete(vk);
        return NULL;
    }
    vlc_atomic_rc_init(&vk->ref_count);

    return vk;
}
예제 #20
0
파일: scaletempo.c 프로젝트: IAPark/vlc
static filter_t *ResamplerCreate(filter_t *p_filter)
{
    filter_t *p_resampler = vlc_object_create( p_filter, sizeof (filter_t) );
    if( unlikely( p_resampler == NULL ) )
        return NULL;

    p_resampler->owner.sys = NULL;
    p_resampler->p_cfg = NULL;
    p_resampler->fmt_in = p_filter->fmt_in;
    p_resampler->fmt_out = p_filter->fmt_in;
    p_resampler->fmt_out.audio.i_rate =
        vlc_atomic_load_float( &p_filter->p_sys->rate_shift );
    aout_FormatPrepare( &p_resampler->fmt_out.audio );
    p_resampler->p_module = module_need( p_resampler, "audio resampler", NULL,
                                         false );

    if( p_resampler->p_module == NULL )
    {
        msg_Err( p_filter, "Could not load resampler" );
        vlc_object_release( p_resampler );
        return NULL;
    }
    return p_resampler;
}
예제 #21
0
파일: rtmp.c 프로젝트: banketree/faplayer
/*****************************************************************************
 * Open: open the rtmp connection
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_access_out_t *p_access = (sout_access_out_t *) p_this;
    sout_access_out_sys_t *p_sys;
    char *psz, *p;
    int length_path, length_media_name;
    int i;

    if( !( p_sys = calloc ( 1, sizeof( sout_access_out_sys_t ) ) ) )
        return VLC_ENOMEM;
    p_access->p_sys = p_sys;

    p_sys->p_thread =
        vlc_object_create( p_access, sizeof( rtmp_control_thread_t ) );
    if( !p_sys->p_thread )
    {
        free( p_sys );
        return VLC_ENOMEM;
    }
    vlc_object_attach( p_sys->p_thread, p_access );

    /* Parse URI - remove spaces */
    p = psz = strdup( p_access->psz_path );
    while( ( p = strchr( p, ' ' ) ) != NULL )
        *p = '+';
    vlc_UrlParse( &p_sys->p_thread->url, psz, 0 );
    free( psz );

    if( p_sys->p_thread->url.psz_host == NULL
        || *p_sys->p_thread->url.psz_host == '\0' )
    {
         msg_Warn( p_access, "invalid host" );
         goto error;
    }

    if( p_sys->p_thread->url.i_port <= 0 )
        p_sys->p_thread->url.i_port = 1935;

    if ( p_sys->p_thread->url.psz_path == NULL )
    {
        msg_Warn( p_access, "invalid path" );
        goto error;
    }

    length_path = strlen( p_sys->p_thread->url.psz_path );
    char* psz_tmp = strrchr( p_sys->p_thread->url.psz_path, '/' );
    if( !psz_tmp )
        goto error;
    length_media_name = strlen( psz_tmp ) - 1;

    p_sys->p_thread->psz_application = strndup( p_sys->p_thread->url.psz_path + 1, length_path - length_media_name - 2 );
    p_sys->p_thread->psz_media = strdup( p_sys->p_thread->url.psz_path + ( length_path - length_media_name ) );

    msg_Dbg( p_access, "rtmp: host='%s' port=%d path='%s'",
             p_sys->p_thread->url.psz_host, p_sys->p_thread->url.i_port, p_sys->p_thread->url.psz_path );

    if( p_sys->p_thread->url.psz_username && *p_sys->p_thread->url.psz_username )
    {
        msg_Dbg( p_access, "      user='******'", p_sys->p_thread->url.psz_username );
    }

    /* Initialize thread variables */
    p_sys->p_thread->b_error= 0;
    p_sys->p_thread->p_fifo_input = block_FifoNew();
    p_sys->p_thread->p_empty_blocks = block_FifoNew();
    p_sys->p_thread->has_audio = 0;
    p_sys->p_thread->has_video = 0;
    p_sys->p_thread->metadata_received = 0;
    p_sys->p_thread->first_media_packet = 1;
    p_sys->p_thread->flv_tag_previous_tag_size = 0x00000000; /* FLV_TAG_FIRST_PREVIOUS_TAG_SIZE */

    p_sys->p_thread->flv_body = rtmp_body_new( -1 );
    p_sys->p_thread->flv_length_body = 0;

    p_sys->p_thread->chunk_size_recv = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
    p_sys->p_thread->chunk_size_send = 128; /* RTMP_DEFAULT_CHUNK_SIZE */
    for(i = 0; i < 64; i++)
    {
        memset( &p_sys->p_thread->rtmp_headers_recv[i], 0, sizeof( rtmp_packet_t ) );
        p_sys->p_thread->rtmp_headers_send[i].length_header = -1;
        p_sys->p_thread->rtmp_headers_send[i].stream_index = -1;
        p_sys->p_thread->rtmp_headers_send[i].timestamp = -1;
        p_sys->p_thread->rtmp_headers_send[i].timestamp_relative = -1;
        p_sys->p_thread->rtmp_headers_send[i].length_encoded = -1;
        p_sys->p_thread->rtmp_headers_send[i].length_body = -1;
        p_sys->p_thread->rtmp_headers_send[i].content_type = -1;
        p_sys->p_thread->rtmp_headers_send[i].src_dst = -1;
        p_sys->p_thread->rtmp_headers_send[i].body = NULL;
    }

    vlc_cond_init( &p_sys->p_thread->wait );
    vlc_mutex_init( &p_sys->p_thread->lock );

    p_sys->p_thread->result_connect = 1;
    /* p_sys->p_thread->result_publish = only used on access */
    p_sys->p_thread->result_play = 1;
    p_sys->p_thread->result_stop = 0;
    p_sys->p_thread->fd = -1;

    /* Open connection */
    if( var_CreateGetBool( p_access, "rtmp-connect" ) > 0 )
    {
#if 0
        p_sys->p_thread->fd = net_ConnectTCP( p_access,
                                              p_sys->p_thread->url.psz_host,
                                              p_sys->p_thread->url.i_port );
#endif
        msg_Err( p_access, "to be implemented" );
        goto error2;
    }
    else
    {
        int *p_fd_listen;

        p_sys->active = 0;
        p_fd_listen = net_ListenTCP( p_access, p_sys->p_thread->url.psz_host,
                                     p_sys->p_thread->url.i_port );
        if( p_fd_listen == NULL )
        {
            msg_Warn( p_access, "cannot listen to %s port %i",
                      p_sys->p_thread->url.psz_host,
                      p_sys->p_thread->url.i_port );
            goto error2;
        }

        do
            p_sys->p_thread->fd = net_Accept( p_access, p_fd_listen );
        while( p_sys->p_thread->fd == -1 );
        net_ListenClose( p_fd_listen );

        if( rtmp_handshake_passive( p_this, p_sys->p_thread->fd ) < 0 )
        {
            msg_Err( p_access, "handshake passive failed");
            goto error2;
        }
    }

    if( vlc_clone( &p_sys->p_thread->thread, ThreadControl, p_sys->p_thread,
                   VLC_THREAD_PRIORITY_INPUT ) )
    {
        msg_Err( p_access, "cannot spawn rtmp control thread" );
        goto error2;
    }

    if( !p_sys->active )
    {
        if( rtmp_connect_passive( p_sys->p_thread ) < 0 )
        {
            msg_Err( p_access, "connect passive failed");
            vlc_cancel( p_sys->p_thread->thread );
            vlc_join( p_sys->p_thread->thread, NULL );
            goto error2;
        }
    }

    p_access->pf_write = Write;
    p_access->pf_seek = Seek;

    return VLC_SUCCESS;

error2:
    vlc_cond_destroy( &p_sys->p_thread->wait );
    vlc_mutex_destroy( &p_sys->p_thread->lock );

    free( p_sys->p_thread->psz_application );
    free( p_sys->p_thread->psz_media );

    if( p_sys->p_thread->fd != -1 )
        net_Close( p_sys->p_thread->fd );
error:
    vlc_UrlClean( &p_sys->p_thread->url );
    vlc_object_release( p_sys->p_thread );
    free( p_sys );

    return VLC_EGENERIC;
}
예제 #22
0
/**************************************************************************
 * Create a Media Instance object.
 *
 * Refcount strategy:
 * - All items created by _new start with a refcount set to 1.
 * - Accessor _release decrease the refcount by 1, if after that
 *   operation the refcount is 0, the object is destroyed.
 * - Accessor _retain increase the refcount by 1 (XXX: to implement)
 *
 * Object locking strategy:
 * - No lock held while in constructor.
 * - When accessing any member variable this lock is held. (XXX who locks?)
 * - When attempting to destroy the object the lock is also held.
 **************************************************************************/
libvlc_media_player_t *
libvlc_media_player_new( libvlc_instance_t *instance )
{
    libvlc_media_player_t * mp;

    assert(instance);

    mp = vlc_object_create (instance->p_libvlc_int, sizeof(*mp));
    if (unlikely(mp == NULL))
    {
        libvlc_printerr("Not enough memory");
        return NULL;
    }

    /* Input */
    var_Create (mp, "rate", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT);

    /* Video */
    var_Create (mp, "vout", VLC_VAR_STRING|VLC_VAR_DOINHERIT);
    var_Create (mp, "window", VLC_VAR_STRING);
    var_Create (mp, "vmem-lock", VLC_VAR_ADDRESS);
    var_Create (mp, "vmem-unlock", VLC_VAR_ADDRESS);
    var_Create (mp, "vmem-display", VLC_VAR_ADDRESS);
    var_Create (mp, "vmem-data", VLC_VAR_ADDRESS);
    var_Create (mp, "vmem-setup", VLC_VAR_ADDRESS);
    var_Create (mp, "vmem-cleanup", VLC_VAR_ADDRESS);
    var_Create (mp, "vmem-chroma", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
    var_Create (mp, "vmem-width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "vmem-height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "vmem-pitch", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "avcodec-hw", VLC_VAR_STRING);
    var_Create (mp, "drawable-xid", VLC_VAR_INTEGER);
#if defined (_WIN32) || defined (__OS2__)
    var_Create (mp, "drawable-hwnd", VLC_VAR_INTEGER);
#endif
#ifdef __APPLE__
    var_Create (mp, "drawable-agl", VLC_VAR_INTEGER);
    var_Create (mp, "drawable-nsobject", VLC_VAR_ADDRESS);
#endif

    var_Create (mp, "keyboard-events", VLC_VAR_BOOL);
    var_SetBool (mp, "keyboard-events", true);
    var_Create (mp, "mouse-events", VLC_VAR_BOOL);
    var_SetBool (mp, "mouse-events", true);

    var_Create (mp, "fullscreen", VLC_VAR_BOOL);
    var_Create (mp, "autoscale", VLC_VAR_BOOL);
    var_SetBool (mp, "autoscale", true);
    var_Create (mp, "scale", VLC_VAR_FLOAT);
    var_SetFloat (mp, "scale", 1.);
    var_Create (mp, "aspect-ratio", VLC_VAR_STRING);
    var_Create (mp, "crop", VLC_VAR_STRING);
    var_Create (mp, "deinterlace", VLC_VAR_INTEGER);
    var_Create (mp, "deinterlace-mode", VLC_VAR_STRING);

    var_Create (mp, "vbi-page", VLC_VAR_INTEGER);

    var_Create (mp, "marq-marquee", VLC_VAR_STRING);
    var_Create (mp, "marq-color", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "marq-opacity", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "marq-position", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "marq-refresh", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "marq-size", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "marq-timeout", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "marq-x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "marq-y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);

    var_Create (mp, "logo-file", VLC_VAR_STRING);
    var_Create (mp, "logo-x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "logo-y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "logo-delay", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "logo-repeat", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "logo-opacity", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "logo-position", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);

    var_Create (mp, "contrast", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
    var_Create (mp, "brightness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
    var_Create (mp, "hue", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "saturation", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
    var_Create (mp, "gamma", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);

     /* Audio */
    var_Create (mp, "aout", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
    var_Create (mp, "mute", VLC_VAR_BOOL);
    var_Create (mp, "volume", VLC_VAR_FLOAT);
    var_Create (mp, "corks", VLC_VAR_INTEGER);
    var_Create (mp, "audio-filter", VLC_VAR_STRING);
    var_Create (mp, "amem-data", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-setup", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-cleanup", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-play", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-pause", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-resume", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-flush", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-drain", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-set-volume", VLC_VAR_ADDRESS);
    var_Create (mp, "amem-format", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
    var_Create (mp, "amem-rate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
    var_Create (mp, "amem-channels", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);

    /* Video Title */
    var_Create (mp, "video-title-show", VLC_VAR_BOOL);
    var_Create (mp, "video-title-position", VLC_VAR_INTEGER);
    var_Create (mp, "video-title-timeout", VLC_VAR_INTEGER);

    /* Equalizer */
    var_Create (mp, "equalizer-preamp", VLC_VAR_FLOAT);
    var_Create (mp, "equalizer-vlcfreqs", VLC_VAR_BOOL);
    var_Create (mp, "equalizer-bands", VLC_VAR_STRING);

    mp->p_md = NULL;
    mp->state = libvlc_NothingSpecial;
    mp->p_libvlc_instance = instance;
    mp->input.p_thread = NULL;
    mp->input.p_resource = input_resource_New(VLC_OBJECT(mp));
    if (unlikely(mp->input.p_resource == NULL))
    {
        vlc_object_release(mp);
        return NULL;
    }
    audio_output_t *aout = input_resource_GetAout(mp->input.p_resource);
    if( aout != NULL )
        input_resource_PutAout(mp->input.p_resource, aout);

    vlc_mutex_init (&mp->input.lock);
    mp->i_refcount = 1;
    mp->p_event_manager = libvlc_event_manager_new(mp, instance);
    if (unlikely(mp->p_event_manager == NULL))
    {
        input_resource_Release(mp->input.p_resource);
        vlc_object_release(mp);
        return NULL;
    }
    vlc_mutex_init(&mp->object_lock);

    register_event(mp, NothingSpecial);
    register_event(mp, Opening);
    register_event(mp, Buffering);
    register_event(mp, Playing);
    register_event(mp, Paused);
    register_event(mp, Stopped);
    register_event(mp, Forward);
    register_event(mp, Backward);
    register_event(mp, EndReached);
    register_event(mp, EncounteredError);
    register_event(mp, SeekableChanged);

    register_event(mp, PositionChanged);
    register_event(mp, TimeChanged);
    register_event(mp, LengthChanged);
    register_event(mp, TitleChanged);
    register_event(mp, PausableChanged);

    register_event(mp, Vout);
    register_event(mp, ScrambledChanged);

    /* Snapshot initialization */
    register_event(mp, SnapshotTaken);

    register_event(mp, MediaChanged);

    /* Attach a var callback to the global object to provide the glue between
     * vout_thread that generates the event and media_player that re-emits it
     * with its own event manager
     *
     * FIXME: It's unclear why we want to put this in public API, and why we
     * want to expose it in such a limiting and ugly way.
     */
    var_AddCallback(mp->p_libvlc, "snapshot-file", snapshot_was_taken, mp);

    libvlc_retain(instance);
    return mp;
}
예제 #23
0
파일: mpgv.c 프로젝트: forthyen/SDesk
/*****************************************************************************
 * Open: initializes demux structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;
    vlc_bool_t   b_forced = VLC_FALSE;

    uint8_t     *p_peek;

    es_format_t  fmt;

    if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
    {
        msg_Err( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }

    if( !strncmp( p_demux->psz_demux, "mpgv", 4 ) )
    {
        b_forced = VLC_TRUE;
    }

    if( p_peek[0] != 0x00 || p_peek[1] != 0x00 || p_peek[2] != 0x01 )
    {
        if( !b_forced )
        {
            msg_Warn( p_demux, "ES module discarded (no startcode)" );
            return VLC_EGENERIC;
        }

        msg_Err( p_demux, "this doesn't look like an MPEG ES stream, continuing" );
    }

    if( p_peek[3] > 0xb9 )
    {
        if( !b_forced )
        {
            msg_Warn( p_demux, "ES module discarded (system startcode)" );
            return VLC_EGENERIC;
        }
        msg_Err( p_demux, "this seems to be a system stream (PS plug-in ?), but continuing" );
    }

    p_demux->pf_demux  = Demux;
    p_demux->pf_control= Control;
    p_demux->p_sys     = p_sys = malloc( sizeof( demux_sys_t ) );
    p_sys->b_start     = VLC_TRUE;
    p_sys->p_es        = NULL;

    /*
     * Load the mpegvideo packetizer
     */
    p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
    p_sys->p_packetizer->pf_decode_audio = NULL;
    p_sys->p_packetizer->pf_decode_video = NULL;
    p_sys->p_packetizer->pf_decode_sub = NULL;
    p_sys->p_packetizer->pf_packetize = NULL;
    es_format_Init( &p_sys->p_packetizer->fmt_in, VIDEO_ES,
                    VLC_FOURCC( 'm', 'p', 'g', 'v' ) );
    es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
    p_sys->p_packetizer->p_module =
        module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );

    if( p_sys->p_packetizer->p_module == NULL)
    {
        vlc_object_destroy( p_sys->p_packetizer );
        msg_Err( p_demux, "cannot find mpgv packetizer" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /*
     * create the output
     */
    es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) );
    p_sys->p_es = es_out_Add( p_demux->out, &fmt );

    return VLC_SUCCESS;
}
예제 #24
0
static sout_stream_id_sys_t * Add( sout_stream_t *p_stream, const es_format_t *p_fmt )
{
    sout_stream_sys_t *p_sys = p_stream->p_sys;
    bridge_t *p_bridge;
    bridged_es_t *p_es;
    char *psz_chain;
    int i;

    if( p_sys->b_inited || p_fmt->i_cat != VIDEO_ES )
        return NULL;

    /* Create decoder object */
    p_sys->p_decoder = vlc_object_create( p_stream, sizeof( decoder_t ) );
    if( !p_sys->p_decoder )
        return NULL;
    p_sys->p_decoder->p_module = NULL;
    p_sys->p_decoder->fmt_in = *p_fmt;
    p_sys->p_decoder->b_frame_drop_allowed = true;
    p_sys->p_decoder->fmt_out = p_sys->p_decoder->fmt_in;
    p_sys->p_decoder->fmt_out.i_extra = 0;
    p_sys->p_decoder->fmt_out.p_extra = 0;
    p_sys->p_decoder->pf_decode_video = 0;
    p_sys->p_decoder->pf_vout_format_update = video_update_format_decoder;
    p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder;
    p_sys->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) );
    if( !p_sys->p_decoder->p_owner )
    {
        vlc_object_release( p_sys->p_decoder );
        return NULL;
    }

    p_sys->p_decoder->p_owner->video = p_fmt->video;
    //p_sys->p_decoder->p_cfg = p_sys->p_video_cfg;

    p_sys->p_decoder->p_module =
        module_need( p_sys->p_decoder, "decoder", "$codec", false );

    if( !p_sys->p_decoder->p_module || !p_sys->p_decoder->pf_decode_video )
    {
        if( p_sys->p_decoder->p_module )
        {
            msg_Err( p_stream, "instanciated a non video decoder" );
            module_unneed( p_sys->p_decoder, p_sys->p_decoder->p_module );
        }
        else
        {
            msg_Err( p_stream, "cannot find decoder" );
        }
        free( p_sys->p_decoder->p_owner );
        vlc_object_release( p_sys->p_decoder );
        return NULL;
    }

    p_sys->b_inited = true;
    vlc_global_lock( VLC_MOSAIC_MUTEX );

    p_bridge = GetBridge( p_stream );
    if ( p_bridge == NULL )
    {
        vlc_object_t *p_libvlc = VLC_OBJECT( p_stream->obj.libvlc );
        vlc_value_t val;

        p_bridge = xmalloc( sizeof( bridge_t ) );

        var_Create( p_libvlc, "mosaic-struct", VLC_VAR_ADDRESS );
        val.p_address = p_bridge;
        var_Set( p_libvlc, "mosaic-struct", val );

        p_bridge->i_es_num = 0;
        p_bridge->pp_es = NULL;
    }

    for ( i = 0; i < p_bridge->i_es_num; i++ )
    {
        if ( p_bridge->pp_es[i]->b_empty )
            break;
    }

    if ( i == p_bridge->i_es_num )
    {
        p_bridge->pp_es = xrealloc( p_bridge->pp_es,
                          (p_bridge->i_es_num + 1) * sizeof(bridged_es_t *) );
        p_bridge->i_es_num++;
        p_bridge->pp_es[i] = xmalloc( sizeof(bridged_es_t) );
    }

    p_sys->p_es = p_es = p_bridge->pp_es[i];

    p_es->i_alpha = var_GetInteger( p_stream, CFG_PREFIX "alpha" );
    p_es->i_x = var_GetInteger( p_stream, CFG_PREFIX "x" );
    p_es->i_y = var_GetInteger( p_stream, CFG_PREFIX "y" );

    //p_es->fmt = *p_fmt;
    p_es->psz_id = p_sys->psz_id;
    p_es->p_picture = NULL;
    p_es->pp_last = &p_es->p_picture;
    p_es->b_empty = false;

    vlc_global_unlock( VLC_MOSAIC_MUTEX );

    if ( p_sys->i_height || p_sys->i_width )
    {
        p_sys->p_image = image_HandlerCreate( p_stream );
    }
    else
    {
        p_sys->p_image = NULL;
    }

    msg_Dbg( p_stream, "mosaic bridge id=%s pos=%d", p_es->psz_id, i );

    /* Create user specified video filters */
    psz_chain = var_GetNonEmptyString( p_stream, CFG_PREFIX "vfilter" );
    msg_Dbg( p_stream, "psz_chain: %s", psz_chain );
    if( psz_chain )
    {
        filter_owner_t owner = {
            .sys = p_sys->p_decoder->p_owner,
            .video = {
                .buffer_new = video_new_buffer_filter,
            },
        };

        p_sys->p_vf2 = filter_chain_NewVideo( p_stream, false, &owner );
        es_format_t fmt;
        es_format_Copy( &fmt, &p_sys->p_decoder->fmt_out );
        if( p_sys->i_chroma )
            fmt.video.i_chroma = p_sys->i_chroma;
        filter_chain_Reset( p_sys->p_vf2, &fmt, &fmt );
        filter_chain_AppendFromString( p_sys->p_vf2, psz_chain );
        free( psz_chain );
    }
    else
    {
예제 #25
0
파일: m4a.c 프로젝트: forthyen/SDesk
/*****************************************************************************
 * Open: initializes demux structures
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;
    uint8_t     *p_peek;
    module_t    *p_id3;
    int         b_forced = VLC_FALSE;

    if( p_demux->psz_path )
    {
        int i_len = strlen( p_demux->psz_path );

        if( i_len > 4 && !strcasecmp( &p_demux->psz_path[i_len - 4], ".aac" ) )
        {
            b_forced = VLC_TRUE;
        }
    }

    if( !p_demux->b_force && !b_forced )
    {
        return VLC_EGENERIC;
    }

    /* skip possible id3 header */
    if( ( p_id3 = module_Need( p_demux, "id3", NULL, 0 ) ) )
    {
        module_Unneed( p_demux, p_id3 );
    }

    /* peek the begining (10 is for adts header) */
    if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 )
    {
        msg_Err( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }
    if( !strncmp( p_peek, "ADIF", 4 ) )
    {
        msg_Err( p_demux, "ADIF file. Not yet supported. (Please report)" );
        return VLC_EGENERIC;
    }

    p_demux->pf_demux  = Demux;
    p_demux->pf_control= Control;
    p_demux->p_sys     = p_sys = malloc( sizeof( demux_sys_t ) );
    p_sys->p_es        = NULL;
    p_sys->b_start     = VLC_TRUE;

    /*
     * Load the mpeg 4 audio packetizer
     */
    p_sys->p_packetizer = vlc_object_create( p_demux, VLC_OBJECT_PACKETIZER );
    p_sys->p_packetizer->pf_decode_audio = NULL;
    p_sys->p_packetizer->pf_decode_video = NULL;
    p_sys->p_packetizer->pf_decode_sub = NULL;
    p_sys->p_packetizer->pf_packetize = NULL;
    es_format_Init( &p_sys->p_packetizer->fmt_in, AUDIO_ES,
                    VLC_FOURCC( 'm', 'p', '4', 'a' ) );
    es_format_Init( &p_sys->p_packetizer->fmt_out, UNKNOWN_ES, 0 );
    p_sys->p_packetizer->p_module =
        module_Need( p_sys->p_packetizer, "packetizer", NULL, 0 );

    if( p_sys->p_packetizer->p_module == NULL)
    {
        vlc_object_destroy( p_sys->p_packetizer );
        msg_Err( p_demux, "cannot find mp4a packetizer" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
예제 #26
0
파일: playlist.c 프로젝트: forthyen/SDesk
/**
 * Create playlist
 *
 * Create a playlist structure.
 * \param p_parent the vlc object that is to be the parent of this playlist
 * \return a pointer to the created playlist, or NULL on error
 */
playlist_t * __playlist_Create ( vlc_object_t *p_parent )
{
    playlist_t *p_playlist;
    vlc_value_t     val;

    /* Allocate structure */
    p_playlist = vlc_object_create( p_parent, VLC_OBJECT_PLAYLIST );
    if( !p_playlist )
    {
        msg_Err( p_parent, "out of memory" );
        return NULL;
    }

    var_Create( p_playlist, "intf-change", VLC_VAR_BOOL );
    val.b_bool = VLC_TRUE;
    var_Set( p_playlist, "intf-change", val );

    var_Create( p_playlist, "item-change", VLC_VAR_INTEGER );
    val.i_int = -1;
    var_Set( p_playlist, "item-change", val );

    var_Create( p_playlist, "playlist-current", VLC_VAR_INTEGER );
    val.i_int = -1;
    var_Set( p_playlist, "playlist-current", val );

    var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL );

    var_Create( p_playlist, "intf-show", VLC_VAR_BOOL );
    val.b_bool = VLC_TRUE;
    var_Set( p_playlist, "intf-show", val );


    var_Create( p_playlist, "prevent-skip", VLC_VAR_BOOL );
    val.b_bool = VLC_FALSE;
    var_Set( p_playlist, "prevent-skip", val );

    var_Create( p_playlist, "play-and-stop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_playlist, "random", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_playlist, "repeat", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
    var_Create( p_playlist, "loop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );

    p_playlist->p_input = NULL;
    p_playlist->i_status = PLAYLIST_STOPPED;
    p_playlist->i_index = -1;
    p_playlist->i_size = 0;
    p_playlist->pp_items = NULL;

    p_playlist->i_groups = 0;
    p_playlist->pp_groups = NULL;
    p_playlist->i_last_group = 0;
    p_playlist->i_last_id = 0;
    p_playlist->i_sort = SORT_ID;
    p_playlist->i_order = ORDER_NORMAL;

    playlist_CreateGroup( p_playlist, _("Normal") );

    if( vlc_thread_create( p_playlist, "playlist", RunThread,
                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
    {
        msg_Err( p_playlist, "cannot spawn playlist thread" );
        vlc_object_destroy( p_playlist );
        return NULL;
    }

    /* The object has been initialized, now attach it */
    vlc_object_attach( p_playlist, p_parent );

    return p_playlist;
}
예제 #27
0
파일: logo.c 프로젝트: forthyen/SDesk
/*****************************************************************************
 * Init: initialize logo video thread output method
 *****************************************************************************/
static int Init( vout_thread_t *p_vout )
{
    vout_sys_t *p_sys = p_vout->p_sys;
    picture_t *p_pic;
    int i_index;

    I_OUTPUTPICTURES = 0;

    /* Initialize the output structure */
    p_vout->output.i_chroma = p_vout->render.i_chroma;
    p_vout->output.i_width  = p_vout->render.i_width;
    p_vout->output.i_height = p_vout->render.i_height;
    p_vout->output.i_aspect = p_vout->render.i_aspect;

    /* Load the video blending filter */
    p_sys->p_blend = vlc_object_create( p_vout, sizeof(filter_t) );
    vlc_object_attach( p_sys->p_blend, p_vout );
    p_sys->p_blend->fmt_out.video.i_x_offset =
        p_sys->p_blend->fmt_out.video.i_y_offset = 0;
    p_sys->p_blend->fmt_in.video.i_x_offset =
        p_sys->p_blend->fmt_in.video.i_y_offset = 0;
    p_sys->p_blend->fmt_out.video.i_aspect = p_vout->render.i_aspect;
    p_sys->p_blend->fmt_out.video.i_chroma = p_vout->output.i_chroma;
    p_sys->p_blend->fmt_in.video.i_chroma = VLC_FOURCC('Y','U','V','A');
    p_sys->p_blend->fmt_in.video.i_aspect = VOUT_ASPECT_FACTOR;
    p_sys->p_blend->fmt_in.video.i_width =
        p_sys->p_blend->fmt_in.video.i_visible_width =
            p_sys->p_pic->p[Y_PLANE].i_visible_pitch;
    p_sys->p_blend->fmt_in.video.i_height =
        p_sys->p_blend->fmt_in.video.i_visible_height =
            p_sys->p_pic->p[Y_PLANE].i_visible_lines;
    p_sys->p_blend->fmt_out.video.i_width =
        p_sys->p_blend->fmt_out.video.i_visible_width =
           p_vout->output.i_width;
    p_sys->p_blend->fmt_out.video.i_height =
        p_sys->p_blend->fmt_out.video.i_visible_height =
            p_vout->output.i_height;

    p_sys->p_blend->p_module =
        module_Need( p_sys->p_blend, "video blending", 0, 0 );
    if( !p_sys->p_blend->p_module )
    {
        msg_Err( p_vout, "can't open blending filter, aborting" );
        vlc_object_detach( p_sys->p_blend );
        vlc_object_destroy( p_sys->p_blend );
        return VLC_EGENERIC;
    }

    if( p_sys->posx < 0 || p_sys->posy < 0 )
    {
        p_sys->posx = 0; p_sys->posy = 0;

        if( p_sys->pos & SUBPICTURE_ALIGN_BOTTOM )
        {
            p_sys->posy = p_vout->render.i_height - p_sys->i_height;
        }
        else if ( !(p_sys->pos & SUBPICTURE_ALIGN_TOP) )
        {
            p_sys->posy = p_vout->render.i_height / 2 - p_sys->i_height / 2;
        }

        if( p_sys->pos & SUBPICTURE_ALIGN_RIGHT )
        {
            p_sys->posx = p_vout->render.i_width - p_sys->i_width;
        }
        else if ( !(p_sys->pos & SUBPICTURE_ALIGN_LEFT) )
        {
            p_sys->posx = p_vout->render.i_width / 2 - p_sys->i_width / 2;
        }
    }

    /* Try to open the real video output */
    msg_Dbg( p_vout, "spawning the real video output" );

    p_sys->p_vout =
        vout_Create( p_vout, p_vout->render.i_width, p_vout->render.i_height,
                     p_vout->render.i_chroma, p_vout->render.i_aspect );

    /* Everything failed */
    if( p_sys->p_vout == NULL )
    {
        msg_Err( p_vout, "can't open vout, aborting" );
        return VLC_EGENERIC;
    }

    var_AddCallback( p_sys->p_vout, "mouse-x", MouseEvent, p_vout);
    var_AddCallback( p_sys->p_vout, "mouse-y", MouseEvent, p_vout);

    ALLOCATE_DIRECTBUFFERS( VOUT_MAX_PICTURES );
    ADD_CALLBACKS( p_sys->p_vout, SendEvents );
    ADD_PARENT_CALLBACKS( SendEventsToChild );

    return VLC_SUCCESS;
}
예제 #28
0
/**
 * ProjectM update thread which do the rendering
 * @param p_this: the p_thread object
 */
static void *Thread( void *p_data )
{
    filter_t  *p_filter = (filter_t*)p_data;
    filter_sys_t *p_sys = p_filter->p_sys;

    video_format_t fmt;
    vlc_gl_t *gl;
    unsigned int i_last_width  = 0;
    unsigned int i_last_height = 0;
    locale_t loc;
    locale_t oldloc;

    projectM *p_projectm;
#ifndef HAVE_PROJECTM2
    char *psz_config;
#else
    char *psz_preset_path;
    char *psz_title_font;
    char *psz_menu_font;
    projectM::Settings settings;
#endif

    vlc_savecancel();

    /* Create the openGL provider */
    p_sys->p_vout =
        (vout_thread_t *)vlc_object_create( p_filter, sizeof(vout_thread_t) );
    if( !p_sys->p_vout )
        goto error;

    /* */
    video_format_Init( &fmt, 0 );
    video_format_Setup( &fmt, VLC_CODEC_RGB32,
                        p_sys->i_width, p_sys->i_height, 0, 1 );
    fmt.i_sar_num = 1;
    fmt.i_sar_den = 1;

    vout_display_state_t state;
    memset( &state, 0, sizeof(state) );
    state.cfg.display.sar.num = 1;
    state.cfg.display.sar.den = 1;
    state.cfg.is_display_filled = true;
    state.cfg.zoom.num = 1;
    state.cfg.zoom.den = 1;
    state.sar.num = 1;
    state.sar.den = 1;

    p_sys->p_vd = vout_NewDisplay( p_sys->p_vout, &fmt, &state, "opengl",
                                   300000, 1000000 );
    if( !p_sys->p_vd )
    {
        vlc_object_release( p_sys->p_vout );
        goto error;
    }
    var_Create( p_sys->p_vout, "fullscreen", VLC_VAR_BOOL );
    var_AddCallback( p_sys->p_vout, "fullscreen", VoutCallback, p_sys->p_vd );

    gl = vout_GetDisplayOpengl( p_sys->p_vd );
    if( !gl )
    {
        vout_DeleteDisplay( p_sys->p_vd, NULL );
        vlc_object_release( p_sys->p_vout );
        goto error;
    }

    /* Work-around the projectM locale bug */
    loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
    oldloc = uselocale (loc);

    /* Create the projectM object */
#ifndef HAVE_PROJECTM2
    psz_config = var_InheritString( p_filter, "projectm-config" );
    p_projectm = new projectM( psz_config );
    free( psz_config );
#else
    psz_preset_path = var_InheritString( p_filter, "projectm-preset-path" );
#ifdef WIN32
    if ( psz_preset_path == NULL )
    {
        char *psz_data_path = config_GetDataDir( p_filter );
        asprintf( &psz_preset_path, "%s" DIR_SEP "visualization", psz_data_path );
        free( psz_data_path );
    }
#endif

    psz_title_font                = var_InheritString( p_filter, "projectm-title-font" );
    psz_menu_font                 = var_InheritString( p_filter, "projectm-menu-font" );

    settings.meshX                = var_InheritInteger( p_filter, "projectm-meshx" );
    settings.meshY                = var_InheritInteger( p_filter, "projectm-meshy" );
    settings.fps                  = 35;
    settings.textureSize          = var_InheritInteger( p_filter, "projectm-texture-size" );
    settings.windowWidth          = p_sys->i_width;
    settings.windowHeight         = p_sys->i_height;
    settings.presetURL            = psz_preset_path;
    settings.titleFontURL         = psz_title_font;
    settings.menuFontURL          = psz_menu_font;
    settings.smoothPresetDuration = 5;
    settings.presetDuration       = 30;
    settings.beatSensitivity      = 10;
    settings.aspectCorrection     = 1;
    settings.easterEgg            = 1;
    settings.shuffleEnabled       = 1;

    p_projectm = new projectM( settings );

    free( psz_menu_font );
    free( psz_title_font );
    free( psz_preset_path );
#endif /* HAVE_PROJECTM2 */

    p_sys->i_buffer_size = p_projectm->pcm()->maxsamples;
    p_sys->p_buffer = (float*)calloc( p_sys->i_buffer_size,
                                      sizeof( float ) );

    vlc_sem_post( &p_sys->ready );

    /* Choose a preset randomly or projectM will always show the first one */
    if ( p_projectm->getPlaylistSize() > 0 )
        p_projectm->selectPreset( (unsigned)vlc_mrand48() % p_projectm->getPlaylistSize() );

    /* */
    for( ;; )
    {
        const mtime_t i_deadline = mdate() + CLOCK_FREQ / 50; /* 50 fps max */
        /* Manage the events */
        vout_ManageDisplay( p_sys->p_vd, true );
        if( p_sys->p_vd->cfg->display.width  != i_last_width ||
            p_sys->p_vd->cfg->display.height != i_last_height )
        {
            /* FIXME it is not perfect as we will have black bands */
            vout_display_place_t place;
            vout_display_PlacePicture( &place, &p_sys->p_vd->source, p_sys->p_vd->cfg, false );
            p_projectm->projectM_resetGL( place.width, place.height );

            i_last_width  = p_sys->p_vd->cfg->display.width;
            i_last_height = p_sys->p_vd->cfg->display.height;
        }

        /* Render the image and swap the buffers */
        vlc_mutex_lock( &p_sys->lock );
        if( p_sys->i_nb_samples > 0 )
        {
            p_projectm->pcm()->addPCMfloat( p_sys->p_buffer,
                                            p_sys->i_nb_samples );
            p_sys->i_nb_samples = 0;
        }
        if( p_sys->b_quit )
        {
            vlc_mutex_unlock( &p_sys->lock );

            delete p_projectm;
            vout_DeleteDisplay( p_sys->p_vd, NULL );
            vlc_object_release( p_sys->p_vout );
            if (loc != (locale_t)0)
            {
                uselocale (oldloc);
                freelocale (loc);
            }
            return NULL;
        }
        vlc_mutex_unlock( &p_sys->lock );

        p_projectm->renderFrame();

        /* */
        mwait( i_deadline );

        if( !vlc_gl_Lock(gl) )
        {
            vlc_gl_Swap( gl );
            vlc_gl_Unlock( gl );
        }
    }
    abort();

error:
    p_sys->b_error = true;
    vlc_sem_post( &p_sys->ready );
    return NULL;
}
예제 #29
0
/**
 * It creates an OpenGL vout display.
 */
static int Open(vlc_object_t *object)
{
    vout_display_t *vd = (vout_display_t *)object;
    vout_display_sys_t *sys;

    /* Allocate structure */
    vd->sys = sys = calloc(1, sizeof(*sys));
    if (!sys)
        return VLC_ENOMEM;

    /* */
    if (CommonInit(vd))
        goto error;

    EventThreadUpdateTitle(sys->event, VOUT_TITLE " (OpenGL output)");

    /* process selected GPU affinity */
    int nVidiaAffinity = var_InheritInteger(vd, "gpu-affinity");
    if (nVidiaAffinity >= 0) CreateGPUAffinityDC(vd, nVidiaAffinity);

    /* */
    sys->hGLDC = GetDC(sys->hvideownd);

    /* Set the pixel format for the DC */
    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    SetPixelFormat(sys->hGLDC,
                   ChoosePixelFormat(sys->hGLDC, &pfd), &pfd);

    /*
     * Create and enable the render context
     * For GPU affinity, attach the window DC
     * to the GPU affinity DC
     */
    sys->hGLRC = wglCreateContext((sys->affinityHDC != NULL) ? sys->affinityHDC : sys->hGLDC);
    wglMakeCurrent(sys->hGLDC, sys->hGLRC);

    const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
#ifdef WGL_EXT_swap_control
    if (HasExtension(extensions, "WGL_EXT_swap_control")) {
        PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
        if (SwapIntervalEXT)
            SwapIntervalEXT(1);
    }
#endif

    /* */
    sys->gl = vlc_object_create(object, sizeof(*sys->gl));

    if (unlikely(!sys->gl))
        goto error;

    sys->gl->swap = Swap;
    sys->gl->getProcAddress = OurGetProcAddress;
    sys->gl->sys = vd;

    video_format_t fmt = vd->fmt;
    const vlc_fourcc_t *subpicture_chromas;
    sys->vgl = vout_display_opengl_New(&fmt, &subpicture_chromas, sys->gl,
                                       &vd->cfg->viewpoint);
    if (!sys->vgl)
        goto error;

    vout_display_info_t info = vd->info;
    info.has_double_click = true;
    info.has_hide_mouse = false;
    info.subpicture_chromas = subpicture_chromas;

   /* Setup vout_display now that everything is fine */
    vd->fmt  = fmt;
    vd->info = info;

    vd->pool    = Pool;
    vd->prepare = Prepare;
    vd->display = Display;
    vd->control = Control;
    vd->manage  = Manage;

    return VLC_SUCCESS;

error:
    Close(object);
    return VLC_EGENERIC;
}
예제 #30
0
파일: encoder.c 프로젝트: forthyen/SDesk
/****************************************************************************
 * EncodeVideo: the whole thing
 ****************************************************************************/
static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
{
    encoder_sys_t *p_sys = p_enc->p_sys;
    AVFrame frame;
    int i_out, i_plane;

#if LIBAVCODEC_BUILD >= 4702
    if ( !p_sys->b_inited && p_enc->i_threads >= 1 )
    {
        struct thread_context_t ** pp_contexts;
        int i;

        p_sys->b_inited = 1;
        pp_contexts = malloc( sizeof(struct thread_context_t *)
                                 * p_enc->i_threads );
        p_sys->p_context->thread_opaque = (void *)pp_contexts;

        for ( i = 0; i < p_enc->i_threads; i++ )
        {
            pp_contexts[i] = vlc_object_create( p_enc,
                                     sizeof(struct thread_context_t) );
            pp_contexts[i]->p_context = p_sys->p_context;
            vlc_mutex_init( p_enc, &pp_contexts[i]->lock );
            vlc_cond_init( p_enc, &pp_contexts[i]->cond );
            pp_contexts[i]->b_work = 0;
            pp_contexts[i]->b_done = 0;
            if ( vlc_thread_create( pp_contexts[i], "encoder", FfmpegThread,
                                    VLC_THREAD_PRIORITY_VIDEO, VLC_FALSE ) )
            {
                msg_Err( p_enc, "cannot spawn encoder thread, expect to die soon" );
                return NULL;
            }
        }

        p_sys->p_context->execute = FfmpegExecute;
    }
#endif

    memset( &frame, 0, sizeof( AVFrame ) );
    for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
    {
        frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
        frame.linesize[i_plane] = p_pict->p[i_plane].i_pitch;
    }

    /* Let ffmpeg select the frame type */
    frame.pict_type = 0;

    frame.repeat_pict = 2 - p_pict->i_nb_fields;

#if LIBAVCODEC_BUILD >= 4685
    frame.interlaced_frame = !p_pict->b_progressive;
    frame.top_field_first = !!p_pict->b_top_field_first;
#endif

#if LIBAVCODEC_BUILD < 4702
    /* Set the pts of the frame being encoded (segfaults with mpeg4!)*/
    if( p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', 'g', 'v' ) ||
        p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '1', 'v' ) ||
        p_enc->fmt_out.i_codec == VLC_FOURCC( 'm', 'p', '2', 'v' ) )
#else
    if( 1 )
#endif
    {
        frame.pts = p_pict->date ? p_pict->date : AV_NOPTS_VALUE;

        if ( p_sys->b_hurry_up && frame.pts != AV_NOPTS_VALUE )
        {
            mtime_t current_date = mdate();

            if ( current_date + HURRY_UP_GUARD3 > frame.pts )
            {
                p_sys->p_context->mb_decision = FF_MB_DECISION_SIMPLE;
                p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
                msg_Dbg( p_enc, "hurry up mode 3" );
            }
            else
            {
                p_sys->p_context->mb_decision = p_sys->i_hq;

                if ( current_date + HURRY_UP_GUARD2 > frame.pts )
                {
                    p_sys->p_context->flags &= ~CODEC_FLAG_TRELLIS_QUANT;
#if LIBAVCODEC_BUILD >= 4690
                    p_sys->p_context->noise_reduction = p_sys->i_noise_reduction
                         + (HURRY_UP_GUARD2 + current_date - frame.pts) / 500;
#endif
                    msg_Dbg( p_enc, "hurry up mode 2" );
                }
                else
                {
                    if ( p_sys->b_trellis )
                        p_sys->p_context->flags |= CODEC_FLAG_TRELLIS_QUANT;
#if LIBAVCODEC_BUILD >= 4690
                    p_sys->p_context->noise_reduction =
                        p_sys->i_noise_reduction;
#endif
                }
            }

            if ( current_date + HURRY_UP_GUARD1 > frame.pts )
            {
                frame.pict_type = FF_P_TYPE;
                /* msg_Dbg( p_enc, "hurry up mode 1 %lld", current_date + HURRY_UP_GUARD1 - frame.pts ); */
            }
        }
    }
    else
    {
        frame.pts = AV_NOPTS_VALUE;
    }

    if ( frame.pts != AV_NOPTS_VALUE && frame.pts != 0 )
    {
        if ( p_sys->i_last_pts == frame.pts )
        {
            msg_Warn( p_enc, "almost fed libavcodec with two frames with the "
                      "same PTS (" I64Fd ")", frame.pts );
            return NULL;
        }
        else if ( p_sys->i_last_pts > frame.pts )
        {
            msg_Warn( p_enc, "almost fed libavcodec with a frame in the "
                      "past (current: " I64Fd ", last: "I64Fd")",
                      frame.pts, p_sys->i_last_pts );
            return NULL;
        }
        else
        {
            p_sys->i_last_pts = frame.pts;
        }
    }

    frame.quality = p_sys->i_quality;

    /* Ugly work-around for stupid libavcodec behaviour */
#if LIBAVCODEC_BUILD >= 4722
    p_sys->i_framenum++;
    p_sys->pi_delay_pts[p_sys->i_framenum % MAX_FRAME_DELAY] = frame.pts;
    frame.pts = p_sys->i_framenum * AV_TIME_BASE *
        p_enc->fmt_in.video.i_frame_rate_base;
    frame.pts += p_enc->fmt_in.video.i_frame_rate - 1;
    frame.pts /= p_enc->fmt_in.video.i_frame_rate;
#endif
    /* End work-around */

    i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
                                  AVCODEC_MAX_VIDEO_FRAME_SIZE, &frame );

    if( i_out > 0 )
    {
        block_t *p_block = block_New( p_enc, i_out );
        memcpy( p_block->p_buffer, p_sys->p_buffer_out, i_out );

        /* FIXME, 3-2 pulldown is not handled correctly */
        p_block->i_length = I64C(1000000) *
            p_enc->fmt_in.video.i_frame_rate_base /
                p_enc->fmt_in.video.i_frame_rate;

        if( !p_sys->p_context->max_b_frames || !p_sys->p_context->delay )
        {
            /* No delay -> output pts == input pts */
            p_block->i_pts = p_block->i_dts = p_pict->date;
        }
        else if( p_sys->p_context->coded_frame->pts != AV_NOPTS_VALUE &&
            p_sys->p_context->coded_frame->pts != 0 &&
            p_sys->i_buggy_pts_detect != p_sys->p_context->coded_frame->pts )
        {
            p_sys->i_buggy_pts_detect = p_sys->p_context->coded_frame->pts;
            p_block->i_pts = p_sys->p_context->coded_frame->pts;

            /* Ugly work-around for stupid libavcodec behaviour */
#if LIBAVCODEC_BUILD >= 4722
            {
            int64_t i_framenum = p_block->i_pts *
                p_enc->fmt_in.video.i_frame_rate /
                p_enc->fmt_in.video.i_frame_rate_base / AV_TIME_BASE;

            p_block->i_pts = p_sys->pi_delay_pts[i_framenum % MAX_FRAME_DELAY];
            }
#endif
            /* End work-around */

            if( p_sys->p_context->coded_frame->pict_type != FF_I_TYPE &&
                p_sys->p_context->coded_frame->pict_type != FF_P_TYPE )
            {
                p_block->i_dts = p_block->i_pts;
            }
            else
            {
                if( p_sys->i_last_ref_pts )
                {
                    p_block->i_dts = p_sys->i_last_ref_pts;
                }
                else
                {
                    /* Let's put something sensible */
                    p_block->i_dts = p_block->i_pts;
                }

                p_sys->i_last_ref_pts = p_block->i_pts;
            }
        }
        else
        {
            /* Buggy libavcodec which doesn't update coded_frame->pts
             * correctly */
            p_block->i_dts = p_block->i_pts = p_pict->date;
        }

        switch ( p_sys->p_context->coded_frame->pict_type )
        {
        case FF_I_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_I;
            break;
        case FF_P_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_P;
            break;
        case FF_B_TYPE:
            p_block->i_flags |= BLOCK_FLAG_TYPE_B;
            break;
        }

        return p_block;
    }

    return NULL;
}