int RemoteCameraHttp::Capture( Image &image )
{
    int content_length = GetResponse();
    if ( content_length == 0 )
    {
        Warning( "Unable to capture image, retrying" );
        return( 1 );
    }
    if ( content_length < 0 )
    {
        Error( "Unable to get response" );
        Disconnect();
        return( -1 );
    }
    switch( format )
    {
        case JPEG :
        {
            if ( !image.DecodeJpeg( buffer.extract( content_length ), content_length, colours, subpixelorder ) )
            {
                Error( "Unable to decode jpeg" );
                Disconnect();
                return( -1 );
            }
            break;
        }
        case X_RGB :
        {
            if ( content_length != image.Size() )
            {
                Error( "Image length mismatch, expected %d bytes, content length was %d", image.Size(), content_length );
                Disconnect();
                return( -1 );
            }
            image.Assign( width, height, colours, subpixelorder, buffer, imagesize );
            break;
        }
        case X_RGBZ :
        {
            if ( !image.Unzip( buffer.extract( content_length ), content_length ) )
            {
                Error( "Unable to unzip RGB image" );
                Disconnect();
                return( -1 );
            }
            image.Assign( width, height, colours, subpixelorder, buffer, imagesize );
            break;
        }
        default :
        {
            Error( "Unexpected image format encountered" );
            Disconnect();
            return( -1 );
        }
    }
    return( 0 );
}
Esempio n. 2
0
int FfmpegCamera::Capture( Image &image )
{
    static int frameCount = 0;
    AVPacket packet;
    int frameComplete = false;
    while ( !frameComplete && (av_read_frame( mFormatContext, &packet ) >= 0) )
    {
        Debug( 5, "Got packet from stream %d", packet.stream_index );
        if ( packet.stream_index == mVideoStreamId )
        {
            if ( avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size) < 0 )
                Fatal( "Unable to decode frame at frame %d", frameCount );

            Debug( 3, "Decoded video packet at frame %d", frameCount );

            if ( frameComplete )
            {
                Debug( 1, "Got frame %d", frameCount );

#if HAVE_LIBSWSCALE
                if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 )
                    Fatal( "Unable to convert raw format %d to RGB at frame %d", mCodecContext->pix_fmt, frameCount );
#else // HAVE_LIBSWSCALE
    Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" );
#endif // HAVE_LIBSWSCALE
 
                image.Assign( mCodecContext->width, mCodecContext->height, colours, (unsigned char *)mFrame->data[0] );

                frameCount++;
            }
        }
        av_free_packet( &packet );
    }
    return (0);
}
Esempio n. 3
0
// Should not return -1 as cancels capture. Always wait for image if available.
int LibvlcCamera::Capture( Image &image )
{   
    while(!mLibvlcData.newImage.getValueImmediate())
        mLibvlcData.newImage.getUpdatedValue(1);

    mLibvlcData.mutex.lock();
    image.Assign(width, height, colours, subpixelorder, mLibvlcData.buffer, width * height * mBpp);
    mLibvlcData.newImage.setValueImmediate(false);
    mLibvlcData.mutex.unlock();
    
    return (0);
}
Esempio n. 4
0
// Should not return -1 as cancels capture. Always wait for image if available.
int LibvlcCamera::Capture(Image &image) {   

  // newImage is a mutex/condition based flag to tell us when there is an image available
  while( !mLibvlcData.newImage.getValueImmediate() ) {
    if (zm_terminate)
      return 0;
    mLibvlcData.newImage.getUpdatedValue(1);
  }

  mLibvlcData.mutex.lock();
  image.Assign(width, height, colours, subpixelorder, mLibvlcData.buffer, width * height * mBpp);
  mLibvlcData.newImage.setValueImmediate(false);
  mLibvlcData.mutex.unlock();

  return 1;
}
Esempio n. 5
0
Image *StreamBase::prepareImage( Image *image )
{
    static int last_scale = 0;
    static int last_zoom = 0;
    static int last_x = 0;
    static int last_y = 0;

    if ( !last_scale )
        last_scale = scale;
    if ( !last_zoom )
        last_zoom = zoom;

    // Do not bother to scale zoomed in images, just crop them and let the browser scale
    // Works in FF2 but breaks FF3 which doesn't like image sizes changing in mid stream.
    bool optimisedScaling = false;

    bool image_copied = false;

    int mag = (scale * zoom) / ZM_SCALE_BASE;
    int act_mag = optimisedScaling?(mag > ZM_SCALE_BASE?ZM_SCALE_BASE:mag):mag;
    Debug( 3, "Scaling by %d, zooming by %d = magnifying by %d(%d)", scale, zoom, mag, act_mag );

    int last_mag = (last_scale * last_zoom) / ZM_SCALE_BASE;
    int last_act_mag = last_mag > ZM_SCALE_BASE?ZM_SCALE_BASE:last_mag;
    Debug( 3, "Last scaling by %d, zooming by %d = magnifying by %d(%d)", last_scale, last_zoom, last_mag, last_act_mag );

    int base_image_width = image->Width(), base_image_height = image->Height();
    Debug( 3, "Base image width = %d, height = %d", base_image_width, base_image_height );

    int virt_image_width = (base_image_width * mag) / ZM_SCALE_BASE, virt_image_height = (base_image_height * mag) / ZM_SCALE_BASE;
    Debug( 3, "Virtual image width = %d, height = %d", virt_image_width, virt_image_height );

    int last_virt_image_width = (base_image_width * last_mag) / ZM_SCALE_BASE, last_virt_image_height = (base_image_height * last_mag) / ZM_SCALE_BASE;
    Debug( 3, "Last virtual image width = %d, height = %d", last_virt_image_width, last_virt_image_height );

    int act_image_width = (base_image_width * act_mag ) / ZM_SCALE_BASE, act_image_height = (base_image_height * act_mag ) / ZM_SCALE_BASE;
    Debug( 3, "Actual image width = %d, height = %d", act_image_width, act_image_height );

    int last_act_image_width = (base_image_width * last_act_mag ) / ZM_SCALE_BASE, last_act_image_height = (base_image_height * last_act_mag ) / ZM_SCALE_BASE;
    Debug( 3, "Last actual image width = %d, height = %d", last_act_image_width, last_act_image_height );

    int disp_image_width = (image->Width() * scale) / ZM_SCALE_BASE, disp_image_height = (image->Height() * scale) / ZM_SCALE_BASE;
    Debug( 3, "Display image width = %d, height = %d", disp_image_width, disp_image_height );

    int last_disp_image_width = (image->Width() * last_scale) / ZM_SCALE_BASE, last_disp_image_height = (image->Height() * last_scale) / ZM_SCALE_BASE;
    Debug( 3, "Last display image width = %d, height = %d", last_disp_image_width, last_disp_image_height );

    int send_image_width = (disp_image_width * act_mag ) / mag, send_image_height = (disp_image_height * act_mag ) / mag;
    Debug( 3, "Send image width = %d, height = %d", send_image_width, send_image_height );

    int last_send_image_width = (last_disp_image_width * last_act_mag ) / last_mag, last_send_image_height = (last_disp_image_height * last_act_mag ) / last_mag;
    Debug( 3, "Last send image width = %d, height = %d", last_send_image_width, last_send_image_height );

    if ( mag != ZM_SCALE_BASE )
    {
        if ( act_mag != ZM_SCALE_BASE )
        {
            Debug( 3, "Magnifying by %d", mag );
            if ( !image_copied )
            {
	            static Image copy_image;
                copy_image.Assign( *image );
                image = &copy_image;
                image_copied = true;
            }
            image->Scale( mag );
        }
    }

    Debug( 3, "Real image width = %d, height = %d", image->Width(), image->Height() );

    if ( disp_image_width < virt_image_width || disp_image_height < virt_image_height )
    {
        static Box last_crop;

        if ( mag != last_mag || x != last_x || y != last_y )
        {
            Debug( 3, "Got click at %d,%d x %d", x, y, mag );

            //if ( !last_mag )
                //last_mag = mag;

            if ( !(last_disp_image_width < last_virt_image_width || last_disp_image_height < last_virt_image_height) )
                last_crop = Box();

            Debug( 3, "Recalculating crop" );
            // Recalculate crop parameters, as %ges
            int click_x = (last_crop.LoX() * 100 ) / last_act_image_width; // Initial crop offset from last image
            click_x += ( x * 100 ) / last_virt_image_width;
            int click_y = (last_crop.LoY() * 100 ) / last_act_image_height; // Initial crop offset from last image
            click_y += ( y * 100 ) / last_virt_image_height;
            Debug( 3, "Got adjusted click at %d%%,%d%%", click_x, click_y );

            // Convert the click locations to the current image pixels
            click_x = ( click_x * act_image_width ) / 100;
            click_y = ( click_y * act_image_height ) / 100;
            Debug( 3, "Got readjusted click at %d,%d", click_x, click_y );

            int lo_x = click_x - (send_image_width/2);
            if ( lo_x < 0 )
                lo_x = 0;
            int hi_x = lo_x + (send_image_width-1);
            if ( hi_x >= act_image_width )
            {
                hi_x = act_image_width - 1;
                lo_x = hi_x - (send_image_width - 1);
            }

            int lo_y = click_y - (send_image_height/2);
            if ( lo_y < 0 )
                lo_y = 0;
            int hi_y = lo_y + (send_image_height-1);
            if ( hi_y >= act_image_height )
            {
                hi_y = act_image_height - 1;
                lo_y = hi_y - (send_image_height - 1);
            }
            last_crop = Box( lo_x, lo_y, hi_x, hi_y );
        }
        Debug( 3, "Cropping to %d,%d -> %d,%d", last_crop.LoX(), last_crop.LoY(), last_crop.HiX(), last_crop.HiY() );
        if ( !image_copied )
        {
	        static Image copy_image;
            copy_image.Assign( *image );
            image = &copy_image;
            image_copied = true;
        }
        image->Crop( last_crop );
    }
    last_scale = scale;
    last_zoom = zoom;
    last_x = x;
    last_y = y;

    return( image );
}
Esempio n. 6
0
int RemoteCameraRtsp::Capture( Image &image )
{
    while ( true )
    {
        buffer.clear();
        if ( !rtspThread->isRunning() )
            break;
        //if ( rtspThread->stopped() )
            //break;
        if ( rtspThread->getFrame( buffer ) )
        {
            Debug( 3, "Read frame %d bytes", buffer.size() );
            Debug( 4, "Address %p", buffer.head() );
            Hexdump( 4, buffer.head(), 16 );

            static AVFrame *tmp_picture = NULL;

            if ( !tmp_picture )
            {
                //if ( c->pix_fmt != pf )
                //{
                    tmp_picture = avcodec_alloc_frame();
                    if ( !tmp_picture )
                    {
                        Panic( "Could not allocate temporary opicture" );
                    }
                    int size = avpicture_get_size( PIX_FMT_RGB24, width, height);
                    uint8_t *tmp_picture_buf = (uint8_t *)malloc(size);
                    if (!tmp_picture_buf)
                    {
                        av_free( tmp_picture );
                        Panic( "Could not allocate temporary opicture" );
                    }
                    avpicture_fill( (AVPicture *)tmp_picture, tmp_picture_buf, PIX_FMT_RGB24, width, height );
                //}
            }

            if ( !buffer.size() )
                return( -1 );

            AVPacket packet;
            av_init_packet( &packet );
            int initialFrameCount = frameCount;
            while ( buffer.size() > 0 )
            {
                int got_picture = false;
                packet.data = buffer.head();
                packet.size = buffer.size();
                int len = avcodec_decode_video2( codecContext, picture, &got_picture, &packet );
                if ( len < 0 )
                {
                    if ( frameCount > initialFrameCount )
                    {
                        // Decoded at least one frame
                        return( 0 );
                    }
                    Error( "Error while decoding frame %d", frameCount );
                    Hexdump( ZM_DBG_ERR, buffer.head(), buffer.size()>256?256:buffer.size() );
                    buffer.clear();
                    continue;
                    //return( -1 );
                }
                Debug( 2, "Frame: %d - %d/%d", frameCount, len, buffer.size() );
                //if ( buffer.size() < 400 )
                    //Hexdump( 0, buffer.head(), buffer.size() );

                if ( got_picture )
                {
                    /* the picture is allocated by the decoder. no need to free it */
                    Debug( 1, "Got picture %d", frameCount );

                    static struct SwsContext *img_convert_ctx = 0;

                    if ( !img_convert_ctx )
                    {
                        img_convert_ctx = sws_getCachedContext( NULL, codecContext->width, codecContext->height, codecContext->pix_fmt, width, height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL );
                        if ( !img_convert_ctx )
                            Panic( "Unable to initialise image scaling context" );
                    }

                    sws_scale( img_convert_ctx, picture->data, picture->linesize, 0, height, tmp_picture->data, tmp_picture->linesize );

                    image.Assign( width, height, colours, tmp_picture->data[0] );

                    frameCount++;

                    return( 0 );
                }
                else
                {
                    Warning( "Unable to get picture from frame" );
                }
                buffer -= len;
            }
        }
    }
    return( -1 );
}