示例#1
0
文件: picture.c 项目: Annovae/vlc
picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_resource_t *p_resource )
{
    video_format_t fmt = *p_fmt;

    /* It is needed to be sure all information are filled */
    video_format_Setup( &fmt, p_fmt->i_chroma,
                              p_fmt->i_width, p_fmt->i_height,
                              p_fmt->i_visible_width, p_fmt->i_visible_height,
                              p_fmt->i_sar_num, p_fmt->i_sar_den );
    if( p_fmt->i_x_offset < p_fmt->i_width &&
        p_fmt->i_y_offset < p_fmt->i_height &&
        p_fmt->i_visible_width  > 0 && p_fmt->i_x_offset + p_fmt->i_visible_width  <= p_fmt->i_width &&
        p_fmt->i_visible_height > 0 && p_fmt->i_y_offset + p_fmt->i_visible_height <= p_fmt->i_height )
        video_format_CopyCrop( &fmt, p_fmt );

    /* */
    picture_t *p_picture = calloc( 1, sizeof(*p_picture) );
    if( !p_picture )
        return NULL;

    /* Make sure the real dimensions are a multiple of 16 */
    if( picture_Setup( p_picture, &fmt ) )
    {
        free( p_picture );
        return NULL;
    }

    if( p_resource )
    {
        p_picture->p_sys = p_resource->p_sys;
        p_picture->gc.pf_destroy = p_resource->pf_destroy;
        assert( p_picture->gc.p_sys == NULL );

        for( int i = 0; i < p_picture->i_planes; i++ )
        {
            p_picture->p[i].p_pixels = p_resource->p[i].p_pixels;
            p_picture->p[i].i_lines  = p_resource->p[i].i_lines;
            p_picture->p[i].i_pitch  = p_resource->p[i].i_pitch;
        }
    }
    else
    {
        if( AllocatePicture( p_picture ) )
        {
            free( p_picture );
            return NULL;
        }
    }

    /* */
    p_picture->format = fmt;

    atomic_init( &p_picture->gc.refcount, 1 );
    if( p_picture->gc.pf_destroy == NULL )
        p_picture->gc.pf_destroy = PictureDestroy;

    return p_picture;
}
示例#2
0
picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_resource_t *p_resource )
{
    video_format_t fmt = *p_fmt;

    /* It is needed to be sure all information are filled */
    video_format_Setup( &fmt, p_fmt->i_chroma,
                              p_fmt->i_width, p_fmt->i_height,
                              p_fmt->i_sar_num, p_fmt->i_sar_den );
    if( p_fmt->i_x_offset < p_fmt->i_width &&
        p_fmt->i_y_offset < p_fmt->i_height &&
        p_fmt->i_visible_width  > 0 && p_fmt->i_x_offset + p_fmt->i_visible_width  <= p_fmt->i_width &&
        p_fmt->i_visible_height > 0 && p_fmt->i_y_offset + p_fmt->i_visible_height <= p_fmt->i_height )
        video_format_CopyCrop( &fmt, p_fmt );

    /* */
    picture_t *p_picture = calloc( 1, sizeof(*p_picture) );
    if( !p_picture )
        return NULL;

    if( p_resource )
    {
        if( picture_Setup( p_picture, fmt.i_chroma, fmt.i_width, fmt.i_height,
                           fmt.i_sar_num, fmt.i_sar_den ) )
        {
            free( p_picture );
            return NULL;
        }
        p_picture->p_sys = p_resource->p_sys;

        for( int i = 0; i < p_picture->i_planes; i++ )
        {
            p_picture->p[i].p_pixels = p_resource->p[i].p_pixels;
            p_picture->p[i].i_lines  = p_resource->p[i].i_lines;
            p_picture->p[i].i_pitch  = p_resource->p[i].i_pitch;
        }
    }
    else
    {
        if( vout_AllocatePicture( p_picture,
                                  fmt.i_chroma, fmt.i_width, fmt.i_height,
                                  fmt.i_sar_num, fmt.i_sar_den ) )
        {
            free( p_picture );
            return NULL;
        }
    }
    /* */
    p_picture->format = fmt;
    p_picture->i_refcount = 1;
    p_picture->pf_release = PictureReleaseCallback;

    return p_picture;
}
/*****************************************************************************
 * SendFrame: send a video frame to the stream output.
 *****************************************************************************/
static block_t *SendFrame( decoder_t *p_dec, block_t *p_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts );

    if( p_sys->b_invert )
    {
        picture_t pic;
        uint8_t *p_tmp, *p_pixels;
        int i, j;

        /* Fill in picture_t fields */
        picture_Setup( &pic, p_dec->fmt_out.i_codec,
                       p_dec->fmt_out.video.i_width,
                       p_dec->fmt_out.video.i_height, 0, 1 );

        if( !pic.i_planes )
        {
            msg_Err( p_dec, "unsupported chroma" );
            return p_block;
        }

        p_tmp = (uint8_t *)malloc( pic.p[0].i_pitch );			// sunqueen modify
        if( !p_tmp )
            return p_block;
        p_pixels = p_block->p_buffer;
        for( i = 0; i < pic.i_planes; i++ )
        {
            int i_pitch = pic.p[i].i_pitch;
            uint8_t *p_top = p_pixels;
            uint8_t *p_bottom = p_pixels + i_pitch *
                (pic.p[i].i_visible_lines - 1);

            for( j = 0; j < pic.p[i].i_visible_lines / 2; j++ )
            {
                memcpy( p_tmp, p_bottom, pic.p[i].i_visible_pitch  );
                memcpy( p_bottom, p_top, pic.p[i].i_visible_pitch  );
                memcpy( p_top, p_tmp, pic.p[i].i_visible_pitch  );
                p_top += i_pitch;
                p_bottom -= i_pitch;
            }

            p_pixels += i_pitch * pic.p[i].i_lines;
        }
        free( p_tmp );
    }

    return p_block;
}
示例#4
0
/**
 * Allocate a new picture in the heap.
 *
 * This function allocates a fake direct buffer in memory, which can be
 * used exactly like a video buffer. The video output thread then manages
 * how it gets displayed.
 */
static int vout_AllocatePicture( picture_t *p_pic,
                                 vlc_fourcc_t i_chroma,
                                 int i_width, int i_height,
                                 int i_sar_num, int i_sar_den )
{
    /* Make sure the real dimensions are a multiple of 16 */
    if( picture_Setup( p_pic, i_chroma, i_width, i_height,
                       i_sar_num, i_sar_den ) != VLC_SUCCESS )
        return VLC_EGENERIC;

    /* Calculate how big the new image should be */
    size_t i_bytes = 0;
    for( int i = 0; i < p_pic->i_planes; i++ )
    {
        const plane_t *p = &p_pic->p[i];

        if( p->i_pitch <= 0 || p->i_lines <= 0 ||
            p->i_pitch > (SIZE_MAX - i_bytes)/p->i_lines )
        {
            p_pic->i_planes = 0;
            return VLC_ENOMEM;
        }
        i_bytes += p->i_pitch * p->i_lines;
    }

    uint8_t *p_data = vlc_memalign( &p_pic->p_data_orig, 16, i_bytes );
    if( !p_data )
    {
        p_pic->i_planes = 0;
        return VLC_EGENERIC;
    }

    /* Fill the p_pixels field for each plane */
    p_pic->p[0].p_pixels = p_data;
    for( int i = 1; i < p_pic->i_planes; i++ )
    {
        p_pic->p[i].p_pixels = &p_pic->p[i-1].p_pixels[ p_pic->p[i-1].i_lines *
                                                        p_pic->p[i-1].i_pitch ];
    }

    return VLC_SUCCESS;
}
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys;

    switch( p_dec->fmt_in.i_codec )
    {
        /* Planar YUV */
        case VLC_CODEC_I444:
        case VLC_CODEC_J444:
        case VLC_CODEC_I440:
        case VLC_CODEC_J440:
        case VLC_CODEC_I422:
        case VLC_CODEC_J422:
        case VLC_CODEC_I420:
        case VLC_CODEC_J420:
        case VLC_CODEC_YV12:
        case VLC_CODEC_YV9:
        case VLC_CODEC_I411:
        case VLC_CODEC_I410:
        case VLC_CODEC_GREY:
        case VLC_CODEC_YUVP:
        case VLC_CODEC_NV12:
        case VLC_CODEC_NV21:
        case VLC_CODEC_I422_10L:
        case VLC_CODEC_I422_10B:

        /* Packed YUV */
        case VLC_CODEC_YUYV:
        case VLC_CODEC_YVYU:
        case VLC_CODEC_UYVY:
        case VLC_CODEC_VYUY:

        /* RGB */
        case VLC_CODEC_RGB32:
        case VLC_CODEC_RGB24:
        case VLC_CODEC_RGB16:
        case VLC_CODEC_RGB15:
        case VLC_CODEC_RGB8:
        case VLC_CODEC_RGBP:
        case VLC_CODEC_RGBA:
            break;

        default:
            return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys =
          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
        return VLC_ENOMEM;
    /* Misc init */
    p_dec->p_sys->b_packetizer = false;
    p_sys->b_invert = false;

    if( (int)p_dec->fmt_in.video.i_height < 0 )
    {
        /* Frames are coded from bottom to top */
        p_dec->fmt_in.video.i_height =
            (unsigned int)(-(int)p_dec->fmt_in.video.i_height);
        p_sys->b_invert = true;
    }
    if( !p_dec->fmt_in.video.i_visible_width )
        p_dec->fmt_in.video.i_visible_width = p_dec->fmt_in.video.i_width;
    if( !p_dec->fmt_in.video.i_visible_height )
        p_dec->fmt_in.video.i_visible_height = p_dec->fmt_in.video.i_height;

    if( p_dec->fmt_in.video.i_visible_width <= 0
     || p_dec->fmt_in.video.i_visible_height <= 0 )
    {
        msg_Err( p_dec, "invalid display size %dx%d",
                 p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_height );
        return VLC_EGENERIC;
    }

    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );

    date_Init( &p_sys->pts, p_dec->fmt_out.video.i_frame_rate,
               p_dec->fmt_out.video.i_frame_rate_base );
    if( p_dec->fmt_out.video.i_frame_rate == 0 ||
        p_dec->fmt_out.video.i_frame_rate_base == 0)
    {
        msg_Warn( p_dec, "invalid frame rate %d/%d, using 25 fps instead",
                  p_dec->fmt_out.video.i_frame_rate,
                  p_dec->fmt_out.video.i_frame_rate_base);
        date_Init( &p_sys->pts, 25, 1 );
    }

    /* Find out p_vdec->i_raw_size */
    video_format_Setup( &p_dec->fmt_out.video, p_dec->fmt_in.i_codec,
                        p_dec->fmt_in.video.i_visible_width,
                        p_dec->fmt_in.video.i_visible_height,
                        p_dec->fmt_in.video.i_sar_num,
                        p_dec->fmt_in.video.i_sar_den );
    picture_t picture;
    picture_Setup( &picture, p_dec->fmt_out.i_codec,
                   p_dec->fmt_in.video.i_width,
                   p_dec->fmt_in.video.i_height, 0, 1 );
    p_sys->i_raw_size = 0;
    for( int i = 0; i < picture.i_planes; i++ )
    {
        p_sys->i_raw_size += picture.p[i].i_visible_pitch *
                             picture.p[i].i_visible_lines;
        p_sys->planes[i] = picture.p[i];
    }

    if( !p_dec->fmt_in.video.i_sar_num || !p_dec->fmt_in.video.i_sar_den )
    {
        p_dec->fmt_out.video.i_sar_num = 1;
        p_dec->fmt_out.video.i_sar_den = 1;
    }

    /* Set callbacks */
    p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
        DecodeBlock;
    p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
        DecodeBlock;

    return VLC_SUCCESS;
}
示例#6
0
文件: switcher.c 项目: Kafay/vlc
/*****************************************************************************
 * UnpackFromFile: Read a YUV picture and store it in our format
 *****************************************************************************/
static int UnpackFromFile( sout_stream_t *p_stream, const char *psz_file,
                           int i_width, int i_height,
                           picture_t *p_pic )
{
    int i, j;
    FILE *p_file = utf8_fopen( psz_file, "r" );

    if ( p_file == NULL )
    {
        msg_Err( p_stream, "file %s not found", psz_file );
        return -1;
    }

    if( picture_Setup( p_pic, VLC_CODEC_I420,
                       i_width, i_height,
                       i_width * VOUT_ASPECT_FACTOR / i_height ) )
    {
        msg_Err( p_stream, "unknown chroma" );
        return -1;
    }
    for ( i = 0; i < p_pic->i_planes; i++ )
    {
        p_pic->p[i].p_pixels = malloc( p_pic->p[i].i_lines *
                                           p_pic->p[i].i_pitch );
        memset( p_pic->p[i].p_pixels, 0, p_pic->p[i].i_lines *
                    p_pic->p[i].i_pitch );
    }

    for ( i = 0; i < i_height; i++ )
    {
        int i_chroma;
        uint8_t p_buffer[i_width * 2];
        uint8_t *p_char = p_buffer;
        uint8_t *p_y = &p_pic->p[0].p_pixels[i * p_pic->p[0].i_pitch];
        uint8_t *p_u = &p_pic->p[1].p_pixels[i/2 * p_pic->p[1].i_pitch];
        uint8_t *p_v = &p_pic->p[2].p_pixels[i/2 * p_pic->p[2].i_pitch];

        if ( fread( p_buffer, 2, i_width, p_file ) != (size_t)i_width )
        {
            msg_Err( p_stream, "premature end of file %s", psz_file );
            fclose( p_file );
            for ( i = 0; i < p_pic->i_planes; i++ )
            {
                free( p_pic->p[i].p_pixels );
            }
            return -1;
        }

        i_chroma = 0;
        for ( j = 0; j < i_width; j++ )
        {
            uint8_t **pp_chroma = i_chroma ? &p_v : &p_u;
            i_chroma = !i_chroma;
            if ( i & 1 )
                **pp_chroma = (**pp_chroma + *p_char + 1) / 2;
            else
                **pp_chroma = *p_char;
            (*pp_chroma)++;
            p_char++;
            *p_y++ = *p_char++;
        }
    }

    fclose( p_file );
    return 0;
}
示例#7
0
文件: dc1394.c 项目: cobr123/qtVlc
/*****************************************************************************
 * Open:
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    demux_t      *p_demux = (demux_t*)p_this;
    demux_sys_t  *p_sys;
    es_format_t   fmt;
    dc1394error_t res;
    int           i_width;
    int           i_height;

    if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
        return VLC_EGENERIC;

    /* Set up p_demux */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
    p_demux->info.i_update = 0;
    p_demux->info.i_title = 0;
    p_demux->info.i_seekpoint = 0;

    p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;

    memset( &fmt, 0, sizeof( es_format_t ) );

    /* DEFAULTS */
    p_sys->video_mode      = DC1394_VIDEO_MODE_640x480_YUV422;
    p_sys->width           = 640;
    p_sys->height          = 480;
    p_sys->frame_rate      = DC1394_FRAMERATE_15;
    p_sys->brightness      = 200;
    p_sys->focus           = 0;
    p_sys->fd_audio        = -1;
    p_sys->p_dccontext     = NULL;
    p_sys->camera          = NULL;
    p_sys->selected_camera = -1;
    p_sys->dma_buffers     = 1;
    p_sys->reset_bus       = 0;

    /* PROCESS INPUT OPTIONS */
    if( process_options(p_demux) != VLC_SUCCESS )
    {
        msg_Err( p_demux, "Bad MRL, please check the option line "
                          "(MRL was: %s)",
                          p_demux->psz_path );
        free( p_sys );
        return VLC_EGENERIC;
    }

    p_sys->p_dccontext = dc1394_new();
    if( !p_sys->p_dccontext )
    {
        msg_Err( p_demux, "Failed to initialise libdc1394");
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
    {
        dc1394_free( p_sys->p_dccontext );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( !p_sys->camera )
    {
        msg_Err( p_demux, "No camera found !!" );
        dc1394_free( p_sys->p_dccontext );
        free( p_sys );
        return VLC_EGENERIC;
    }

    if( p_sys->reset_bus )
    {
        if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
        {
            msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
            Close( p_this );
            return VLC_EGENERIC;
        }
        else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
    }

    if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to reset camera");
        Close( p_this );
        return VLC_EGENERIC;
    }

    if( dc1394_camera_print_info( p_sys->camera,
                  stderr ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to print camera info");
        Close( p_this );
        return VLC_EGENERIC;
    }

    if( dc1394_feature_get_all( p_sys->camera,
                &p_sys->features ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to get feature set");
        Close( p_this );
        return VLC_EGENERIC;
    }
    // TODO: only print features if verbosity increased
    dc1394_feature_print_all(&p_sys->features, stderr);

#if 0 //"Note that you need to execute this function only if you use exotic video1394 device names. /dev/video1394, /dev/video1394/* and /dev/video1394-* are automatically recognized." http://damien.douxchamps.net/ieee1394/libdc1394/v2.x/api/capture/
    if( p_sys->video_device )
    {
        if( dc1394_capture_set_device_filename( p_sys->camera,
                        p_sys->video_device ) != DC1394_SUCCESS )
        {
            msg_Err( p_demux, "Unable to set video device");
            Close( p_this );
            return VLC_EGENERIC;
        }
    }
#endif

    if( p_sys->focus )
    {
        if( dc1394_feature_set_value( p_sys->camera,
                      DC1394_FEATURE_FOCUS,
                      p_sys->focus ) != DC1394_SUCCESS )
        {
            msg_Err( p_demux, "Unable to set initial focus to %u",
                     p_sys->focus );
        }
        else
            msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
    }

    if( dc1394_feature_set_value( p_sys->camera,
                  DC1394_FEATURE_FOCUS,
                  p_sys->brightness ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to set initial brightness to %u",
                 p_sys->brightness );
    }
    else
        msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );

    if( dc1394_video_set_framerate( p_sys->camera,
                    p_sys->frame_rate ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to set framerate");
        Close( p_this );
        return VLC_EGENERIC;
    }

    if( dc1394_video_set_mode( p_sys->camera,
                   p_sys->video_mode ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to set video mode");
        Close( p_this );
        return VLC_EGENERIC;
    }

    if( dc1394_video_set_iso_speed( p_sys->camera,
                    DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to set iso speed");
        Close( p_this );
        return VLC_EGENERIC;
    }

    /* and setup capture */
    res = dc1394_capture_setup( p_sys->camera,
                    p_sys->dma_buffers,
                DC1394_CAPTURE_FLAGS_DEFAULT);
    if( res != DC1394_SUCCESS )
    {
        if( res == DC1394_NO_BANDWIDTH )
        {
            msg_Err( p_demux ,"No bandwidth: try adding the "
             "\"resetbus\" option" );
        }
        else
        {
            msg_Err( p_demux ,"Unable to setup capture" );
        }
        Close( p_this );
        return VLC_EGENERIC;
    }

    /* TODO - UYV444 chroma converter is missing, when it will be available
     * fourcc will become variable (and not just a fixed value for UYVY)
     */
    i_width = p_sys->width;
    i_height = p_sys->height;

    if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY,
                       i_width, i_height, 1, 1 ) )
    {
        msg_Err( p_demux ,"unknown chroma" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );

    fmt.video.i_width = i_width;
    fmt.video.i_height = i_height;

    msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
             (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );

    p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );

    if( p_sys->audio_device )
    {
        if( OpenAudioDev( p_demux ) == VLC_SUCCESS )
        {
            es_format_t fmt;
            es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_S16L ); /* FIXME: hmm, ?? */

            fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
            fmt.audio.i_rate = p_sys->i_sample_rate;
            fmt.audio.i_bitspersample = 16;
            fmt.audio.i_blockalign = fmt.audio.i_channels *
                                     fmt.audio.i_bitspersample / 8;
            fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
                            fmt.audio.i_bitspersample;

            msg_Dbg( p_demux, "New audio es %d channels %dHz",
            fmt.audio.i_channels, fmt.audio.i_rate );

            p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
        }
    }

    /* have the camera start sending us data */
    if( dc1394_video_set_transmission( p_sys->camera,
                       DC1394_ON ) != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Unable to start camera iso transmission" );
        dc1394_capture_stop( p_sys->camera );
        Close( p_this );
        return VLC_EGENERIC;
    }
    msg_Dbg( p_demux, "Set iso transmission" );
    // TODO: reread camera
    return VLC_SUCCESS;
}
示例#8
0
文件: dc1394.c 项目: FLYKingdom/vlc
/*****************************************************************************
 * Open:
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys;
    es_format_t fmt;
    int i;
    int i_width;
    int i_height;
    int result = 0;

    if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
        return VLC_EGENERIC;

    /* Set up p_demux */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
    p_demux->info.i_update = 0;
    p_demux->info.i_title = 0;
    p_demux->info.i_seekpoint = 0;

    p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
    if( !p_sys )
        return VLC_ENOMEM;
    memset( &fmt, 0, sizeof( es_format_t ) );

    /* DEFAULTS */
    p_sys->frame_size = MODE_640x480_YUV422;
    p_sys->width      = 640;
    p_sys->height     = 480;
    p_sys->frame_rate = FRAMERATE_30;
    p_sys->brightness = 200;
    p_sys->focus      = 0;
    p_sys->dma_capture = DMA_ON; /* defaults to VIDEO1394 capture mode */
    p_sys->fd_audio   = -1;
    p_sys->fd_video   = NULL;
    p_sys->camera_nodes = NULL;
    p_sys->selected_camera = 0;
    p_sys->dma_device = NULL;
    p_sys->selected_uid = 0;

    /* PROCESS INPUT OPTIONS */
    if( process_options(p_demux) != VLC_SUCCESS )
    {
        msg_Err( p_demux, "Bad MRL, please check the option line "
                          "(MRL was: %s)",
                          p_demux->psz_path );
        free( p_sys );
        p_demux->p_sys = NULL;
        return VLC_EGENERIC;
    }

    msg_Dbg( p_demux, "Selected camera %d", p_sys->selected_camera );
    msg_Dbg( p_demux, "Selected uid 0x%llx", p_sys->selected_uid );

    ScanCameras( p_sys, p_demux );
    if( !p_sys->camera_nodes )
    {
        msg_Err( p_demux, "No camera found !!" );
        free( p_sys );
        p_demux->p_sys = NULL;
        return VLC_EGENERIC;
    }

    if( p_sys->selected_uid )
    {
        int found = 0;
        for( i=0; i < p_sys->num_cameras; i++ )
        {
            if( p_sys->camera_nodes[i].uid == p_sys->selected_uid )
            {
                p_sys->selected_camera = i;
                found++;
                break;
            }
        }
        if( !found )
        {
            msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
                     p_sys->selected_uid );
            Close( p_this );
            return VLC_EGENERIC;
        }
    }
    else if( p_sys->selected_camera >= p_sys->num_cameras )
    {
        msg_Err( p_demux, "there are not this many cameras. (%d/%d)",
                          p_sys->selected_camera, p_sys->num_cameras );
        Close( p_this );
        return VLC_EGENERIC;
    }

    p_sys->fd_video = dc1394_create_handle(
                        p_sys->camera_nodes[p_sys->selected_camera].port );
    if( (int)p_sys->fd_video < 0 )
    {
        msg_Err( p_demux, "Can't init dc1394 handle" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    /* get camera info */
    result = dc1394_get_camera_info( p_sys->fd_video,
                        p_sys->camera_nodes[p_sys->selected_camera].node,
                        &p_sys->camera_info );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux ,"unable to get camera info" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    dc1394_print_camera_info( &p_sys->camera_info );
    result = dc1394_get_camera_misc_info( p_sys->fd_video,
                        p_sys->camera_nodes[p_sys->selected_camera].node,
                        &p_sys->misc_info );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "unable to get camera misc info" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    /* init camera and set some video options  */
    result = dc1394_init_camera( p_sys->camera_info.handle,
                                 p_sys->camera_info.id );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "unable to get init dc1394 camera" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    if( p_sys->focus )
    {
        result = dc1394_set_focus( p_sys->camera_info.handle,
                        p_sys->camera_nodes[p_sys->selected_camera].node,
                        p_sys->focus );
        if( result != DC1394_SUCCESS )
        {
            msg_Err( p_demux, "unable to set initial focus to %u",
                     p_sys->focus );
        }
        msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
    }

    result = dc1394_set_brightness( p_sys->camera_info.handle,
                        p_sys->camera_nodes[p_sys->selected_camera].node,
                        p_sys->brightness );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "unable to set init brightness to %d",
                 p_sys->brightness);
        Close( p_this );
        return VLC_EGENERIC;
    }

    result = dc1394_set_video_framerate( p_sys->camera_info.handle,
                        p_sys->camera_nodes[p_sys->selected_camera].node,
                        p_sys->frame_rate );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "unable to set framerate to %d",
                 p_sys->frame_rate );
        Close( p_this );
        return VLC_EGENERIC;
    }
    p_sys->misc_info.framerate = p_sys->frame_rate;

    result = dc1394_set_video_format( p_sys->camera_info.handle,
                        p_sys->camera_nodes[p_sys->selected_camera].node,
                        FORMAT_VGA_NONCOMPRESSED );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "unable to set video format to VGA_NONCOMPRESSED" );
        Close( p_this );
        return VLC_EGENERIC;
    }
    p_sys->misc_info.format = FORMAT_VGA_NONCOMPRESSED;

    result = dc1394_set_video_mode( p_sys->camera_info.handle,
                        p_sys->camera_nodes[p_sys->selected_camera].node,
                        p_sys->frame_size );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "unable to set video mode" );
        Close( p_this );
        return VLC_EGENERIC;
    }
    p_sys->misc_info.mode = p_sys->frame_size;

    /* reprobe everything */
    result = dc1394_get_camera_info( p_sys->camera_info.handle,
                                     p_sys->camera_info.id,
                                     &p_sys->camera_info );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Could not get camera basic information!" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    result = dc1394_get_camera_misc_info( p_sys->camera_info.handle,
                                          p_sys->camera_info.id,
                                          &p_sys->misc_info );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Could not get camera misc information!" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    /* set iso_channel */
    result = dc1394_set_iso_channel_and_speed( p_sys->camera_info.handle,
                                               p_sys->camera_info.id,
                                               p_sys->selected_camera,
                                               SPEED_400 );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "Could not set iso channel!" );
        Close( p_this );
        return VLC_EGENERIC;
    }
    msg_Dbg( p_demux, "Using ISO channel %d", p_sys->misc_info.iso_channel );
    p_sys->misc_info.iso_channel = p_sys->selected_camera;

    /* and setup capture */
    if( p_sys->dma_capture )
    {
        result = dc1394_dma_setup_capture( p_sys->camera_info.handle,
                        p_sys->camera_info.id,
                        p_sys->misc_info.iso_channel,
                        p_sys->misc_info.format,
                        p_sys->misc_info.mode,
                        SPEED_400,
                        p_sys->misc_info.framerate,
                        10, 0,
                        p_sys->dma_device,
                        &p_sys->camera );
        if( result != DC1394_SUCCESS )
        {
            msg_Err( p_demux ,"unable to setup camera" );
            Close( p_this );
            return VLC_EGENERIC;
        }
    }
    else
    {
        result = dc1394_setup_capture( p_sys->camera_info.handle,
                    p_sys->camera_info.id,
                    p_sys->misc_info.iso_channel,
                    p_sys->misc_info.format,
                    p_sys->misc_info.mode,
                    SPEED_400,
                    p_sys->misc_info.framerate,
                    &p_sys->camera );
        if( result != DC1394_SUCCESS)
        {
            msg_Err( p_demux ,"unable to setup camera" );
            Close( p_this );
            return VLC_EGENERIC;
        }
    }

    /* TODO - UYV444 chroma converter is missing, when it will be available
     * fourcc will become variable (and not just a fixed value for UYVY)
     */
    i_width = p_sys->camera.frame_width;
    i_height = p_sys->camera.frame_height;

    if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY,
                       i_width, i_height,
                       i_width * VOUT_ASPECT_FACTOR / i_height ) )
    {
        msg_Err( p_demux ,"unknown chroma" );
        Close( p_this );
        return VLC_EGENERIC;
    }

    es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );

    fmt.video.i_width = i_width;
    fmt.video.i_height = i_height;

    msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
             (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );

    p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );

    if( p_sys->audio_device )
    {
        OpenAudioDev( p_demux );
        if( p_sys->fd_audio >= 0 )
        {
            es_format_t fmt;
            es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_S16L ); /* FIXME: hmm, ?? */

            fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
            fmt.audio.i_rate = p_sys->i_sample_rate;
            fmt.audio.i_bitspersample = 16;
            fmt.audio.i_blockalign = fmt.audio.i_channels *
                                     fmt.audio.i_bitspersample / 8;
            fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
                            fmt.audio.i_bitspersample;

            msg_Dbg( p_demux, "new audio es %d channels %dHz",
            fmt.audio.i_channels, fmt.audio.i_rate );

            p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
        }
    }

    /* have the camera start sending us data */
    result = dc1394_start_iso_transmission( p_sys->camera_info.handle,
                                            p_sys->camera_info.id );
    if( result != DC1394_SUCCESS )
    {
        msg_Err( p_demux, "unable to start camera iso transmission" );
        if( p_sys->dma_capture )
        {
            dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
        }
        else
        {
            dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
        }
        Close( p_this );
        return VLC_EGENERIC;
    }
    p_sys->misc_info.is_iso_on = DC1394_TRUE;
    return VLC_SUCCESS;
}
示例#9
0
文件: evas.c 项目: chouquette/vlc
static int
EvasImageBuffersAlloc( vout_display_t *vd, video_format_t *p_fmt )
{
    vout_display_sys_t *sys = vd->sys;
    picture_t *p_pic = NULL;
    picture_resource_t rsc;
    size_t i_bytes = 0;

    memset(&rsc, 0, sizeof(picture_resource_t));
    if( !( p_pic = picture_NewFromResource( p_fmt, &rsc ) ) )
        return -1;

    if( picture_Setup( p_pic, p_fmt ) )
    {
        picture_Release( p_pic );
        return -1;
    }

    for( int i = 0; i < p_pic->i_planes; ++i )
        memcpy( &sys->p_planes[i], &p_pic->p[i], sizeof(plane_t));
    sys->i_nb_planes = p_pic->i_planes;
    picture_Release( p_pic );

    if( !( sys->p_buffers = calloc( sys->i_nb_buffers, sizeof(struct buffer) ) ) )
        goto error;

    /* Calculate how big the new image should be */
    for( unsigned int i = 0; i < sys->i_nb_planes; i++ )
    {
        const plane_t *p = &sys->p_planes[i];

        if( p->i_pitch < 0 || p->i_lines <= 0 ||
            (size_t)p->i_pitch > (SIZE_MAX - i_bytes)/p->i_lines )
            goto error;
        i_bytes += p->i_pitch * p->i_lines;
    }

    if( !i_bytes )
        goto error;

    for( unsigned int i = 0; i < sys->i_nb_buffers; ++i )
    {
        struct buffer *p_buffer = &sys->p_buffers[i];

        p_buffer->p[0] = aligned_alloc( 16, i_bytes );

        if( !p_buffer->p[0] )
        {
            sys->i_nb_buffers = i;
            break;
        }

        for( unsigned int j = 1; j < sys->i_nb_planes; j++ )
            p_buffer->p[j] = &p_buffer->p[j-1][ sys->p_planes[j-1].i_lines *
                                                sys->p_planes[j-1].i_pitch ];
    }

    return 0;

error:
    if( sys->p_buffers )
        EvasImageBuffersFree( vd );
    return -1;
}