Пример #1
0
int vout_Snapshot( vout_thread_t *p_vout, picture_t *p_pic )
{
    image_handler_t *p_image = image_HandlerCreate( p_vout );
    video_format_t fmt_in, fmt_out;
    char *psz_filename = NULL;
    vlc_value_t val, format;
    DIR *path;
    int i_ret;
    bool b_embedded_snapshot;
    int i_id = 0;

    /* */
    val.psz_string = var_GetNonEmptyString( p_vout, "snapshot-path" );

    /* Embedded snapshot : if snapshot-path == object:id */
    if( val.psz_string && sscanf( val.psz_string, "object:%d", &i_id ) > 0 )
        b_embedded_snapshot = true;
    else
        b_embedded_snapshot = false;

    /* */
    memset( &fmt_in, 0, sizeof(video_format_t) );
    fmt_in = p_vout->fmt_in;
    if( fmt_in.i_sar_num <= 0 || fmt_in.i_sar_den <= 0 )
    {
        fmt_in.i_sar_num =
        fmt_in.i_sar_den = 1;
    }

    /* */
    memset( &fmt_out, 0, sizeof(video_format_t) );
    fmt_out.i_sar_num =
    fmt_out.i_sar_den = 1;
    fmt_out.i_chroma = b_embedded_snapshot ? VLC_FOURCC('p','n','g',' ') : 0;
    fmt_out.i_width = var_GetInteger( p_vout, "snapshot-width" );
    fmt_out.i_height = var_GetInteger( p_vout, "snapshot-height" );

    if( b_embedded_snapshot &&
        fmt_out.i_width == 0 && fmt_out.i_height == 0 )
    {
        /* If snapshot-width and/or snapshot height were not specified,
           use a default snapshot width of 320 */
        fmt_out.i_width = 320;
    }

    if( fmt_out.i_height == 0 && fmt_out.i_width > 0 )
    {
        fmt_out.i_height = fmt_in.i_height * fmt_out.i_width / fmt_in.i_width;
        const int i_height = fmt_out.i_height * fmt_in.i_sar_den / fmt_in.i_sar_num;
        if( i_height > 0 )
            fmt_out.i_height = i_height;
    }
    else
    {
        if( fmt_out.i_width == 0 && fmt_out.i_height > 0 )
        {
            fmt_out.i_width = fmt_in.i_width * fmt_out.i_height / fmt_in.i_height;
        }
        else
        {
            fmt_out.i_width = fmt_in.i_width;
            fmt_out.i_height = fmt_in.i_height;
        }
        const int i_width = fmt_out.i_width * fmt_in.i_sar_num / fmt_in.i_sar_den;
        if( i_width > 0 )
            fmt_out.i_width = i_width;
    }

    /* Embedded snapshot
       create a snapshot_t* and store it in
       object(object-id)->p_private, then unlock and signal the
       waiting object.
     */
    if( b_embedded_snapshot )
    {
        vlc_object_t* p_dest;
        block_t *p_block;
        snapshot_t *p_snapshot;
        size_t i_size;

        /* Destination object-id is following object: */
        p_dest = ( vlc_object_t* )vlc_object_get( i_id );
        if( !p_dest )
        {
            msg_Err( p_vout, "Cannot find calling object" );
            image_HandlerDelete( p_image );
            return VLC_EGENERIC;
        }
        /* Object must be locked. We will unlock it once we get the
           snapshot and written it to p_private */
        p_dest->p_private = NULL;

        /* Save the snapshot to a memory zone */
        p_block = image_Write( p_image, p_pic, &fmt_in, &fmt_out );
        if( !p_block )
        {
            msg_Err( p_vout, "Could not get snapshot" );
            image_HandlerDelete( p_image );
            vlc_object_signal( p_dest );
            vlc_object_release( p_dest );
            return VLC_EGENERIC;
        }

        /* Copy the p_block data to a snapshot structure */
        /* FIXME: get the timestamp */
        p_snapshot = malloc( sizeof( snapshot_t ) );
        if( !p_snapshot )
        {
            block_Release( p_block );
            image_HandlerDelete( p_image );
            vlc_object_signal( p_dest );
            vlc_object_release( p_dest );
            return VLC_ENOMEM;
        }

        i_size = p_block->i_buffer;

        p_snapshot->i_width = fmt_out.i_width;
        p_snapshot->i_height = fmt_out.i_height;
        p_snapshot->i_datasize = i_size;
        p_snapshot->date = p_block->i_pts; /* FIXME ?? */
        p_snapshot->p_data = malloc( i_size );
        if( !p_snapshot->p_data )
        {
            block_Release( p_block );
            free( p_snapshot );
            image_HandlerDelete( p_image );
            vlc_object_signal( p_dest );
            vlc_object_release( p_dest );
            return VLC_ENOMEM;
        }
        memcpy( p_snapshot->p_data, p_block->p_buffer, p_block->i_buffer );

        p_dest->p_private = p_snapshot;

        block_Release( p_block );

        /* Unlock the object */
        vlc_object_signal( p_dest );
        vlc_object_release( p_dest );

        image_HandlerDelete( p_image );
        return VLC_SUCCESS;
    }

    /* Get default directory if none provided */
    if( !val.psz_string )
        val.psz_string = VoutSnapshotGetDefaultDirectory( p_vout );
    if( !val.psz_string )
    {
        msg_Err( p_vout, "no path specified for snapshots" );
        image_HandlerDelete( p_image );
        return VLC_EGENERIC;
    }

    /* Get snapshot format, default being "png" */
    format.psz_string = var_GetNonEmptyString( p_vout, "snapshot-format" );
    if( !format.psz_string )
        format.psz_string = strdup( "png" );
    if( !format.psz_string )
    {
        free( val.psz_string );
        image_HandlerDelete( p_image );
        return VLC_ENOMEM;
    }

    /*
     * Did the user specify a directory? If not, path = NULL.
     */
    path = utf8_opendir ( (const char *)val.psz_string  );
    if( path != NULL )
    {
        char *psz_prefix = var_GetNonEmptyString( p_vout, "snapshot-prefix" );
        if( psz_prefix == NULL )
            psz_prefix = strdup( "vlcsnap-" );
        else
        {
            char *psz_tmp = str_format( p_vout, psz_prefix );
            filename_sanitize( psz_tmp );
            free( psz_prefix );
            psz_prefix = psz_tmp;
        }

        closedir( path );
        if( var_GetBool( p_vout, "snapshot-sequential" ) == true )
        {
            int i_num = var_GetInteger( p_vout, "snapshot-num" );
            struct stat st;

            do
            {
                free( psz_filename );
                if( asprintf( &psz_filename, "%s" DIR_SEP "%s%05d.%s",
                              val.psz_string, psz_prefix, i_num++,
                              format.psz_string ) == -1 )
                {
                    msg_Err( p_vout, "could not create snapshot" );
                    image_HandlerDelete( p_image );
                    return VLC_EGENERIC;
                }
            }
            while( utf8_stat( psz_filename, &st ) == 0 );

            var_SetInteger( p_vout, "snapshot-num", i_num );
        }
        else
        {
            if( asprintf( &psz_filename, "%s" DIR_SEP "%s%u.%s",
                          val.psz_string, psz_prefix,
                          (unsigned int)(p_pic->date / 100000) & 0xFFFFFF,
                          format.psz_string ) == -1 )
            {
                msg_Err( p_vout, "could not create snapshot" );
                image_HandlerDelete( p_image );
                return VLC_EGENERIC;
            }
        }

        free( psz_prefix );
    }
    else // The user specified a full path name (including file name)
    {
        psz_filename = str_format( p_vout, val.psz_string );
        path_sanitize( psz_filename );
    }

    free( val.psz_string );
    free( format.psz_string );

    /* Save the snapshot */
    i_ret = image_WriteUrl( p_image, p_pic, &fmt_in, &fmt_out, psz_filename );
    if( i_ret != VLC_SUCCESS )
    {
        msg_Err( p_vout, "could not create snapshot %s", psz_filename );
        free( psz_filename );
        image_HandlerDelete( p_image );
        return VLC_EGENERIC;
    }

    /* */
    msg_Dbg( p_vout, "snapshot taken (%s)", psz_filename );
    vout_OSDMessage( VLC_OBJECT( p_vout ), DEFAULT_CHAN,
                     "%s", psz_filename );
    free( psz_filename );

    /* */
    if( var_GetBool( p_vout, "snapshot-preview" ) )
    {
        if( VoutSnapshotPip( p_vout, p_image, p_pic, &fmt_in ) )
            msg_Warn( p_vout, "Failed to display snapshot" );
    }
    image_HandlerDelete( p_image );

    return VLC_SUCCESS;
}
Пример #2
0
/*****************************************************************************
 * PrefsPanel class definition.
 *****************************************************************************/
PrefsPanel::PrefsPanel( HWND parent, HINSTANCE hInst, intf_thread_t *_p_intf,
                        PrefsDialog *_p_prefs_dialog,
                        int i_object_id, char *psz_section, char *psz_help )
{
    module_config_t *p_item;
    module_t *p_module = NULL;

    /* Initializations */
    p_intf = _p_intf;
    p_prefs_dialog = _p_prefs_dialog;

    b_advanced = VLC_TRUE;

    if( i_object_id == PLUGIN_ID || i_object_id == GENERAL_ID ||
        i_object_id == CAPABILITY_ID )
    {
        label = CreateWindow( _T("STATIC"), _FROMMB(psz_section),
                              WS_CHILD | WS_VISIBLE | SS_LEFT,
                              5, 10 + (15 + 10), 200, 15,
                              parent, NULL, hInst, NULL );
        config_window = NULL;
    }
    else
    {
        /* Get a pointer to the module */
        p_module = (module_t *)vlc_object_get( p_intf,  i_object_id );
        if( p_module->i_object_type != VLC_OBJECT_MODULE )
        {
            /* 0OOoo something went really bad */
            return;
        }

        /* Enumerate config options and add corresponding config boxes
         * (submodules don't have config options, they are stored in the
         *  parent module) */
        if( p_module->b_submodule )
            p_item = ((module_t *)p_module->p_parent)->p_config;
        else
            p_item = p_module->p_config;

        /* Find the category if it has been specified */
        if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY )
        {
            while( !(p_item->i_type == CONFIG_HINT_CATEGORY) ||
                   strcmp( psz_section, p_item->psz_text ) )
            {
                if( p_item->i_type == CONFIG_HINT_END ) break;
                p_item++;
            }
        }

        /* Add a head title to the panel */
        label = CreateWindow( _T("STATIC"), _FROMMB(psz_section ?
                        p_item->psz_text : p_module->psz_longname),
                        WS_CHILD | WS_VISIBLE | SS_LEFT,
                        5, 10 + (15 + 10), 250, 15,
                        parent, NULL, hInst, NULL );

        WNDCLASS wc;
        memset( &wc, 0, sizeof(wc) );
        wc.style          = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc    = (WNDPROC) _p_prefs_dialog->BaseWndProc;
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = 0;
        wc.hInstance      = hInst;
        wc.hIcon          = 0;
        wc.hCursor        = 0;
        wc.hbrBackground  = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName   = 0;
        wc.lpszClassName  = _T("PrefsPanelClass");
        RegisterClass(&wc);

        RECT rc;
        GetWindowRect( parent, &rc);
        config_window = CreateWindow( _T("PrefsPanelClass"),
                        _T("config_window"),
                        WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER,
                        5, 10 + 2*(15 + 10), rc.right - 5 - 7, 105,
                        parent, NULL, hInst, (void *) _p_prefs_dialog );

        int y_pos = 5;
        if( p_item ) do
        {
            /* If a category has been specified, check we finished the job */
            if( psz_section && p_item->i_type == CONFIG_HINT_CATEGORY &&
                strcmp( psz_section, p_item->psz_text ) )
                break;

            ConfigControl *control =
                CreateConfigControl( VLC_OBJECT(p_intf),
                                     p_item, config_window,
                                     hInst, &y_pos );

            /* Don't add items that were not recognized */
            if( control == NULL ) continue;

            /* Add the config data to our array so we can keep a trace of it */
            config_array.push_back( control );
        }
        while( p_item->i_type != CONFIG_HINT_END && p_item++ );
                
        GetWindowRect( config_window, &rc);
        maxvalue = y_pos - (rc.bottom - rc.top) + 5;
        oldvalue = 0;
        SetScrollRange( config_window, SB_VERT, 0, maxvalue, TRUE );
    }
}
Пример #3
0
/*****************************************************************************
 * DumpCommand: print the current vlc structure
 *****************************************************************************
 * This function prints either an ASCII tree showing the connections between
 * vlc objects, and additional information such as their refcount, thread ID,
 * etc. (command "tree"), or the same data as a simple list (command "list").
 *****************************************************************************/
static int DumpCommand( vlc_object_t *p_this, char const *psz_cmd,
                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    if( *psz_cmd == 't' )
    {
        char psz_foo[2 * MAX_DUMPSTRUCTURE_DEPTH + 1];
        vlc_object_t *p_object;

        if( *newval.psz_string )
        {
            p_object = vlc_object_get( p_this, atoi(newval.psz_string) );

            if( !p_object )
            {
                return VLC_ENOOBJ;
            }
        }
        else
        {
            p_object = p_this->p_vlc ? VLC_OBJECT(p_this->p_vlc) : p_this;
        }

        vlc_mutex_lock( &structure_lock );

        psz_foo[0] = '|';
        DumpStructure( p_object, 0, psz_foo );

        vlc_mutex_unlock( &structure_lock );

        if( *newval.psz_string )
        {
            vlc_object_release( p_this );
        }
    }
    else if( *psz_cmd == 'l' )
    {
        vlc_object_t **pp_current, **pp_end;

        vlc_mutex_lock( &structure_lock );

        pp_current = p_this->p_libvlc->pp_objects;
        pp_end = pp_current + p_this->p_libvlc->i_objects;

        for( ; pp_current < pp_end ; pp_current++ )
        {
            if( (*pp_current)->b_attached )
            {
                PrintObject( *pp_current, "" );
            }
            else
            {
                printf( " o %.8i %s (not attached)\n",
                        (*pp_current)->i_object_id,
                        (*pp_current)->psz_object_type );
            }
        }

        vlc_mutex_unlock( &structure_lock );
    }

    return VLC_SUCCESS;
}
Пример #4
0
/*****************************************************************************
 * Stress: perform various stress tests
 *****************************************************************************/
static int Stress( vlc_object_t *p_this, char const *psz_cmd,
                   vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
    vlc_object_t **pp_objects;
    mtime_t start;
    char ** ppsz_name;
    char *  psz_blob;
    int     i, i_level;

    if( *newval.psz_string )
    {
        i_level = atoi( newval.psz_string );
        if( i_level <= 0 )
        {
            i_level = 1;
        }
        else if( i_level > 200 )
        {
            /* It becomes quite dangerous above 150 */
            i_level = 200;
        }
    }
    else
    {
        i_level = 10;
    }

    /* Allocate required data */
    ppsz_name = malloc( MAXVAR * i_level * sizeof(char*) );
    psz_blob = malloc( 20 * MAXVAR * i_level * sizeof(char) );
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        ppsz_name[i] = psz_blob + 20 * i;
    }

    pp_objects = malloc( MAXOBJ * i_level * sizeof(void*) );

    /*
     *  Test #1: objects
     */
    printf( "Test #1: objects\n" );

    printf( " - creating %i objects\n", MAXOBJ * i_level );
    start = mdate();
    for( i = 0; i < MAXOBJ * i_level; i++ )
    {
        pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
    }

    printf( " - randomly looking up %i objects\n", MAXLOOK * i_level );
    for( i = MAXLOOK * i_level; i--; )
    {
        int id = (int) (MAXOBJ * i_level * 1.0 * rand() / (RAND_MAX));
        vlc_object_get( p_this, pp_objects[id]->i_object_id );
        vlc_object_release( p_this );
    }

    printf( " - destroying the objects (LIFO)\n" );
    for( i = MAXOBJ * i_level; i--; )
    {
        vlc_object_destroy( pp_objects[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /*
     *  Test #2: integer variables
     */
    printf( "Test #2: integer variables\n" );

    printf( " - creating %i integer variables\n", MAXVAR * i_level );
    start = mdate();
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
        var_Create( p_this, ppsz_name[i], VLC_VAR_INTEGER );
    }

    printf( " - randomly assigning %i values\n", MAXSET * i_level );
    for( i = 0; i < MAXSET * i_level; i++ )
    {
        int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
        var_Set( p_this, ppsz_name[v], (vlc_value_t)i );
    }

    printf( " - destroying the variables\n" );
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        var_Destroy( p_this, ppsz_name[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /*
     *  Test #3: string variables
     */
    printf( "Test #3: string variables\n" );

    printf( " - creating %i string variables\n", MAXVAR * i_level );
    start = mdate();
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        sprintf( ppsz_name[i], "foo-%04i-bar-%04x", i, i * 11 );
        var_Create( p_this, ppsz_name[i], VLC_VAR_STRING );
    }

    printf( " - randomly assigning %i values\n", MAXSET * i_level );
    for( i = 0; i < MAXSET * i_level; i++ )
    {
        int v = (int) (MAXVAR * i_level * 1.0 * rand() / (RAND_MAX));
        var_Set( p_this, ppsz_name[v], (vlc_value_t)ppsz_name[v] );
    }

    printf( " - destroying the variables\n" );
    for( i = 0; i < MAXVAR * i_level; i++ )
    {
        var_Destroy( p_this, ppsz_name[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /*
     *  Test #4: threads
     */
    printf( "Test #4: threads\n" );
    start = mdate();

    printf( " - spawning %i threads that will each create %i objects\n",
            MAXTH * i_level, MAXOBJ/MAXTH );
    for( i = 0; i < MAXTH * i_level; i++ )
    {
        pp_objects[i] = vlc_object_create( p_this, VLC_OBJECT_GENERIC );
        vlc_thread_create( pp_objects[i], "foo", Dummy, 0, VLC_TRUE );
    }

    printf( " - killing the threads (LIFO)\n" );
    for( i = MAXTH * i_level; i--; )
    {
        pp_objects[i]->b_die = VLC_TRUE;
        vlc_thread_join( pp_objects[i] );
        vlc_object_destroy( pp_objects[i] );
    }

    printf( "done (%fs).\n", (mdate() - start) / 1000000.0 );

    /* Free required data */
    free( pp_objects );
    free( psz_blob );
    free( ppsz_name );

    return VLC_SUCCESS;
}