Device-WebIO-RaspberryPi

 view release on metacpan or  search on metacpan

lib/Device/WebIO/RaspberryPi.pm  view on Meta::CPAN


    my $scalar_buf = pack 'C*', @$buf;
    open( my $jpeg_fh, '<', \$scalar_buf )
        or die "Could not open ref to scalar: $!\n";

    return $jpeg_fh;
}


with 'Device::WebIO::Device::I2CProvider';

sub i2c_channels { 2 }

sub i2c_read
{
    my ($self, $channel, $addr, $register, $len) = @_;

    my $dev_str = '/dev/i2c-' . $channel;
    my $i2c = $self->_pi->i2c( $addr, $dev_str );
    my @data = $i2c->read_bytes( $len, $register );

    return @data;
}

sub i2c_write
{
    my ($self, $channel, $addr, $register, @data) = @_;

    my $dev_str = '/dev/i2c-' . $channel;
    my $i2c = $self->_pi->i2c( $addr, $dev_str );
    $i2c->write_block( \@data, $register );

    return 1;
}


has '_vid_width' => (
    is      => 'rw',
    default => sub {[
        1920
    ]},
);
has '_vid_height' => (
    is      => 'rw',
    default => sub {[
       1080 
    ]},
);
has '_vid_fps' => (
    is      => 'rw',
    default => sub {[
       30
    ]},
);
has '_vid_bitrate' => (
    is      => 'rw',
    default => sub {[
       8000
    ]},
);
has '_vid_stream_callbacks' => (
    is      => 'rw',
    default => sub {[]},
);
has '_vid_stream_callback_types' => (
    is      => 'rw',
    default => sub {[]},
);
has 'cv' => (
    is      => 'rw',
    default => sub { AnyEvent->condvar },
);
has 'vid_use_audio' => (
    is      => 'rw',
    default => sub { 0 },
);
has 'vid_audio_input_device' => (
    is      => 'rw',
    default => sub { 'hw:1,0' },
);
with 'Device::WebIO::Device::VideoOutputCallback';

sub vid_channels
{
    return 1;
}

sub vid_height
{
    my ($self, $pin) = @_;
    return $self->_vid_height->[$pin];
}

sub vid_width
{
    my ($self, $pin) = @_;
    return $self->_vid_width->[$pin];
}

sub vid_fps
{
    my ($self, $pin) = @_;
    return $self->_vid_fps->[$pin];
}

sub vid_kbps
{
    my ($self, $pin) = @_;
    return $self->_vid_bitrate->[$pin];
}

sub vid_set_width
{
    my ($self, $pin, $val) = @_;
    return $self->_vid_width->[$pin] = $val;
}

sub vid_set_height
{
    my ($self, $pin, $val) = @_;
    return $self->_vid_height->[$pin] = $val;
}

sub vid_set_fps
{
    my ($self, $pin, $val) = @_;
    return $self->_vid_fps->[$pin] = $val;
}

sub vid_set_kbps
{
    my ($self, $pin, $val) = @_;
    $val *= 1024;
    return $self->_vid_bitrate->[$pin] = $val;
}

sub vid_allowed_content_types
{
    return keys %ALLOWED_VIDEO_TYPES;
}

sub vid_stream
{
    my ($self, $pin, $type) = @_;
    die "Do not support type '$type'" unless exists $ALLOWED_VIDEO_TYPES{$type};
    $self->_init_gstreamer;
    return 1;
}

sub vid_stream_callback
{
    my ($self, $pin, $type, $callback) = @_;
    die "Do not support type '$type'" unless exists $ALLOWED_VIDEO_TYPES{$type};
    $self->_vid_stream_callbacks->[$pin] = $callback;
    $self->_vid_stream_callback_types->[$pin] = $type;
    return 1;
}

sub vid_stream_begin_loop
{
    my ($self, $channel) = @_;
    my $width    = $self->vid_width( $channel );
    my $height   = $self->vid_height( $channel );
    my $fps      = $self->vid_fps( $channel );
    my $bitrate  = $self->vid_kbps( $channel );
    my $callback = $self->_vid_stream_callbacks->[$channel];
    my $type     = $self->_vid_stream_callback_types->[$channel];
    my $use_audio = $self->vid_use_audio;
    my $audio_dev = $self->vid_audio_input_device;


    $self->_init_gstreamer;
    my $cv = $self->cv;
    my $pipeline = GStreamer1::Pipeline->new( 'pipeline' );

    my $rpi        = GStreamer1::ElementFactory::make( rpicamsrc => 'and_who' );
    my $h264parse  = GStreamer1::ElementFactory::make( h264parse => 'are_you' );
    my $capsfilter = GStreamer1::ElementFactory::make(
        capsfilter => 'the_proud_lord_said' );
    my $sink    = GStreamer1::ElementFactory::make(
        fakesink => 'that_i_should_bow_so_low' );
    my $vid_queue = GStreamer1::ElementFactory::make( 'queue' => 'only_a_cat' );

    my $muxer = ($type ne 'video/H264')
        ? $self->_get_vid_mux_by_type( $type )
        : undef;

    $rpi->set( bitrate => $bitrate );

    my $caps = GStreamer1::Caps::Simple->new( 'video/x-h264',
        width  => 'Glib::Int' => $width,
        height => 'Glib::Int' => $height,
        fps    => 'Glib::Int' => $fps,
    );
    $capsfilter->set( caps => $caps );

    $sink->set( 'signal-handoffs' => TRUE );
    $sink->signal_connect(
        'handoff' => $self->_get_vid_stream_callback( $pipeline, $cv, $callback )
    );

    $pipeline->add( $muxer ) if defined $muxer;

    if( $use_audio && defined $muxer ) {
        my $audio_src = GStreamer1::ElementFactory::make(
            'alsasrc' => 'of_a_different_coat' );
        my $audio_caps = GStreamer1::ElementFactory::make(
            capsfilter => 'the_only_truth_i_know' );
        my $mp3enc = GStreamer1::ElementFactory::make(
            lamemp3enc => 'in_a_coat_of_red' );
        my $audio_queue = GStreamer1::ElementFactory::make(
            queue => 'or_a_coat_of_gold' );

        $audio_src->set( 'device' => $audio_dev );
        $mp3enc->set( 'bitrate' => 256 );

        my $caps = GStreamer1::Caps::Simple->new( 'audio/x-raw',
            rate     => 'Glib::Int'    => 44100,
            channels => 'Glib::Int'    => 1,
            format   => 'Glib::String' => 'S16LE',
        );
        $audio_caps->set( caps => $caps );

        $pipeline->add( $_ ) for $audio_src, $audio_caps, $mp3enc, $audio_queue;
        $audio_src->link(   $audio_caps  );
        $audio_caps->link(  $mp3enc      );



( run in 3.718 seconds using v1.01-cache-2.11-cpan-97f6503c9c8 )