Video-Capture-V4l-0.902/0000755000000000000000000000000011042166057013336 5ustar rootrootVideo-Capture-V4l-0.902/V4l/0000755000000000000000000000000011042166057014003 5ustar rootrootVideo-Capture-V4l-0.902/V4l/V4l.pm0000644000000000000000000001540111042166043015002 0ustar rootrootpackage Video::Capture::V4l; use strict 'subs'; use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD); require Exporter; require DynaLoader; use Fcntl; $VERSION = '0.902'; @ISA = qw(Exporter DynaLoader); @EXPORT = qw( MODE_AUTO MODE_NTSC MODE_PAL MODE_SECAM PALETTE_GREY PALETTE_HI240 PALETTE_PLANAR PALETTE_RAW PALETTE_RGB24 PALETTE_RGB32 PALETTE_RGB555 PALETTE_RGB565 PALETTE_UYVY PALETTE_YUV410P PALETTE_YUV411 PALETTE_YUV411P PALETTE_YUV420 PALETTE_YUV420P PALETTE_YUV422 PALETTE_YUV422P PALETTE_YUYV SOUND_LANG1 SOUND_LANG2 SOUND_MONO SOUND_STEREO VBI_MAXLINES VBI_BPL VBI_BPF ); @EXPORT_OK = qw( MODE_AUTO MODE_NTSC MODE_PAL MODE_SECAM PALETTE_GREY PALETTE_HI240 PALETTE_PLANAR PALETTE_RAW PALETTE_RGB24 PALETTE_RGB32 PALETTE_RGB555 PALETTE_RGB565 PALETTE_UYVY PALETTE_YUV410P PALETTE_YUV411 PALETTE_YUV411P PALETTE_YUV420 PALETTE_YUV420P PALETTE_YUV422 PALETTE_YUV422P PALETTE_YUYV SOUND_LANG1 SOUND_LANG2 SOUND_MONO SOUND_STEREO AUDIO_MUTE AUDIO_BASS AUDIO_MUTABLE AUDIO_TREBLE AUDIO_VOLUME TUNER_LOW TUNER_MBS_ON TUNER_NORM TUNER_NTSC TUNER_PAL TUNER_RDS_ON TUNER_SECAM TUNER_STEREO_ON VC_AUDIO VC_TUNER TYPE_CAMERA TYPE_TV BASE_VIDIOCPRIVATE CAPTURE_EVEN CAPTURE_ODD CLIPMAP_SIZE CLIP_BITMAP MAX_FRAME NO_UNIT PALETTE_COMPONENT WINDOW_INTERLACE HARDWARE_AZTECH HARDWARE_BROADWAY HARDWARE_BT848 HARDWARE_CADET HARDWARE_GEMTEK HARDWARE_PERMEDIA2 HARDWARE_PLANB HARDWARE_PMS HARDWARE_PSEUDO HARDWARE_QCAM_BW HARDWARE_QCAM_C HARDWARE_RIVA128 HARDWARE_RTRACK HARDWARE_RTRACK2 HARDWARE_SAA5249 HARDWARE_SAA7146 HARDWARE_SF16MI HARDWARE_TYPHOON HARDWARE_VIDEUM HARDWARE_VINO HARDWARE_ZOLTRIX TYPE_CAPTURE TYPE_CHROMAKEY TYPE_CLIPPING TYPE_FRAMERAM TYPE_MONOCHROME TYPE_OVERLAY TYPE_SCALES TYPE_SUBCAPTURE TYPE_TELETEXT TYPE_TUNER ); # shit sub VBI_MAXLINES (){ 32 } sub VBI_BPL (){ 2048 } sub VBI_BPF (){ VBI_BPL * VBI_MAXLINES } bootstrap Video::Capture::V4l $VERSION; sub new(;$) { my $class = shift; my $device = shift || "/dev/video0"; my $self = bless { device => $device }, $class; $self->{handle} = local *{$device}; sysopen $self->{handle},$device,O_RDWR or return; $self->{fd} = fileno ($self->{handle}); $self->{capability} = _capabilities_new ($self->{fd}); $self->{picture} = _picture_new ($self->{fd}); $self->{capability}->get && $self->{picture}->get ? $self : (); } sub capability($) { shift->{capability} } sub picture($) { shift->{picture} } sub channel($$) { my $c = _channel_new ($_[0]->{fd}); $c->channel ($_[1]); $c->get ? $c : (); } sub tuner($$) { my $c = _tuner_new ($_[0]->{fd}); $c->tuner ($_[1]); $c->get ? $c : (); } sub audio($$) { my $c = _audio_new ($_[0]->{fd}); $c->audio ($_[1]); $c->get ? $c : (); } sub freq($;$) { _freq (shift->{fd},@_); } package Video::Capture::V4l::Capability; sub capture ($){ shift->type & &Video::Capture::V4l::TYPE_CAPTURE } sub tuner ($){ shift->type & &Video::Capture::V4l::TYPE_TUNER } sub teletext ($){ shift->type & &Video::Capture::V4l::TYPE_TELETEXT } sub overlay ($){ shift->type & &Video::Capture::V4l::TYPE_OVERLAY } sub chromakey ($){ shift->type & &Video::Capture::V4l::TYPE_CHROMAKEY } sub clipping ($){ shift->type & &Video::Capture::V4l::TYPE_CLIPPING } sub frameram ($){ shift->type & &Video::Capture::V4l::TYPE_FRAMERAM } sub scales ($){ shift->type & &Video::Capture::V4l::TYPE_SCALES } sub monochrome($){ shift->type & &Video::Capture::V4l::TYPE_MONOCHROME} sub subcapture($){ shift->type & &Video::Capture::V4l::TYPE_SUBCAPTURE} package Video::Capture::V4l::Channel; sub tuner ($){ shift->flags & &Video::Capture::V4l::VC_TUNER } sub audio ($){ shift->flags & &Video::Capture::V4l::VC_AUDIO } sub tv ($){ shift->type & &Video::Capture::V4l::TYPE_TV } sub camera ($){ shift->type & &Video::Capture::V4l::TYPE_CAMERA } package Video::Capture::V4l::Tuner; sub pal ($){ shift->flags & &Video::Capture::V4l::TUNER_PAL } sub ntsc ($){ shift->flags & &Video::Capture::V4l::TUNER_NTSC } sub secam ($){ shift->flags & &Video::Capture::V4l::TUNER_SECAM } sub low ($){ shift->flags & &Video::Capture::V4l::TUNER_LOW } sub norm ($){ shift->flags & &Video::Capture::V4l::TUNER_NORM } sub stereo_on ($){ shift->flags & &Video::Capture::V4l::TUNER_STEREO_ON} sub rds_on ($){ shift->flags & &Video::Capture::V4l::TUNER_RDS_ON } sub mbs_on ($){ shift->flags & &Video::Capture::V4l::TUNER_MBS_ON } package Video::Capture::V4l::Audio; sub mute ($){ shift->flags & &Video::Capture::V4l::AUDIO_MUTE } sub mutatble ($){ shift->flags & &Video::Capture::V4l::AUDIO_MUTABLE } sub volume ($){ shift->flags & &Video::Capture::V4l::AUDIO_VOLUME } sub bass ($){ shift->flags & &Video::Capture::V4l::AUDIO_BASS } sub treble ($){ shift->flags & &Video::Capture::V4l::AUDIO_TREBLE } package Video::Capture::V4l::VBI; use Fcntl; sub new(;$) { my $class = shift; my $device = shift || "/dev/vbi0"; my $self = bless { device => $device }, $class; $self->{handle} = local *{$device}; sysopen $self->{handle},$device,O_RDWR or return; $self->{fd} = fileno ($self->{handle}); $self } sub fileno($) { $_[0]->{fd} } 1; __END__ =head1 NAME Video::Capture::V4l - Perl interface to the Video4linux framegrabber interface. =head1 SYNOPSIS use Video::Capture::V4l; =head1 DESCRIPTION Not documentation AGAIN! Please see the scripts grab, inexer or vbi that are packaged in the distribution and direct any question and feature requests (as well as bug reports) to the author. =head1 Exported constants The following hideous constants are defined in the C package, but you rarely need to use them. AUDIO_BASS AUDIO_MUTABLE AUDIO_MUTE AUDIO_TREBLE AUDIO_VOLUME CAPTURE_EVEN CAPTURE_ODD MAX_FRAME MODE_AUTO MODE_NTSC MODE_PAL MODE_SECAM PALETTE_COMPONENT PALETTE_GREY PALETTE_HI240 PALETTE_PLANAR PALETTE_RAW PALETTE_RGB24 PALETTE_RGB32 PALETTE_RGB555 PALETTE_RGB565 PALETTE_UYVY PALETTE_YUV410P PALETTE_YUV411 PALETTE_YUV411P PALETTE_YUV420 PALETTE_YUV420P PALETTE_YUV422 PALETTE_YUV422P PALETTE_YUYV SOUND_LANG1 SOUND_LANG2 SOUND_MONO SOUND_STEREO TUNER_LOW TUNER_MBS_ON TUNER_NORM TUNER_NTSC TUNER_PAL TUNER_RDS_ON TUNER_SECAM TUNER_STEREO_ON TYPE_CAMERA TYPE_TV VC_AUDIO VC_TUNER TYPE_CAPTURE TYPE_CHROMAKEY TYPE_CLIPPING TYPE_FRAMERAM TYPE_MONOCHROME TYPE_OVERLAY TYPE_SCALES TYPE_SUBCAPTURE TYPE_TELETEXT TYPE_TUNER =head1 AUTHOR Marc Lehmann =head1 LICENSE This module is available under GPL only (see the file COPYING for details), if you want an exception please contact the author, who might grant exceptions freely ;) =head1 SEE ALSO perl(1). =cut Video-Capture-V4l-0.902/V4l/V4l.xs0000644000000000000000000004721710211641046015030 0ustar rootroot#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #include #include #include #include #define NEED_newCONSTSUB #include "../gppport.h" #ifndef pTHX_ #define pTHX_ #endif #define XSRETURN_bool(bool) if (bool) XSRETURN_YES; else XSRETURN_NO; #define VBI_BPF (2048*32) typedef struct video_capability *Video__Capture__V4l__Capability; typedef struct video_channel *Video__Capture__V4l__Channel; typedef struct video_audio *Video__Capture__V4l__Audio; typedef struct video_picture *Video__Capture__V4l__Picture; typedef struct video_tuner *Video__Capture__V4l__Tuner; static void attach_struct (SV *sv, size_t bytes) { void *ptr; sv = SvRV (sv); Newz (0, ptr, bytes, void*); sv_magic (sv, 0, '~', 0, bytes); mg_find(sv, '~')->mg_ptr = ptr; } static SV * new_struct (SV *sv, size_t bytes, const char *pkg) { SV *rv = newRV_noinc (sv); attach_struct (rv, bytes); return sv_bless (rv, gv_stashpv ((char *)pkg, TRUE)); } static void * old_struct (SV *sv, const char *name) { /* TODO: check name */ return mg_find (SvRV(sv), '~')->mg_ptr; } static int framesize (unsigned int format, unsigned int pixels) { if (format==VIDEO_PALETTE_RGB565) return pixels*2; if (format==VIDEO_PALETTE_RGB24) return pixels*3; if (format==VIDEO_PALETTE_RGB555) return pixels*2; if (format==VIDEO_PALETTE_HI240) return pixels*1; if (format==VIDEO_PALETTE_GREY) return pixels*1; if (format==VIDEO_PALETTE_RGB32) return pixels*4; if (format==VIDEO_PALETTE_UYVY) return pixels*2; if (format==VIDEO_PALETTE_YUYV) return pixels*2; /* everything below is very probably WRONG */ if (format==VIDEO_PALETTE_YUV410P) return pixels*2; if (format==VIDEO_PALETTE_YUV411) return pixels*2; if (format==VIDEO_PALETTE_YUV411P) return pixels*2; if (format==VIDEO_PALETTE_YUV420) return pixels*3/2; if (format==VIDEO_PALETTE_YUV420P) return pixels*3/2; if (format==VIDEO_PALETTE_YUV422) return pixels*2; if (format==VIDEO_PALETTE_YUV422P) return pixels*2; if (format==VIDEO_PALETTE_PLANAR) return pixels*2; if (format==VIDEO_PALETTE_RAW) return pixels*8; return 0; } struct private { int fd; unsigned char *mmap_base; struct video_mbuf vm; }; static int private_free (pTHX_ SV *obj, MAGIC *mg) { struct private *p = (struct private *)mg->mg_ptr; munmap (p->mmap_base, p->vm.size); return 0; } static MGVTBL vtbl_private = {0, 0, 0, 0, private_free}; static struct private * find_private (SV *sv) { HV *hv = (HV*)SvRV(sv); MAGIC *mg = mg_find ((SV*)hv, '~'); if (!mg) { struct private p; p.fd = SvIV (*hv_fetch (hv, "fd", 2, 0)); if (ioctl (p.fd, VIDIOCGMBUF, &p.vm) == 0) { p.mmap_base = (unsigned char *)mmap (0, p.vm.size, PROT_READ|PROT_WRITE, MAP_SHARED, p.fd, 0); if (p.mmap_base) { sv_magic ((SV*)hv, 0, '~', (char*)&p, sizeof p); mg = mg_find ((SV*)hv, '~'); mg->mg_virtual = &vtbl_private; } } } return (struct private *) (mg ? mg->mg_ptr : 0); } typedef unsigned char u8; typedef unsigned int UI; #define get_field(field) (*hv_fetch ((HV*)SvRV (self), #field, strlen(#field), 0)) /* only one thread currently */ typedef struct vbi_frame { struct vbi_frame *next; int size; char data[VBI_BPF]; } vbi_frame; static vbi_frame *vbi_head, *vbi_tail, *vbi_free; static int vbi_fd; static UI vbi_max; static pthread_t vbi_snatcher; static pthread_mutex_t vbi_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t vbi_cond = PTHREAD_COND_INITIALIZER; static void * vbi_snatcher_thread (void *arg) { /* try to become a realtime process. */ #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING { struct sched_param sp; sp.sched_priority = (sched_get_priority_max (SCHED_FIFO) + sched_get_priority_min (SCHED_FIFO)) / 2 - 1; pthread_setschedparam (pthread_self (), SCHED_FIFO, &sp); } #endif for(;;) { vbi_frame *next; pthread_mutex_lock (&vbi_lock); if (vbi_free) { next = vbi_free; vbi_free = vbi_free->next; pthread_mutex_unlock (&vbi_lock); next->next = 0; next->size = read (vbi_fd, next->data, VBI_BPF); pthread_mutex_lock (&vbi_lock); if (vbi_tail) vbi_tail->next = next; else vbi_head = vbi_tail = next; vbi_tail = next; vbi_max--; pthread_cond_signal (&vbi_cond); pthread_mutex_unlock (&vbi_lock); } else { static struct timespec to = { 0, 1000000000 / 70 }; /* skip almost a frame */ pthread_mutex_unlock (&vbi_lock); pthread_testcancel (); nanosleep (&to, 0); } } } MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l::VBI PROTOTYPES: ENABLE SV * field(self) SV * self CODE: int fd = SvIV(get_field(fd)); if (vbi_fd == fd) { vbi_frame *next; pthread_mutex_lock (&vbi_lock); while (!vbi_head) pthread_cond_wait (&vbi_cond, &vbi_lock); RETVAL = newSVpvn (vbi_head->data, vbi_head->size); vbi_max++; next = vbi_head->next; vbi_head->next = vbi_free; vbi_free = vbi_head; vbi_head = next; if (!next) vbi_tail = vbi_head; pthread_mutex_unlock (&vbi_lock); } else { int len; RETVAL = newSVpvn ("", 0); SvGROW (RETVAL, VBI_BPF); len = read (fd, SvPV_nolen (RETVAL), VBI_BPF); SvCUR_set (RETVAL, len); } OUTPUT: RETVAL void backlog(self,backlog) SV * self unsigned int backlog CODE: { while (vbi_max != backlog) { vbi_frame *f; pthread_mutex_lock (&vbi_lock); if (vbi_max < backlog) { f = malloc (sizeof (vbi_frame)); f->next = vbi_free; vbi_free = f; vbi_max++; } else { if (vbi_free) { f = vbi_free; vbi_free = vbi_free->next; free (f); vbi_max--; } } pthread_mutex_unlock (&vbi_lock); } if (backlog) { if (!vbi_fd) { vbi_fd = SvIV(get_field(fd)); pthread_create (&vbi_snatcher, 0, vbi_snatcher_thread, 0); } } else { if (vbi_fd) { pthread_cancel (vbi_snatcher); pthread_join (vbi_snatcher, 0); vbi_fd = 0; } /* no locking necessary, in theory */ while (vbi_head) { vbi_frame *next = vbi_head->next; free (vbi_head); vbi_head = next; } vbi_tail = 0; } } int queued(self) CODE: if (vbi_fd) { /* FIXME: lock/unlock */ pthread_mutex_lock (&vbi_lock); RETVAL = !!vbi_head; pthread_mutex_unlock (&vbi_lock); } else RETVAL = 1; OUTPUT: RETVAL MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l SV * capture(sv,frame,width,height,format = VIDEO_PALETTE_RGB24) SV *sv unsigned int frame unsigned int width unsigned int height unsigned int format CODE: { struct private *p; if ((p = find_private (sv))) { struct video_mmap vm; vm.frame = frame; vm.height = height; vm.width = width; vm.format = format; if (ioctl (p->fd, VIDIOCMCAPTURE, &vm) == 0) { SV *fr = newSV (0); SvUPGRADE (fr, SVt_PV); SvREADONLY_on (fr); SvPVX (fr) = p->mmap_base + p->vm.offsets[frame]; SvCUR_set (fr, framesize (format, width*height)); SvLEN_set (fr, 0); SvPOK_only (fr); RETVAL = fr; } else XSRETURN_EMPTY; } else XSRETURN_EMPTY; } OUTPUT: RETVAL void sync(sv,frame) SV *sv int frame PPCODE: { struct private *p; if ((p = find_private (sv)) && ioctl (p->fd, VIDIOCSYNC, &frame) == 0) XSRETURN_YES; else XSRETURN_EMPTY; } unsigned long _freq (fd,fr) int fd unsigned long fr CODE: if (items > 1) { fr = ((fr<<4)+499)/1000; ioctl (fd, VIDIOCSFREQ, &fr); } if (GIMME_V != G_VOID) { if (ioctl (fd, VIDIOCGFREQ, &fr) == 0) RETVAL = (fr*1000+7)>>4; else XSRETURN_EMPTY; } else XSRETURN (0); OUTPUT: RETVAL SV * _capabilities_new(fd) int fd CODE: RETVAL = new_struct (newSViv (fd), sizeof (struct video_capability), "Video::Capture::V4l::Capability"); OUTPUT: RETVAL SV * _channel_new(fd) int fd CODE: RETVAL = new_struct (newSViv (fd), sizeof (struct video_channel), "Video::Capture::V4l::Channel"); OUTPUT: RETVAL SV * _tuner_new(fd) int fd CODE: RETVAL = new_struct (newSViv (fd), sizeof (struct video_tuner), "Video::Capture::V4l::Tuner"); OUTPUT: RETVAL SV * _audio_new(fd) int fd CODE: RETVAL = new_struct (newSViv (fd), sizeof (struct video_audio), "Video::Capture::V4l::Audio"); OUTPUT: RETVAL SV * _picture_new(fd) int fd CODE: RETVAL = new_struct (newSViv (fd), sizeof (struct video_picture), "Video::Capture::V4l::Picture"); OUTPUT: RETVAL MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l::Capability void get(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCGCAP, old_struct (sv, "Video::Capture::V4l::Capability")) == 0); MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l::Channel void get(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCGCHAN, old_struct (sv, "Video::Capture::V4l::Channel")) == 0); void set(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCSCHAN, old_struct (sv, "Video::Capture::V4l::Channel")) == 0); MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l::Tuner void get(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCGTUNER, old_struct (sv, "Video::Capture::V4l::Tuner")) == 0); void set(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCSTUNER, old_struct (sv, "Video::Capture::V4l::Tuner")) == 0); MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l::Audio void get(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCGAUDIO, old_struct (sv, "Video::Capture::V4l::Audio")) == 0); void set(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCSAUDIO, old_struct (sv, "Video::Capture::V4l::Audio")) == 0); MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l::Picture void get(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCGPICT, old_struct (sv, "Video::Capture::V4l::Picture")) == 0); void set(sv) SV * sv CODE: XSRETURN_bool (ioctl (SvIV (SvRV (sv)), VIDIOCSPICT, old_struct (sv, "Video::Capture::V4l::Picture")) == 0); # accessors/mutators INCLUDE: ./genacc | MODULE = Video::Capture::V4l PACKAGE = Video::Capture::V4l PROTOTYPES: ENABLE BOOT: { HV *stash = gv_stashpvn("Video::Capture::V4l", 19, TRUE); newCONSTSUB(stash,"AUDIO_BASS", newSViv(VIDEO_AUDIO_BASS)); newCONSTSUB(stash,"AUDIO_MUTABLE", newSViv(VIDEO_AUDIO_MUTABLE)); newCONSTSUB(stash,"AUDIO_MUTE", newSViv(VIDEO_AUDIO_MUTE)); newCONSTSUB(stash,"AUDIO_TREBLE", newSViv(VIDEO_AUDIO_TREBLE)); newCONSTSUB(stash,"AUDIO_VOLUME", newSViv(VIDEO_AUDIO_VOLUME)); newCONSTSUB(stash,"CAPTURE_EVEN", newSViv(VIDEO_CAPTURE_EVEN)); newCONSTSUB(stash,"CAPTURE_ODD", newSViv(VIDEO_CAPTURE_ODD)); newCONSTSUB(stash,"MAX_FRAME", newSViv(VIDEO_MAX_FRAME)); newCONSTSUB(stash,"MODE_AUTO", newSViv(VIDEO_MODE_AUTO)); newCONSTSUB(stash,"MODE_NTSC", newSViv(VIDEO_MODE_NTSC)); newCONSTSUB(stash,"MODE_PAL", newSViv(VIDEO_MODE_PAL)); newCONSTSUB(stash,"MODE_SECAM", newSViv(VIDEO_MODE_SECAM)); newCONSTSUB(stash,"PALETTE_COMPONENT", newSViv(VIDEO_PALETTE_COMPONENT)); newCONSTSUB(stash,"PALETTE_GREY", newSViv(VIDEO_PALETTE_GREY)); newCONSTSUB(stash,"PALETTE_HI240", newSViv(VIDEO_PALETTE_HI240)); newCONSTSUB(stash,"PALETTE_PLANAR", newSViv(VIDEO_PALETTE_PLANAR)); newCONSTSUB(stash,"PALETTE_RAW", newSViv(VIDEO_PALETTE_RAW)); newCONSTSUB(stash,"PALETTE_RGB24", newSViv(VIDEO_PALETTE_RGB24)); newCONSTSUB(stash,"PALETTE_RGB32", newSViv(VIDEO_PALETTE_RGB32)); newCONSTSUB(stash,"PALETTE_RGB555", newSViv(VIDEO_PALETTE_RGB555)); newCONSTSUB(stash,"PALETTE_RGB565", newSViv(VIDEO_PALETTE_RGB565)); newCONSTSUB(stash,"PALETTE_UYVY", newSViv(VIDEO_PALETTE_UYVY)); newCONSTSUB(stash,"PALETTE_YUV410P", newSViv(VIDEO_PALETTE_YUV410P)); newCONSTSUB(stash,"PALETTE_YUV411", newSViv(VIDEO_PALETTE_YUV411)); newCONSTSUB(stash,"PALETTE_YUV411P", newSViv(VIDEO_PALETTE_YUV411P)); newCONSTSUB(stash,"PALETTE_YUV420", newSViv(VIDEO_PALETTE_YUV420)); newCONSTSUB(stash,"PALETTE_YUV420P", newSViv(VIDEO_PALETTE_YUV420P)); newCONSTSUB(stash,"PALETTE_YUV422", newSViv(VIDEO_PALETTE_YUV422)); newCONSTSUB(stash,"PALETTE_YUV422P", newSViv(VIDEO_PALETTE_YUV422P)); newCONSTSUB(stash,"PALETTE_YUYV", newSViv(VIDEO_PALETTE_YUYV)); newCONSTSUB(stash,"SOUND_LANG1", newSViv(VIDEO_SOUND_LANG1)); newCONSTSUB(stash,"SOUND_LANG2", newSViv(VIDEO_SOUND_LANG2)); newCONSTSUB(stash,"SOUND_MONO", newSViv(VIDEO_SOUND_MONO)); newCONSTSUB(stash,"SOUND_STEREO", newSViv(VIDEO_SOUND_STEREO)); newCONSTSUB(stash,"TUNER_LOW", newSViv(VIDEO_TUNER_LOW)); newCONSTSUB(stash,"TUNER_MBS_ON", newSViv(VIDEO_TUNER_MBS_ON)); newCONSTSUB(stash,"TUNER_NORM", newSViv(VIDEO_TUNER_NORM)); newCONSTSUB(stash,"TUNER_NTSC", newSViv(VIDEO_TUNER_NTSC)); newCONSTSUB(stash,"TUNER_PAL", newSViv(VIDEO_TUNER_PAL)); newCONSTSUB(stash,"TUNER_RDS_ON", newSViv(VIDEO_TUNER_RDS_ON)); newCONSTSUB(stash,"TUNER_SECAM", newSViv(VIDEO_TUNER_SECAM)); newCONSTSUB(stash,"TUNER_STEREO_ON", newSViv(VIDEO_TUNER_STEREO_ON)); newCONSTSUB(stash,"TYPE_CAMERA", newSViv(VIDEO_TYPE_CAMERA)); newCONSTSUB(stash,"TYPE_TV", newSViv(VIDEO_TYPE_TV)); newCONSTSUB(stash,"VC_AUDIO", newSViv(VIDEO_VC_AUDIO)); newCONSTSUB(stash,"VC_TUNER", newSViv(VIDEO_VC_TUNER)); newCONSTSUB(stash,"TYPE_CAPTURE", newSViv(VID_TYPE_CAPTURE)); newCONSTSUB(stash,"TYPE_CHROMAKEY", newSViv(VID_TYPE_CHROMAKEY)); newCONSTSUB(stash,"TYPE_CLIPPING", newSViv(VID_TYPE_CLIPPING)); newCONSTSUB(stash,"TYPE_FRAMERAM", newSViv(VID_TYPE_FRAMERAM)); newCONSTSUB(stash,"TYPE_MONOCHROME", newSViv(VID_TYPE_MONOCHROME)); newCONSTSUB(stash,"TYPE_OVERLAY", newSViv(VID_TYPE_OVERLAY)); newCONSTSUB(stash,"TYPE_SCALES", newSViv(VID_TYPE_SCALES)); newCONSTSUB(stash,"TYPE_SUBCAPTURE", newSViv(VID_TYPE_SUBCAPTURE)); newCONSTSUB(stash,"TYPE_TELETEXT", newSViv(VID_TYPE_TELETEXT)); newCONSTSUB(stash,"TYPE_TUNER", newSViv(VID_TYPE_TUNER)); } void bgr2rgb(fr) SV * fr CODE: { u8 *data, *end; end = SvEND (fr); for (data = SvPV_nolen (fr); data < end; data += 3) { data[0] ^= data[2]; data[2] ^= data[0]; data[0] ^= data[2]; } } OUTPUT: fr SV * reduce2(fr,w) SV * fr UI w CODE: { u8 *src, *dst, *end; src = SvPV_nolen (fr); dst = SvPV_nolen (fr); w *= 3; do { end = src + w; do { dst[1] = ((UI)src[0] + (UI)src[3]) >> 1; src++; dst[2] = ((UI)src[0] + (UI)src[3]) >> 1; src++; dst[0] = ((UI)src[0] + (UI)src[3]) >> 1; src++; src += 3; dst += 3; } while (src < end); src = end + w; } while (src < (u8*)SvEND (fr)); SvCUR_set (fr, dst - (u8*)SvPV_nolen (fr)); } OUTPUT: fr void normalize(fr) SV * fr CODE: { u8 mfr = 255, max = 0; u8 *src, *dst, *end; end = SvEND (fr); dst = SvPV_nolen (fr); for (src = SvPV_nolen (fr); src < end; src++) { if (*src > max) max = *src; if (*src < mfr) mfr = *src; } if (max != mfr) for (src = SvPV_nolen (fr); src < end; ) *dst++ = ((UI)*src++ - mfr) * 255 / (max-mfr); } OUTPUT: fr void findmin(db,fr,start=0,count=0) SV * db SV * fr UI start UI count PPCODE: { UI diff, min = -1; int mindata, data; u8 *src, *dst, *end, *efr; UI datasize = SvCUR (fr); UI framesize = datasize + sizeof(int); src = SvPV_nolen (db) + start * framesize; if (src < (u8*)SvPV_nolen (db) || src > (u8*)SvEND (db)) src = SvPV_nolen (db); end = src + count * framesize; if (end <= src || end > (u8*)SvEND (db)) end = SvEND (db); do { data = *((int *)src); src += sizeof (int); dst = SvPV_nolen (fr); efr = src + datasize; diff = 0; do { int dif = (int)*src++ - (int)*dst++; diff += dif*dif; } while (src < efr); if (min > diff) { min = diff; mindata = data; } } while (src < end); EXTEND (sp, 2); PUSHs (sv_2mortal (newSViv (mindata))); PUSHs (sv_2mortal (newSViv ((min << 8) / SvCUR (fr)))); } void linreg(array) SV * array PPCODE: { AV *xy = (AV*) SvRV (array); I32 i; I32 n = (av_len (xy)+1)>>1; double x_ = 0, y_ = 0; double sxy = 0, sxx = 0, syy = 0; for (i=0; i>1; double c = 0; double c2 = 0; for (i=0; i) { chomp; if (/::/) { $pkg = $_; print "\nMODULE = Video::Capture::V4l PACKAGE = $pkg\n\n"; } elsif (/^(.*?)(\w+\??)$/) { my ($type,$field) = ($1,$2); my $ro = $field =~ s/\?$//; my $get = "RETVAL = s->$field;"; my $set = "s->$field = $field;"; if ($type eq "char *") { $get = "RETVAL = s->$field;"; $set = "strcpy (s->$field, $field);"; } if ($ro) { $set = "croak (\"attribute '$field' is readonly\");"; } print < 'Video::Capture::V4l', 'VERSION_FROM' => 'V4l.pm', LIBS => '-lpthread', ); Video-Capture-V4l-0.902/VBI/0000755000000000000000000000000011042166057013756 5ustar rootrootVideo-Capture-V4l-0.902/VBI/VBI.pm0000644000000000000000000013516110333432355014742 0ustar rootrootpackage Video::Capture::VBI; =head1 NAME Video::Capture::VBI - Functions to manipulate vbi fields & lines. =head1 SYNOPSIS use Video::Capture::VBI; =head1 DESCRIPTION =over 4 =item new Create a new VBI decoder object. VBI decoding often requires state, which this object represents =item reset (NYI) Reset the state (e.g. after switching a channel). =back =cut BEGIN { require Exporter; require DynaLoader; @ISA = ('Exporter', 'DynaLoader'); $VERSION = 0.05; @EXPORT = qw( decode_field decode_vtpage decode_ansi bcd2dec VBI_VT VBI_VPS VBI_VC VBI_VDAT VBI_EMPTY VBI_OTHER VTX_COLMASK VTX_GRSEP VTX_HIDDEN VTX_BOX VTX_FLASH VTX_DOUBLE1 VTX_DOUBLE2 VTX_INVERT VTX_DOUBLE VTX_SUB VTX_S1 VTX_S2 VTX_S3 VTX_S4 VTX_C4 VTX_C5 VTX_C6 VTX_C7 VTX_C8 VTX_C9 VTX_C10 VTX_C11 VTX_NOC VTX_C12 VTX_C13 VTX_C14 ); @EXPORT_OK = qw( %VPS_CNI %VT_NI ); bootstrap Video::Capture::VBI $VERSION; } use Fcntl; =head1 CONSTANTS / MASK OPERATORS The following constants are available (see ETS 300 706 for a more thorough definition). VTX_SUB 0x003f7f # S1..S4 field mask VTX_C4 0x000080 # erase page VTX_C5 0x004000 # newsflash VTX_C6 0x008000 # subtitle VTX_C7 0x010000 # suppress header VTX_C8 0x020000 # update indicator VTX_C9 0x040000 # interrupted sequence VTX_C10 0x080000 # inhibit display VTX_C11 0x100000 # magazine serial VTX_C12 0x200000 # ... option ... VTX_C13 0x400000 # ... character ... VTX_C14 0x800000 # ... set The following mask functions all take a single "CTRL" bitfield and return the corresponding subfield: VTX_S1 (shift )&15 } # S1 VTX_S2 (shift>> 4)& 7 } # S2 VTX_S3 (shift>> 8)&15 } # S3 VTX_S4 (shift>>12)& 3 } # S4 VTX_NOC (shift>>21)& 7 } # national character set... =cut sub VTX_SUB (){ 0x003f7f } sub VTX_S1 ($){ (shift )&15 } sub VTX_S2 ($){ (shift>> 4)& 7 } sub VTX_S3 ($){ (shift>> 8)&15 } sub VTX_S4 ($){ (shift>>12)& 3 } sub VTX_C4 (){ 0x000080 } # erase page sub VTX_C5 (){ 0x004000 } # newsflash sub VTX_C6 (){ 0x008000 } # subtitle sub VTX_C7 (){ 0x010000 } # suppress header sub VTX_C8 (){ 0x020000 } # update indicator sub VTX_C9 (){ 0x040000 } # interrupted sequence sub VTX_C10 (){ 0x080000 } # inhibit display sub VTX_C11 (){ 0x100000 } # magazine serial sub VTX_NOC ($){ (shift>>21)& 7 } # national ... sub VTX_C12 (){ 0x200000 } # ... option ... sub VTX_C13 (){ 0x400000 } # ... character ... sub VTX_C14 (){ 0x800000 } # ... set { use utf8; %VPS_CNI = (0xdc1 => 'ARD bundesweit, Erstes Deutsches Fernsehen', 0xdc2 => 'ZDF bundesweit, Zweites Deutsches Fernsehen', 0xdc3 => 'ARD/ZDF / Gemeinsames Vormittagsprogramm', 0xdc4 => 'ARD-TV-Sternpunkt', 0xdc5 => 'ARD-TV-Sternpunkt-Fehlersieb, interne Störfallkennung', 0xdc6 => 'not to be used until 2003', 0xdc7 => 'Satelliten-Programm "3sat" (ARD/ZDF/ORF/SRG common programme)', 0xdc8 => 'Phoenix ARD/ZDF', 0xdc9 => 'Kinderkanal ARD/ZDF', 0xdca => 'BR-1 / Regionalprogramm', 0xdcb => 'BR-3 / landesweit (split at times)', 0xdcc => 'BR-3 / Süd', 0xdcd => 'BR-3 / Nord', 0xdce => 'HR-1 / Regionalprogramm', 0xdcf => 'Hessen 3 / landesweit', 0xdd1 => 'NDR-1 / Landesprogramm Hamburg', 0xdd2 => 'NDR-1 / Landesprogramm Niedersachsen', 0xdd3 => 'NDR-1 / Landesprogramm Schleswig-Holstein', 0xdd4 => 'Nord-3 (common 3 Programme NDR, SFB, RB, split at times)', 0xdd5 => 'NDR-3 / dreiländerweit', 0xdd6 => 'NDR-3 / Hamburg', 0xdd7 => 'NDR-3 / Niedersachsen', 0xdd8 => 'NDR-3 / Schleswig-Holstein', 0xdd9 => 'RB-1 / Regionalprogramm', 0xdda => 'RB-3 (separation from Nord 3)', 0xddb => 'SFB-1 / Regionalprogramm', 0xddc => 'SFB-3 (separation from Nord 3)', 0xddd => 'SWR-1 / Regionalprogramm Baden-Württemberg', 0xdde => 'SWR-1 / Regionalprogramm Rheinland-Pfalz', 0xddf => 'SR-1 / Regionalprogramm', 0xde0 => ' ', 0xde1 => 'SWR-BW / Regionalprogramm Baden-Württemberg', 0xde2 => 'SWR-SAAR / Regionalprogramm Saarland', 0xde3 => 'SWR-BW / Regionalprogramm Baden-Württemberg', 0xde4 => 'SWR-RHPF / Regionalprogramm Rheinland-Pfalz', 0xde5 => 'WDR-1 / Regionalprogramm', 0xde6 => 'WDR-3 / landesweit (split at times)', 0xde7 => 'WDR-3 / Bielefeld', 0xde8 => 'WDR-3 / Dortmund', 0xde9 => 'WDR-3 / Düsseldorf', 0xdea => 'WDR-3 / Köln', 0xdeb => 'WDR-3 / Münster', 0xdec => 'SWR-REG / Regionalprogramm', 0xded => 'SWR-REG / Regionalprogramm Baden-Württemberg', 0xdee => 'SWR-MA / Regionalprogramm Mannheim', 0xdef => 'SWR1 / Regionalprogramm', 0xdf0 => 'SWR1-REG / Regionalprogramm', 0xdf1 => 'NDR-1 / Landesprogramm Mecklenburg-Vorpommern', 0xdf2 => 'NDR-3 / Mecklenburg-Vorpommern', 0xdf3 => 'MDR-1 / Landesprogramm Sachsen', 0xdf4 => 'MDR-3 / Sachsen', 0xdf5 => 'MDR / Dresden', 0xdf6 => 'MDR-1 / Landesprogramm Sachsen-Anhalt', 0xdf7 => 'Lokal-Programm WDR-Dortmund', 0xdf8 => 'MDR-3 / Sachsen-Anhalt', 0xdf9 => 'MDR / Magdeburg', 0xdfa => 'MDR-1 / Landesprogramm Thüringen', 0xdfb => 'MDR-3 / Thüringen', 0xdfc => 'MDR / Erfurt', 0xdfd => 'MDR-1 / Regionalprogramm', 0xdfe => 'MDR-3 / landesweit', 0xd81 => 'ORB-1 / Regionalprogramm', 0xd82 => 'ORB-3 / landesweit', 0xd83 => 'not to be used until 2001', 0xd84 => 'not to be used until 2001', 0xd85 => 'Arte', 0xd86 => 'not to be used until 2001', 0xd87 => '1A-Fernsehen', 0xd88 => 'VIVA', 0xd89 => 'VIVA 2', 0xd8a => 'Super RTL', 0xd8b => 'RTL Club', 0xd8c => 'n-tv', 0xd8d => 'Deutsches Sportfernsehen', 0xd8e => 'VOX Fernsehen', 0xd8f => 'RTL 2', 0xd90 => 'RTL 2 / regional', 0xd91 => 'Eurosport', 0xd92 => 'Kabel 1', 0xd93 => 'not to be used until 2003', 0xd94 => 'PRO 7', 0xd95 => 'SAT 1 / Brandenburg', 0xd96 => 'SAT 1 / Thüringen', 0xd97 => 'SAT 1 / Sachsen', 0xd98 => 'SAT 1 / Mecklenburg-Vorpommern', 0xd99 => 'SAT 1 / Sachsen-Anhalt', 0xd9a => 'RTL / Regional', 0xd9b => 'RTL / Schleswig-Holstein', 0xd9c => 'RTL / Hamburg', 0xd9d => 'RTL / Berlin', 0xd9e => 'RTL / Niedersachsen', 0xd9f => 'RTL / Bremen', 0xda0 => 'RTL / Nordrhein-Westfalen', 0xda1 => 'RTL / Hessen', 0xda2 => 'RTL / Rheinland-Pfalz', 0xda3 => 'RTL / Baden-Württemberg', 0xda4 => 'RTL / Bayern', 0xda5 => 'RTL / Saarland', 0xda6 => 'RTL / Sachsen-Anhalt', 0xda7 => 'RTL / Mecklenburg-Vorpommern', 0xda8 => 'RTL / Sachsen', 0xda9 => 'RTL / Thüringen', 0xdaa => 'RTL / Brandenburg', 0xdab => 'RTL Plus', 0xdac => 'Premiere', 0xdad => 'SAT 1 / Regional', 0xdae => 'SAT 1 / Schleswig-Holstein', 0xdaf => 'SAT 1 / Hamburg', 0xdb0 => 'SAT 1 / Berlin', 0xdb1 => 'SAT 1 Niedersachsen', 0xdb2 => 'SAT 1 / Bremen', 0xdb3 => 'SAT 1 Nordrhein-Westfalen', 0xdb4 => 'SAT 1 / Hessen', 0xdb5 => 'SAT 1 / Rheinland-Pfalz', 0xdb6 => 'SAT 1 / Baden-Württemberg', 0xdb7 => 'SAT 1 / Bayern', 0xdb8 => 'SAT 1 / Saarland', 0xdb9 => 'SAT 1', 0xdba => 'NEUN LIVE', 0xdbb => 'Deutsche Welle Fernsehen Berlin', 0xdbc => 'not to be used until 2002', 0xdbd => 'Berlin-Offener Kanal', 0xdbe => 'Berlin-Mix-Channel II', 0xdbf => 'Berlin-Mix-Channel 1', 0xd41 => 'FESTIVAL', 0xd42 => 'MUXX', 0xd43 => 'EXTRA', 0xd74 => 'NICK', 0xd75 => 'KDG INFO', 0xd76 => 'D VIERTE', 0xd77 => '1-2-3.TV', 0xd78 => 'TELE-5', 0xd79 => 'RTL SHOP', 0xd7a => 'N24', 0xd7b => 'TV.B', 0xd7c => 'ONYX-TV', 0xd7d => 'QVC-Teleshopping', 0xd7e => 'Nickelodeon', 0xd7f => 'Home Shopping Europe', 0x4c1 => 'SRG, Schweizer Fernsehen DRS, SF 1', 0x4c2 => 'SSR, Télévision Suisse Romande, TSR 1', 0x4c3 => 'SSR, Televisione svizzera di lingua italiana, TSI 1', 0x4c4 => 'not to be used until 2004', 0x4c5 => 'not to be used until 2004', 0x4c6 => 'not to be used until 2007', 0x4c7 => 'SRG, Schweizer Fernsehen DRS, SF 2', 0x4c8 => 'SSR, Télévision Suisse Romande, TSR 2', 0x4c9 => 'SSR, Televisione svizzera di lingua italiana, TSI 2', 0x4ca => 'SRG SSR Sat Access', 0x481 => 'TeleZüri', 0x482 => 'Teleclub Abonnements-Fernsehen', 0x483 => '- ', 0x484 => 'TeleBern', 0x485 => 'Tele M1', 0x486 => 'Star TV', 0x487 => 'Pro 7', 0x488 => 'TopTV', 0xac1 => 'ORF - FS 1', 0xac2 => 'ORF - FS 2', 0xac3 => 'ORF - FS 3', 0xaca => 'ATV+', 0xacb => 'ORF - FS 2 / Lokalprogramm Burgenland', 0xacc => 'ORF - FS 2 / Lokalprogramm Kärnten', 0xacd => 'ORF - FS 2 / Lokalprogramm Niederösterreich', 0xace => 'ORF - FS 2 / Lokalprogramm Oberösterreich', 0xacf => 'ORF - FS 2 / Lokalprogramm Salzburg', 0xad0 => 'ORF - FS 2 / Lokalprogramm Steiermark', 0xad1 => 'ORF - FS 2 / Lokalprogramm Tirol', 0xad2 => 'ORF - FS 2 / Lokalprogramm Vorarlberg', 0xad3 => 'ORF - FS 2 / Lokalprogramm Wien', 0x7c0 => 'Studio 1+1', 0x7c8 => 'Novy Kanal', 0x7c5 => 'M1'); %VT_NI = (0x4301 => ['ORF-1', 'Austria'], 0x4302 => ['ORF-2', 'Austria'], 0x4303 => ['ORF future use', 'Austria'], 0x4304 => ['ORF future use', 'Austria'], 0x4305 => ['ORF future use', 'Austria'], 0x4306 => ['ORF future use', 'Austria'], 0x4307 => ['ORF future use', 'Austria'], 0x4308 => ['ORF future use', 'Austria'], 0x4309 => ['ORF future use', 'Austria'], 0x430a => ['ORF future use', 'Austria'], 0x430b => ['ORF future use', 'Austria'], 0x430c => ['ATV', 'Austria'], 0x320c => ['AB3', 'Belgium'], 0x320d => ['AB4e', 'Belgium'], 0x3201 => ['VRT TV1', 'Belgium', 0x1601, 0x3603], 0x3202 => ['CANVAS', 'Belgium', 0x1602, 0x3602], 0x3203 => ['RTBF 1', 'Belgium'], 0x3204 => ['RTBF 2', 'Belgium'], 0x3205 => ['VTM', 'Belgium', 0x1605, 0x3605], 0x3206 => ['Kanaal2', 'Belgium', 0x1606, 0x3606], 0x3207 => ['RTBF Sat', 'Belgium'], 0x3208 => ['RTBF future use', 'Belgium'], 0x3209 => ['RTL-TVI', 'Belgium'], 0x320a => ['CLUB-RTL', 'Belgium'], 0x0404 => ['VT4', 'Belgium', 0x1604, 0x3604], 0x320f => ['JIM.tv', 'Belgium'], 0x3225 => ['PLUG TV', 'Belgium'], 0x3210 => ['RTV-Kempen', 'Belgium'], 0x3211 => ['RTV-Mechelen', 'Belgium'], 0x3212 => ['MCM Belgium', 'Belgium'], 0x3213 => ['Vitaya', 'Belgium'], 0x3214 => ['WTV', 'Belgium'], 0x3215 => ['FocusTV', 'Belgium'], 0x3216 => ['Be 1 ana', 'Belgium'], 0x3217 => ['Be 1 num', 'Belgium'], 0x3218 => ['Be Ciné 1', 'Belgium'], 0x3219 => ['Be Sport 1', 'Belgium'], 0x32a7 => ['Be 1 + 1h', 'Belgium'], 0x32a8 => ['Be Ciné 2', 'Belgium'], 0x32a9 => ['Be Sport 2', 'Belgium'], 0x321a => ['PRIME Sport 1', 'Belgium'], 0x321b => ['PRIME SPORT 2', 'Belgium'], 0x321c => ['PRIME Action', 'Belgium'], 0x321d => ['PRIME One', 'Belgium'], 0x3221 => ['TV Limburg', 'Belgium'], 0x3222 => ['Kanaal 3', 'Belgium'], 0x320e => ['Ring TV', 'Belgium'], 0x321e => ['TV Brussel', 'Belgium'], 0x321f => ['AVSe', 'Belgium'], 0x3223 => ['ATV', 'Belgium'], 0x3224 => ['ROB TV', 'Belgium'], 0x3230 => ['Télé Bruxelles', 'Belgium'], 0x3231 => ['Télésambre', 'Belgium'], 0x3232 => ['TV Com', 'Belgium'], 0x3233 => ['Canal Zoom', 'Belgium'], 0x3234 => ['Vidéoscope', 'Belgium'], 0x3235 => ['Canal C', 'Belgium'], 0x3236 => ['Télé MB', 'Belgium'], 0x3237 => ['Antenne Centre', 'Belgium'], 0x3238 => ['Télévesdre', 'Belgium'], 0x3239 => ['RTC Télé Liège', 'Belgium'], 0x3240 => ['No tele', 'Belgium'], 0x3241 => ['TV Lux', 'Belgium'], 0x325a => ['Kanaal Z - NL', 'Belgium'], 0x325b => ['CANAL Z - FR', 'Belgium'], 0x326a => ['CARTOON Network - NL', 'Belgium'], 0x326b => ['CARTOON Network - FR', 'Belgium'], 0x327a => ['LIBERTY CHANNEL - NL', 'Belgium'], 0x327b => ['LIBERTY CHANNEL - FR', 'Belgium'], 0x328a => ['TCM - NL', 'Belgium'], 0x328b => ['TCM - FR', 'Belgium'], 0x3298 => ['Mozaiek/Mosaique', 'Belgium'], 0x3299 => ['Info Kanaal/Canal Info', 'Belgium'], 0x3226 => ['Sporza', 'Belgium'], 0x3227 => ['VIJF tv', 'Belgium'], 0x0385 => ['HRT', 'Croatia'], 0x4201 => ['Republic CT 1', 'Czech', 0x32c1, 0x3c21], 0x4202 => ['Republic CT 2', 'Czech', 0x32c2, 0x3c22], 0x4231 => ['Republic CT1 Regional', 'Czech', 0x32f1, 0x3c25], 0x4211 => ['Republic CT1 Regional, Brno', 'Czech', 0x32d1, 0x3b01], 0x4221 => ['Republic CT1 Regional, Ostravia', 'Czech', 0x32e1, 0x3b02], 0x4232 => ['Republic CT2 Regional', 'Czech', 0x32f2, 0x3b03], 0x4212 => ['Republic CT2 Regional, Brno', 'Czech', 0x32d2, 0x3b04], 0x4222 => ['Republic CT2 Regional, Ostravia', 'Czech', 0x32e2, 0x3b05], 0x4203 => ['Republic NOVA TV', 'Czech', 0x32c3, 0x3c23], 0x4204 => ['Republic Prima TV', 'Czech', 0x32c4, 0x3c04], 0x4205 => ['Republic TV Praha', 'Czech'], 0x4206 => ['Republic TV HK', 'Czech'], 0x4207 => ['Republic TV Pardubice', 'Czech'], 0x4208 => ['Republic TV Brno', 'Czech'], 0x4504 => ['Discovery Denmark', 'Denmark'], 0x7392 => ['DR1', 'Denmark', 0x2901, 0x3901], 0x49cf => ['DR2', 'Denmark', 0x2903, 0x3903], 0x4502 => ['TV 2', 'Denmark', 0x2902, 0x3902], 0x4503 => ['TV 2 Zulu', 'Denmark', 0x2904, 0x3904], 0x4505 => ['TV 2 Charlie', 'Denmark', 0x2905], 0x4508 => ['TV 2 Film', 'Denmark', 0x2908], 0x4506 => ['TV Danmark', 'Denmark', 0x2906], 0x4507 => ['Kanal 5', 'Denmark', 0x2907], 0x358f => ['OWL3', 'Finland', 0x260f, 0x3614], 0x3583 => ['YLE future use', 'Finland', 0x2603, 0x3608], 0x3584 => ['YLE future use', 'Finland', 0x2604, 0x3609], 0x3585 => ['YLE future use', 'Finland', 0x2605, 0x360a], 0x3586 => ['YLE future use', 'Finland', 0x2606, 0x360b], 0x3587 => ['YLE future use', 'Finland', 0x2607, 0x360c], 0x3588 => ['YLE future use', 'Finland', 0x2608, 0x360d], 0x3589 => ['YLE future use', 'Finland', 0x2609, 0x360e], 0x358a => ['YLE future use', 'Finland', 0x260a, 0x360f], 0x358b => ['YLE future use', 'Finland', 0x260b, 0x3610], 0x358c => ['YLE future use', 'Finland', 0x260c, 0x3611], 0x358d => ['YLE future use', 'Finland', 0x260d, 0x3612], 0x358e => ['YLE future use', 'Finland', 0x260e, 0x3613], 0x3581 => ['YLE1', 'Finland', 0x2601, 0x3601], 0x3582 => ['YLE2', 'Finland', 0x2602, 0x3607], 0x33c1 => ['AB1', 'France', 0x2fc1, 0x3f41], 0x3320 => ['Aqui TV', 'France', 0x2f20, 0x3f20], 0x330a => ['Arte / La Cinquième', 'France', 0x2f0a, 0x3f0a], 0x33c2 => ['Canal J', 'France', 0x2fc2, 0x3f42], 0x33c3 => ['Canal Jimmy', 'France', 0x2fc3, 0x3f43], 0x33f4 => ['Canal+', 'France', 0x2f04, 0x3f04], 0xfe01 => ['Euronews', 'France', 0x2fe1, 0x3f61], 0xf101 => ['Eurosport', 'France', 0x2fe2, 0x3f62], 0xf102 => ['Eurosport2', 'France', 0x2fe3, 0x3f63], 0xf103 => ['Eurosportnews', 'France', 0x2fe4, 0x3f64], 0x33f2 => ['France 2', 'France', 0x2f02, 0x3f02], 0x33f3 => ['France 3', 'France', 0x2f03, 0x3f03], 0x33c5 => ['La Chaîne Météo', 'France', 0x2fc5, 0x3f45], 0x33c4 => ['LCI', 'France', 0x2fc4, 0x3f44], 0x33f6 => ['M6', 'France', 0x2f06, 0x3f06], 0x33c6 => ['MCM', 'France', 0x2fc6, 0x3f46], 0x33c8 => ['Paris Première', 'France', 0x2fc8, 0x3f48], 0x33c9 => ['Planète', 'France', 0x2fc9, 0x3f49], 0x3311 => ['RFO1', 'France', 0x2f11, 0x3f11], 0x3312 => ['RFO2', 'France', 0x2f12, 0x3f12], 0x33b2 => ['Sailing Channel', 'France'], 0x33ca => ['Série Club', 'France', 0x2fca, 0x3f4a], 0x33cb => ['Télétoon', 'France', 0x2fcb, 0x3f4b], 0x33cc => ['Téva', 'France', 0x2fcc, 0x3f4c], 0x33f1 => ['TF1', 'France', 0x2f01, 0x3f01], 0x3321 => ['TLM', 'France', 0x2f21, 0x3f21], 0x3322 => ['TLT', 'France', 0x2f22, 0x3f22], 0x33c7 => ['TMC Monte-Carlo', 'France', 0x2fc7, 0x3f47], 0xf500 => ['TV5', 'France', 0x2fe5, 0x3f65], 0x49c7 => ['3SAT', 'Germany'], 0x4901 => ['ARD', 'Germany'], 0x49c1 => ['ARD future use', 'Germany'], 0x49c3 => ['ARD future use', 'Germany'], 0x49c4 => ['ARD future use', 'Germany'], 0x49c5 => ['ARD future use', 'Germany'], 0x49c6 => ['ARD future use', 'Germany'], 0x49ca => ['ARD future use', 'Germany'], 0x49cc => ['ARD future use', 'Germany'], 0x49cd => ['ARD future use', 'Germany'], 0x49ce => ['ARD future use', 'Germany'], 0x49d0 => ['ARD future use', 'Germany'], 0x49d1 => ['ARD future use', 'Germany'], 0x49d2 => ['ARD future use', 'Germany'], 0x49d3 => ['ARD future use', 'Germany'], 0x49d5 => ['ARD future use', 'Germany'], 0x49d6 => ['ARD future use', 'Germany'], 0x49d7 => ['ARD future use', 'Germany'], 0x49d8 => ['ARD future use', 'Germany'], 0x49da => ['ARD future use', 'Germany'], 0x49db => ['ARD future use', 'Germany'], 0x49dd => ['ARD future use', 'Germany'], 0x49de => ['ARD future use', 'Germany'], 0x49e0 => ['ARD future use', 'Germany'], 0x49e2 => ['ARD future use', 'Germany'], 0x49e3 => ['ARD future use', 'Germany'], 0x49e5 => ['ARD future use', 'Germany'], 0x49e7 => ['ARD future use', 'Germany'], 0x49e8 => ['ARD future use', 'Germany'], 0x49e9 => ['ARD future use', 'Germany'], 0x49ea => ['ARD future use', 'Germany'], 0x49eb => ['ARD future use', 'Germany'], 0x49ec => ['ARD future use', 'Germany'], 0x49ed => ['ARD future use', 'Germany'], 0x49ee => ['ARD future use', 'Germany'], 0x49ef => ['ARD future use', 'Germany'], 0x49f0 => ['ARD future use', 'Germany'], 0x49f1 => ['ARD future use', 'Germany'], 0x49f2 => ['ARD future use', 'Germany'], 0x49f3 => ['ARD future use', 'Germany'], 0x49f4 => ['ARD future use', 'Germany'], 0x49f5 => ['ARD future use', 'Germany'], 0x49f6 => ['ARD future use', 'Germany'], 0x49f7 => ['ARD future use', 'Germany'], 0x49f8 => ['ARD future use', 'Germany'], 0x49f9 => ['ARD future use', 'Germany'], 0x49fa => ['ARD future use', 'Germany'], 0x49fb => ['ARD future use', 'Germany'], 0x49fc => ['ARD future use', 'Germany'], 0x49fd => ['ARD future use', 'Germany'], 0x4981 => ['ARD future use', 'Germany'], 0x490a => ['Arte', 'Germany'], 0x49cb => ['BR', 'Germany'], 0x4944 => ['BR-Alpha', 'Germany'], 0x4943 => ['EXTRA', 'Germany'], 0x4941 => ['Festival', 'Germany'], 0x49ff => ['HR', 'Germany'], 0x49c9 => ['Kinderkanal', 'Germany'], 0x49fe => ['MDR', 'Germany'], 0x4942 => ['MUXX', 'Germany'], 0x49d4 => ['NDR', 'Germany'], 0x4982 => ['ORB', 'Germany'], 0x4908 => ['Phoenix', 'Germany'], 0x5c49 => ['QVC D Gmbh', 'Germany'], 0x49d9 => ['RB', 'Germany'], 0x49dc => ['SFB', 'Germany'], 0x49df => ['SR', 'Germany'], 0x49e1 => ['SWR-BW', 'Germany'], 0x49e4 => ['SWR-RP', 'Germany'], 0x49bd => ['1-2-3.TV', 'Germany'], 0x49be => ['TELE-5', 'Germany'], 0x49bf => ['Home Shopping Europe', 'Germany'], 0x490c => ['VOX Television', 'Germany'], 0x49e6 => ['WDR', 'Germany'], 0x4902 => ['ZDF', 'Germany'], 0x3004 => ['ET future use', 'Greece', 0x2104, 0x3104], 0x3005 => ['ET future use', 'Greece', 0x2105, 0x3105], 0x3006 => ['ET future use', 'Greece', 0x2106, 0x3106], 0x3007 => ['ET future use', 'Greece', 0x2107, 0x3107], 0x3008 => ['ET future use', 'Greece', 0x2108, 0x3108], 0x3009 => ['ET future use', 'Greece', 0x2109, 0x3109], 0x300a => ['ET future use', 'Greece', 0x210a, 0x310a], 0x300b => ['ET future use', 'Greece', 0x210b, 0x310b], 0x300c => ['ET future use', 'Greece', 0x210c, 0x310c], 0x300d => ['ET future use', 'Greece', 0x210d, 0x310d], 0x300e => ['ET future use', 'Greece', 0x210e, 0x310e], 0x300f => ['ET future use', 'Greece', 0x210f, 0x310f], 0x3001 => ['ET-1', 'Greece', 0x2101, 0x3101], 0x3003 => ['ET-3', 'Greece', 0x2103, 0x3103], 0x3002 => ['NET', 'Greece', 0x2102, 0x3102], 0x3636 => ['Duna Televizio', 'Hungary'], 0x3601 => ['MTV1', 'Hungary'], 0x3681 => ['MTV1 future use', 'Hungary'], 0x3611 => ['MTV1 regional, Budapest', 'Hungary'], 0x3651 => ['MTV1 regional, Debrecen', 'Hungary'], 0x3661 => ['MTV1 regional, Miskolc', 'Hungary'], 0x3621 => ['MTV1 regional, Pécs', 'Hungary'], 0x3631 => ['MTV1 regional, Szeged', 'Hungary'], 0x3641 => ['MTV1 regional, Szombathely', 'Hungary'], 0x3602 => ['MTV2', 'Hungary'], 0x3682 => ['MTV2 future use', 'Hungary'], 0x3622 => ['tv2', 'Hungary'], 0x3620 => ['tv2 future use', 'Hungary'], 0x3541 => ['Rikisutvarpid-Sjonvarp', 'Iceland'], 0x3532 => ['Network 2', 'Ireland', 0x4202, 0x3202], 0x3534 => ['RTE future use', 'Ireland', 0x4204, 0x3204], 0x3535 => ['RTE future use', 'Ireland', 0x4205, 0x3205], 0x3536 => ['RTE future use', 'Ireland', 0x4206, 0x3206], 0x3537 => ['RTE future use', 'Ireland', 0x4207, 0x3207], 0x3538 => ['RTE future use', 'Ireland', 0x4208, 0x3208], 0x3539 => ['RTE future use', 'Ireland', 0x4209, 0x3209], 0x353a => ['RTE future use', 'Ireland', 0x420a, 0x320a], 0x353b => ['RTE future use', 'Ireland', 0x420b, 0x320b], 0x353c => ['RTE future use', 'Ireland', 0x420c, 0x320c], 0x353d => ['RTE future use', 'Ireland', 0x420d, 0x320d], 0x353e => ['RTE future use', 'Ireland', 0x420e, 0x320e], 0x353f => ['RTE future use', 'Ireland', 0x420f, 0x320f], 0x3531 => ['RTE1', 'Ireland', 0x4201, 0x3201], 0x3533 => ['Teilifis na Gaeilge', 'Ireland', 0x4203, 0x3203], 0x3333 => ['TV3', 'Ireland'], 0x3901 => ['RAI 1', 'Italy'], 0x3902 => ['RAI 2', 'Italy'], 0x3903 => ['RAI 3', 'Italy'], 0x3904 => ['Rete A', 'Italy'], 0x3905 => ['Canale Italia', 'Italy', 0x1505], 0x3909 => ['Telenova', 'Italy'], 0x390a => ['Arte', 'Italy'], 0x3910 => ['TRS TV', 'Italy'], 0x3911 => ['Sky Cinema Classic', 'Italy', 0x1511], 0x3912 => ['Sky Future use (canale 109)', 'Italy', 0x1512], 0x3913 => ['Sky Calcio 1', 'Italy', 0x1513], 0x3914 => ['Sky Calcio 2', 'Italy', 0x1514], 0x3915 => ['Sky Calcio 3', 'Italy', 0x1515], 0x3916 => ['Sky Calcio 4', 'Italy', 0x1516], 0x3917 => ['Sky Calcio 5', 'Italy', 0x1517], 0x3918 => ['Sky Calcio 6', 'Italy', 0x1518], 0x3919 => ['Sky Calcio 7', 'Italy', 0x1519], 0x3920 => ['RaiNews24', 'Italy'], 0x3921 => ['RAI Med', 'Italy'], 0x3922 => ['RAI Sport', 'Italy'], 0x3923 => ['RAI Educational', 'Italy'], 0x3924 => ['RAI Edu Lab', 'Italy'], 0x3925 => ['RAI Nettuno 1', 'Italy'], 0x3926 => ['RAI Nettuno 2', 'Italy'], 0x3927 => ['Camera Deputati', 'Italy'], 0x3928 => ['RAI Mosaico', 'Italy'], 0x3929 => ['RAI future use', 'Italy'], 0x392a => ['RAI future use', 'Italy'], 0x392b => ['RAI future use', 'Italy'], 0x392c => ['RAI future use', 'Italy'], 0x392d => ['RAI future use', 'Italy'], 0x392e => ['RAI future use', 'Italy'], 0x392f => ['RAI future use', 'Italy'], 0x3930 => ['Discovery Italy', 'Italy'], 0x3933 => ['MTV Italia', 'Italy'], 0x3934 => ['MTV Brand New', 'Italy'], 0x3935 => ['MTV Hits', 'Italy'], 0x3938 => ['RTV38', 'Italy'], 0x3939 => ['GAY TV', 'Italy'], 0x3940 => ['Video Italia', 'Italy'], 0x3941 => ['SAT 2000', 'Italy'], 0x3942 => ['Jimmy', 'Italy', 0x1542], 0x3943 => ['Planet', 'Italy', 0x1543], 0x3944 => ['Cartoon Network', 'Italy', 0x1544], 0x3945 => ['Boomerang', 'Italy', 0x1545], 0x3946 => ['CNN International', 'Italy', 0x1546], 0x3947 => ['Cartoon Network +1', 'Italy', 0x1547], 0x3948 => ['Sky Sports 3', 'Italy', 0x1548], 0x3949 => ['Sky Diretta Gol', 'Italy', 0x1549], 0x3950 => ['RAISat Album', 'Italy'], 0x3951 => ['RAISat Art', 'Italy'], 0x3952 => ['RAISat Cinema', 'Italy'], 0x3953 => ['RAISat Fiction', 'Italy'], 0x3954 => ['RAISat GamberoRosso', 'Italy'], 0x3955 => ['RAISat Ragazzi', 'Italy'], 0x3956 => ['RAISat Show', 'Italy'], 0x3957 => ['RAISat G. Rosso interattivo', 'Italy'], 0x3958 => ['RAISat future use', 'Italy'], 0x3959 => ['RAISat future use', 'Italy'], 0x395a => ['RAISat future use', 'Italy'], 0x395b => ['RAISat future use', 'Italy'], 0x395c => ['RAISat future use', 'Italy'], 0x395d => ['RAISat future use', 'Italy'], 0x395e => ['RAISat future use', 'Italy'], 0x395f => ['RAISat future use', 'Italy'], 0x3960 => ['SCI FI CHANNEL', 'Italy', 0x1560], 0x3961 => ['Discovery Civilisations', 'Italy'], 0x3962 => ['Discovery Travel and Adventure', 'Italy'], 0x3963 => ['Discovery Science', 'Italy'], 0x3968 => ['Sky Meteo24', 'Italy', 0x1568], 0x3970 => ['Sky Cinema 2', 'Italy'], 0x3971 => ['Sky Cinema 3', 'Italy'], 0x3972 => ['Sky Cinema Autore', 'Italy'], 0x3973 => ['Sky Cinema Max', 'Italy'], 0x3974 => ['Sky Cinema 16:9', 'Italy'], 0x3975 => ['Sky Sports 2', 'Italy'], 0x3976 => ['Sky TG24', 'Italy'], 0x3977 => ['Fox', 'Italy', 0x1577], 0x3978 => ['Foxlife', 'Italy', 0x1578], 0x3979 => ['National Geographic Channel', 'Italy', 0x1579], 0x3980 => ['A1', 'Italy', 0x1580], 0x3981 => ['History Channel', 'Italy', 0x1581], 0x3985 => ['FOX KIDS', 'Italy'], 0x3986 => ['PEOPLE TV – RETE 7', 'Italy'], 0x3987 => ['FOX KIDS +1', 'Italy'], 0x3988 => ['LA7', 'Italy'], 0x3989 => ['PrimaTV', 'Italy'], 0x398a => ['SportItalia', 'Italy'], 0x3990 => ['STUDIO UNIVERSAL', 'Italy', 0x1590], 0x3991 => ['Marcopolo', 'Italy', 0x1591], 0x3992 => ['Alice', 'Italy', 0x1592], 0x3993 => ['Nuvolari', 'Italy', 0x1593], 0x3994 => ['Leonardo', 'Italy', 0x1594], 0x3996 => ['SUPERPIPPA CHANNEL', 'Italy', 0x1596], 0x3997 => ['Sky Sports 1', 'Italy'], 0x3998 => ['Sky Cinema 1', 'Italy'], 0x3999 => ['Tele+3', 'Italy'], 0x39a0 => ['Sky Calcio 8', 'Italy', 0x15a0], 0x39a1 => ['Sky Calcio 9', 'Italy', 0x15a1], 0x39a2 => ['Sky Calcio 10', 'Italy', 0x15a2], 0x39a3 => ['Sky Calcio 11', 'Italy', 0x15a3], 0x39a4 => ['Sky Calcio 12', 'Italy', 0x15a4], 0x39a5 => ['Sky Calcio 13', 'Italy', 0x15a5], 0x39a6 => ['Sky Calcio 14', 'Italy', 0x15a6], 0x39a7 => ['Telesanterno', 'Italy', 0x15a7], 0x39a8 => ['Telecentro', 'Italy', 0x15a8], 0x39a9 => ['Telestense', 'Italy', 0x15a9], 0x39b0 => ['Disney Channel +1', 'Italy', 0x15b0], 0x39b1 => ['Sailing Channel', 'Italy'], 0x39b2 => ['Disney Channel', 'Italy', 0x15b2], 0x39b3 => ['7 Gold-Sestra Rete', 'Italy', 0x15b3], 0x39b4 => ['Rete 8-VGA', 'Italy', 0x15b4], 0x39b5 => ['Nuovarete', 'Italy', 0x15b5], 0x39b6 => ['Radio Italia TV', 'Italy', 0x15b6], 0x39b7 => ['Rete 7', 'Italy', 0x15b7], 0x39b8 => ['E! Entertainment Television', 'Italy', 0x15b8], 0x39b9 => ['Toon Disney', 'Italy', 0x15b9], 0x39c7 => ['Bassano TV', 'Italy', 0x15c7], 0x39c8 => ['ESPN Classic Sport', 'Italy', 0x15c8], 0x39ca => ['VIDEOLINA', 'Italy'], 0x39d2 => ['Mediaset Premium 1', 'Italy', 0x15d2], 0x39d3 => ['Mediaset Premium 2', 'Italy', 0x15d3], 0x39d4 => ['Mediaset Premium 3', 'Italy', 0x15d4], 0x39d5 => ['Mediaset Premium 4', 'Italy', 0x15d5], 0x39d1 => ['Mediaset Premium 5', 'Italy', 0x15d1], 0x39d6 => ['BOING', 'Italy', 0x15d6], 0x39d7 => ['Playlist Italia', 'Italy', 0x15d7], 0x39d8 => ['MATCH MUSIC', 'Italy', 0x15d8], 0x39e1 => ['National Geographic +1', 'Italy', 0x15e1], 0x39e2 => ['History Channel +1', 'Italy', 0x15e2], 0x39e3 => ['Sky TV', 'Italy', 0x15e3], 0x39e4 => ['GXT', 'Italy', 0x15e4], 0x39e5 => ['Playhouse Disney', 'Italy', 0x15e5], 0x39e6 => ['Sky Canale 224', 'Italy', 0x15e6], 0x39f1 => ['Teleradiocity', 'Italy'], 0x39f2 => ['Teleradiocity Genova', 'Italy'], 0x39f3 => ['Teleradiocity Lombardia', 'Italy'], 0x39f4 => ['Telestar Piemonte', 'Italy'], 0x39f5 => ['Telestar Liguria', 'Italy'], 0x39f6 => ['Telestar Lombardia', 'Italy'], 0x39f7 => ['Italia 8 Piemonte', 'Italy'], 0x39f8 => ['Italia 8 Lombardia', 'Italy'], 0xfa04 => ['Rete 4', 'Italy'], 0xfa05 => ['Canale 5', 'Italy'], 0xfa06 => ['Italia 1', 'Italy'], 0x39e7 => ['Music Box', 'Italy'], 0x39d9 => ['Televisiva SUPER3', 'Italy'], 0x39e9 => ['TN7 Telenorba', 'Italy'], 0x391a => ['TN8 Telenorba', 'Italy'], 0x393a => ['TP9 Telepuglia', 'Italy'], 0x4000 => ['RTL Télé Lëtzebuerg', 'Luxembourg'], 0x3101 => ['Nederland 1', 'Netherlands', 0x4801, 0x3801], 0x3102 => ['Nederland 2', 'Netherlands', 0x4802, 0x3802], 0x3103 => ['Nederland 3', 'Netherlands', 0x4803, 0x3803], 0x3104 => ['RTL 4', 'Netherlands', 0x4804, 0x3804], 0x3105 => ['RTL 5', 'Netherlands', 0x4805, 0x3805], 0x3147 => ['RTL7', 'Netherlands', 0x4847, 0x3847], 0x3110 => ['NOS future use', 'Netherlands'], 0x3111 => ['NOS future use', 'Netherlands'], 0x3112 => ['NOS future use', 'Netherlands'], 0x3113 => ['NOS future use', 'Netherlands'], 0x3114 => ['NOS future use', 'Netherlands'], 0x3115 => ['NOS future use', 'Netherlands'], 0x3116 => ['NOS future use', 'Netherlands'], 0x3117 => ['NOS future use', 'Netherlands'], 0x3118 => ['NOS future use', 'Netherlands'], 0x3119 => ['NOS future use', 'Netherlands'], 0x311a => ['NOS future use', 'Netherlands'], 0x311b => ['NOS future use', 'Netherlands'], 0x311c => ['NOS future use', 'Netherlands'], 0x311d => ['NOS future use', 'Netherlands'], 0x311e => ['NOS future use', 'Netherlands'], 0x311f => ['NOS future use', 'Netherlands'], 0x3107 => ['NOS future use', 'Netherlands', 0x4807, 0x3807], 0x3108 => ['NOS future use', 'Netherlands', 0x4808, 0x3808], 0x3109 => ['NOS future use', 'Netherlands', 0x4809, 0x3809], 0x310a => ['NOS future use', 'Netherlands', 0x480a, 0x380a], 0x310b => ['NOS future use', 'Netherlands', 0x480b, 0x380b], 0x310c => ['NOS future use', 'Netherlands', 0x480c, 0x380c], 0x310d => ['NOS future use', 'Netherlands', 0x480d, 0x380d], 0x310e => ['NOS future use', 'Netherlands', 0x480e, 0x380e], 0x310f => ['NOS future use', 'Netherlands', 0x480f, 0x380f], 0x3120 => ['The BOX', 'Netherlands', 0x4820, 0x3820], 0x3121 => ['Discovery Netherlands', 'Netherlands'], 0x3122 => ['Nickelodeon', 'Netherlands', 0x4822, 0x3822], 0x3123 => ['Animal Planet Benelux', 'Netherlands'], 0x3124 => ['TALPA TV', 'Netherlands'], 0x3125 => ['NET5', 'Netherlands'], 0x3126 => ['SBS6', 'Netherlands'], 0x3127 => ['SBS future use', 'Netherlands'], 0x3128 => ['V8', 'Netherlands'], 0x3129 => ['SBS future use', 'Netherlands'], 0x312a => ['SBS future use', 'Netherlands'], 0x312b => ['SBS future use', 'Netherlands'], 0x312c => ['SBS future use', 'Netherlands'], 0x312d => ['SBS future use', 'Netherlands'], 0x312e => ['SBS future use', 'Netherlands'], 0x312f => ['SBS future use', 'Netherlands'], 0x3130 => ['TMF (Netherlands service)', 'Netherlands'], 0x3131 => ['TMF (Belgian Flanders service)', 'Netherlands'], 0x3132 => ['MTV NL', 'Netherlands'], 0x3137 => ['RNN7', 'Netherlands'], 0x4701 => ['NRK1', 'Norway'], 0x4703 => ['NRK2', 'Norway'], 0x4702 => ['TV 2', 'Norway'], 0x4704 => ['TV Norge', 'Norway'], 0x4720 => ['Discovery Nordic', 'Norway'], 0x4831 => ['Animal Planet', 'Poland'], 0x4830 => ['Discovery Poland', 'Poland'], 0x4810 => ['TV Polonia', 'Poland'], 0x4801 => ['TVP1', 'Poland'], 0x4802 => ['TVP2', 'Poland'], 0x4880 => ['TVP Warszawa', 'Poland'], 0x4881 => ['TVP Bialystok', 'Poland'], 0x4882 => ['TVP Bydgoszcz', 'Poland'], 0x4883 => ['TVP Gdansk', 'Poland'], 0x4884 => ['TVP Katowice', 'Poland'], 0x4886 => ['TVP Krakow', 'Poland'], 0x4887 => ['TVP Lublin', 'Poland'], 0x4888 => ['TVP Lodz', 'Poland'], 0x4890 => ['TVP Rzeszow', 'Poland'], 0x4891 => ['TVP Poznan', 'Poland'], 0x4892 => ['TVP Szczecin', 'Poland'], 0x4893 => ['TVP Wroclaw', 'Poland'], 0x4820 => ['TVN', 'Poland'], 0x4821 => ['TVN Siedem', 'Poland'], 0x4822 => ['TVN24', 'Poland'], 0x3516 => ['Future use', 'Portugal'], 0x3517 => ['Future use', 'Portugal'], 0x3518 => ['Future use', 'Portugal'], 0x3519 => ['Future use', 'Portugal'], 0x3510 => ['RTP1', 'Portugal'], 0x3511 => ['RTP2', 'Portugal'], 0x3512 => ['RTPAF', 'Portugal'], 0x3514 => ['RTPAZ', 'Portugal'], 0x3513 => ['RTPI', 'Portugal'], 0x3515 => ['RTPM', 'Portugal'], 0x3781 => ['Marino RTV', 'San'], 0x42a7 => ['future use', 'Slovakia', 0x35a7, 0x3527], 0x42a8 => ['future use', 'Slovakia', 0x35a8, 0x3528], 0x42a9 => ['future use', 'Slovakia', 0x35a9, 0x3529], 0x42aa => ['future use', 'Slovakia', 0x35aa, 0x352a], 0x42ab => ['future use', 'Slovakia', 0x35ab, 0x352b], 0x42ac => ['future use', 'Slovakia', 0x35ac, 0x352c], 0x42ad => ['future use', 'Slovakia', 0x35ad, 0x352d], 0x42ae => ['future use', 'Slovakia', 0x35ae, 0x352e], 0x42af => ['future use', 'Slovakia', 0x35af, 0x352f], 0x42a1 => ['STV1', 'Slovakia', 0x35a1, 0x3521], 0x42a5 => ['STV1 Regional, B. Bystrica', 'Slovakia', 0x35a5, 0x3525], 0x42a3 => ['STV1 Regional, KoÅ¡ice', 'Slovakia', 0x35a3, 0x3523], 0x42a2 => ['STV2', 'Slovakia', 0x35a2, 0x3522], 0x42a6 => ['STV2 Regional, B. Bystrica', 'Slovakia', 0x35a6, 0x3526], 0x42a4 => ['STV2 Regional, KoÅ¡ice', 'Slovakia', 0x35a4, 0x3524], 0x42b1 => ['TV JOJ', 'Slovakia', 0x35b1, 0x3511], 0xaae5 => ['future use', 'Slovenia'], 0xaae6 => ['future use', 'Slovenia'], 0xaae7 => ['future use', 'Slovenia'], 0xaae8 => ['future use', 'Slovenia'], 0xaae9 => ['future use', 'Slovenia'], 0xaaea => ['future use', 'Slovenia'], 0xaaeb => ['future use', 'Slovenia'], 0xaaec => ['future use', 'Slovenia'], 0xaaed => ['future use', 'Slovenia'], 0xaaee => ['future use', 'Slovenia'], 0xaaef => ['future use', 'Slovenia'], 0xaaf2 => ['future use', 'Slovenia'], 0xaaf3 => ['future use', 'Slovenia'], 0xaaf4 => ['future use', 'Slovenia'], 0xaaf5 => ['future use', 'Slovenia'], 0xaaf6 => ['future use', 'Slovenia'], 0xaaf7 => ['future use', 'Slovenia'], 0xaaf8 => ['future use', 'Slovenia'], 0xaaf9 => ['future use', 'Slovenia'], 0xaae3 => ['KC', 'Slovenia'], 0xaae1 => ['SLO1', 'Slovenia'], 0xaae2 => ['SLO2', 'Slovenia'], 0xaaf1 => ['SLO3', 'Slovenia'], 0xaae4 => ['TLM', 'Slovenia'], 0x340a => ['Arte', 'Spain'], 0xca33 => ['C33', 'Spain'], 0xba01 => ['ETB 1', 'Spain'], 0x3402 => ['ETB 2', 'Spain'], 0xca03 => ['TV3', 'Spain'], 0x3e00 => ['TVE1', 'Spain'], 0xe100 => ['TVE2', 'Spain'], 0xe200 => ['TVE Internacional Europa', 'Spain'], 0x3403 => ['CANAL 9', 'Spain'], 0x3404 => ['PUNT 2', 'Spain'], 0x3405 => ['CCV', 'Spain'], 0x3406 => ['CANAL 9 NEWS 24H Future use', 'Spain'], 0x3407 => ['CANAL 9 Future Use', 'Spain'], 0x3408 => ['CANAL 9 DVB Future Use', 'Spain'], 0x3409 => ['CANAL 9 DVB Future Use', 'Spain'], 0x340b => ['CANAL 9 DVB Future Use', 'Spain'], 0x340c => ['CANAL 9 DVB Future Use', 'Spain'], 0x340d => ['CANAL 9 DVB Future Use', 'Spain'], 0x340e => ['CANAL 9 DVB Future Use', 'Spain'], 0x340f => ['CANAL 9 DVB Future Use', 'Spain'], 0x3410 => ['CANAL 9 DVB Future Use', 'Spain'], 0x3411 => ['CANAL 9 DVB Future Use', 'Spain'], 0x3412 => ['CANAL 9 DVB Future Use', 'Spain'], 0x3413 => ['CANAL 9 DVB Future Use', 'Spain'], 0x3414 => ['CANAL 9 DVB Future Use', 'Spain'], 0xe500 => ['Tele5', 'Spain', 0x1fe5], 0x4601 => ['SVT 1', 'Sweden', 0x4e01, 0x3e01], 0x4602 => ['SVT 2', 'Sweden', 0x4e02, 0x3e02], 0x4603 => ['SVT future use', 'Sweden', 0x4e03, 0x3e03], 0x4604 => ['SVT future use', 'Sweden', 0x4e04, 0x3e04], 0x4605 => ['SVT future use', 'Sweden', 0x4e05, 0x3e05], 0x4606 => ['SVT future use', 'Sweden', 0x4e06, 0x3e06], 0x4607 => ['SVT future use', 'Sweden', 0x4e07, 0x3e07], 0x4608 => ['SVT future use', 'Sweden', 0x4e08, 0x3e08], 0x4609 => ['SVT future use', 'Sweden', 0x4e09, 0x3e09], 0x460a => ['SVT future use', 'Sweden', 0x4e0a, 0x3e0a], 0x460b => ['SVT future use', 'Sweden', 0x4e0b, 0x3e0b], 0x460c => ['SVT future use', 'Sweden', 0x4e0c, 0x3e0c], 0x460d => ['SVT future use', 'Sweden', 0x4e0d, 0x3e0d], 0x460e => ['SVT future use', 'Sweden', 0x4e0e, 0x3e0e], 0x460f => ['SVT future use', 'Sweden', 0x4e0f, 0x3e0f], 0x4600 => ['SVT Test Txmns', 'Sweden', 0x4e00, 0x3e00], 0x4640 => ['TV 4', 'Sweden', 0x4e40, 0x3e40], 0x4641 => ['TV 4 future use', 'Sweden', 0x4e41, 0x3e41], 0x4642 => ['TV 4 future use', 'Sweden', 0x4e42, 0x3e42], 0x4643 => ['TV 4 future use', 'Sweden', 0x4e43, 0x3e43], 0x4644 => ['TV 4 future use', 'Sweden', 0x4e44, 0x3e44], 0x4645 => ['TV 4 future use', 'Sweden', 0x4e45, 0x3e45], 0x4646 => ['TV 4 future use', 'Sweden', 0x4e46, 0x3e46], 0x4647 => ['TV 4 future use', 'Sweden', 0x4e47, 0x3e47], 0x4648 => ['TV 4 future use', 'Sweden', 0x4e48, 0x3e48], 0x4649 => ['TV 4 future use', 'Sweden', 0x4e49, 0x3e49], 0x464a => ['TV 4 future use', 'Sweden', 0x4e4a, 0x3e4a], 0x464b => ['TV 4 future use', 'Sweden', 0x4e4b, 0x3e4b], 0x464c => ['TV 4 future use', 'Sweden', 0x4e4c, 0x3e4c], 0x464d => ['TV 4 future use', 'Sweden', 0x4e4d, 0x3e4d], 0x464e => ['TV 4 future use', 'Sweden', 0x4e4e, 0x3e4e], 0x464f => ['TV 4 future use', 'Sweden', 0x4e4f, 0x3e4f], 0x410a => ['SAT ACCESS', 'Switzerland', 0x24ca, 0x344a], 0x4101 => ['SF 1', 'Switzerland', 0x24c1, 0x3441], 0x4107 => ['SF 2', 'Switzerland', 0x24c7, 0x3447], 0x4103 => ['TSI 1', 'Switzerland', 0x24c3, 0x3443], 0x4109 => ['TSI 2', 'Switzerland', 0x24c9, 0x3449], 0x4102 => ['TSR 1', 'Switzerland', 0x24c2, 0x3442], 0x4108 => ['TSR 2', 'Switzerland', 0x24c8, 0x3448], 0x4121 => ['U1', 'Switzerland', 0x2421], 0x4122 => ['TeleZüri', 'Switzerland', 0x2422], 0x900a => ['ATV', 'Turkey'], 0x9006 => ['AVRASYA', 'Turkey', 0x4306, 0x3306], 0x900e => ['BRAVO TV', 'Turkey'], 0x9008 => ['Cine 5', 'Turkey'], 0x900d => ['EKO TV', 'Turkey'], 0x900c => ['EURO D', 'Turkey'], 0x9010 => ['FUN TV', 'Turkey'], 0x900f => ['GALAKSI TV', 'Turkey'], 0x900b => ['KANAL D', 'Turkey'], 0x9012 => ['KANAL D future use', 'Turkey'], 0x9013 => ['KANAL D future use', 'Turkey'], 0x9007 => ['Show TV', 'Turkey'], 0x9015 => ['Show TV future use', 'Turkey'], 0x9016 => ['Show TV future use', 'Turkey'], 0x9017 => ['Show Euro', 'Turkey'], 0x9020 => ['STAR TV', 'Turkey'], 0x9021 => ['STARMAX', 'Turkey'], 0x9022 => ['KANAL 6', 'Turkey'], 0x9023 => ['STAR 4', 'Turkey'], 0x9024 => ['STAR 5', 'Turkey'], 0x9025 => ['STAR 6', 'Turkey'], 0x9026 => ['STAR 7', 'Turkey'], 0x9027 => ['STAR 8', 'Turkey'], 0x9028 => ['STAR TV future use', 'Turkey'], 0x9029 => ['STAR TV future use', 'Turkey'], 0x9030 => ['STAR TV future use', 'Turkey'], 0x9031 => ['STAR TV future use', 'Turkey'], 0x9032 => ['STAR TV future use', 'Turkey'], 0x9033 => ['STAR TV future use', 'Turkey'], 0x9034 => ['STAR TV future use', 'Turkey'], 0x9035 => ['STAR TV future use', 'Turkey'], 0x9036 => ['STAR TV future use', 'Turkey'], 0x9037 => ['STAR TV future use', 'Turkey'], 0x9038 => ['STAR TV future use', 'Turkey'], 0x9039 => ['STAR TV future use', 'Turkey'], 0x9009 => ['Super Sport', 'Turkey'], 0x9011 => ['TEMPO TV', 'Turkey'], 0x9014 => ['TGRT', 'Turkey'], 0x9001 => ['TRT-1', 'Turkey', 0x4301, 0x3301], 0x9002 => ['TRT-2', 'Turkey', 0x4302, 0x3302], 0x9003 => ['TRT-3', 'Turkey', 0x4303, 0x3303], 0x9004 => ['TRT-4', 'Turkey', 0x4304, 0x3304], 0x9005 => ['TRT-INT', 'Turkey', 0x4305, 0x3305], 0xfb9c => ['ANGLIA TV', 'UK', 0x2c1c, 0x3c1c], 0xfb9f => ['ANGLIA TV future use', 'UK', 0x2c1f, 0x3c1f], 0xfb9d => ['ANGLIA TV future use', 'UK', 0x5bcd, 0x3b4d], 0xfb9e => ['ANGLIA TV future use', 'UK', 0x5bce, 0x3b4e], 0x4469 => ['BBC News 24', 'UK', 0x2c69, 0x3c69], 0x4468 => ['BBC Prime', 'UK', 0x2c68, 0x3c68], 0x4457 => ['BBC World', 'UK', 0x2c57, 0x3c57], 0x4458 => ['BBC Worldwide future 01', 'UK', 0x2c58, 0x3c58], 0x4459 => ['BBC Worldwide future 02', 'UK', 0x2c59, 0x3c59], 0x445a => ['BBC Worldwide future 03', 'UK', 0x2c5a, 0x3c5a], 0x445b => ['BBC Worldwide future 04', 'UK', 0x2c5b, 0x3c5b], 0x445c => ['BBC Worldwide future 05', 'UK', 0x2c5c, 0x3c5c], 0x445d => ['BBC Worldwide future 06', 'UK', 0x2c5d, 0x3c5d], 0x445e => ['BBC Worldwide future 07', 'UK', 0x2c5e, 0x3c5e], 0x445f => ['BBC Worldwide future 08', 'UK', 0x2c5f, 0x3c5f], 0x4460 => ['BBC Worldwide future 09', 'UK', 0x2c60, 0x3c60], 0x4461 => ['BBC Worldwide future 10', 'UK', 0x2c61, 0x3c61], 0x4462 => ['BBC Worldwide future 11', 'UK', 0x2c62, 0x3c62], 0x4463 => ['BBC Worldwide future 12', 'UK', 0x2c63, 0x3c63], 0x4464 => ['BBC Worldwide future 13', 'UK', 0x2c64, 0x3c64], 0x4465 => ['BBC Worldwide future 14', 'UK', 0x2c65, 0x3c65], 0x4466 => ['BBC Worldwide future 15', 'UK', 0x2c66, 0x3c66], 0x4467 => ['BBC Worldwide future 16', 'UK', 0x2c67, 0x3c67], 0x447f => ['BBC1', 'UK', 0x2c7f, 0x3c7f], 0x4443 => ['BBC1 future 01', 'UK', 0x2c43, 0x3c43], 0x4445 => ['BBC1 future 02', 'UK', 0x2c45, 0x3c45], 0x4479 => ['BBC1 future 03', 'UK', 0x2c79, 0x3c79], 0x4447 => ['BBC1 future 04', 'UK', 0x2c47, 0x3c47], 0x4477 => ['BBC1 future 05', 'UK', 0x2c77, 0x3c77], 0x4449 => ['BBC1 future 06', 'UK', 0x2c49, 0x3c49], 0x4475 => ['BBC1 future 07', 'UK', 0x2c75, 0x3c75], 0x444b => ['BBC1 future 08', 'UK', 0x2c4b, 0x3c4b], 0x4473 => ['BBC1 future 09', 'UK', 0x2c73, 0x3c73], 0x444d => ['BBC1 future 10', 'UK', 0x2c4d, 0x3c4d], 0x4471 => ['BBC1 future 11', 'UK', 0x2c71, 0x3c71], 0x444f => ['BBC1 future 12', 'UK', 0x2c4f, 0x3c4f], 0x446f => ['BBC1 future 13', 'UK', 0x2c6f, 0x3c6f], 0x4451 => ['BBC1 future 14', 'UK', 0x2c51, 0x3c51], 0x446d => ['BBC1 future 15', 'UK', 0x2c6d, 0x3c6d], 0x4453 => ['BBC1 future 16', 'UK', 0x2c53, 0x3c53], 0x446b => ['BBC1 future 17', 'UK', 0x2c6b, 0x3c6b], 0x4455 => ['BBC1 future 18', 'UK', 0x2c55, 0x3c55], 0x4441 => ['BBC1 NI', 'UK', 0x2c41, 0x3c41], 0x447b => ['BBC1 Scotland', 'UK', 0x2c7b, 0x3c7b], 0x447d => ['BBC1 Wales', 'UK', 0x2c7d, 0x3c7d], 0x4440 => ['BBC2', 'UK', 0x2c40, 0x3c40], 0x447c => ['BBC2 future 01', 'UK', 0x2c7c, 0x3c7c], 0x447a => ['BBC2 future 02', 'UK', 0x2c7a, 0x3c7a], 0x4446 => ['BBC2 future 03', 'UK', 0x2c46, 0x3c46], 0x4478 => ['BBC2 future 04', 'UK', 0x2c78, 0x3c78], 0x4448 => ['BBC2 future 05', 'UK', 0x2c48, 0x3c48], 0x4476 => ['BBC2 future 06', 'UK', 0x2c76, 0x3c76], 0x444a => ['BBC2 future 07', 'UK', 0x2c4a, 0x3c4a], 0x4474 => ['BBC2 future 08', 'UK', 0x2c74, 0x3c74], 0x444c => ['BBC2 future 09', 'UK', 0x2c4c, 0x3c4c], 0x4472 => ['BBC2 future 10', 'UK', 0x2c72, 0x3c72], 0x444e => ['BBC2 future 11', 'UK', 0x2c4e, 0x3c4e], 0x4470 => ['BBC2 future 12', 'UK', 0x2c70, 0x3c70], 0x4450 => ['BBC2 future 13', 'UK', 0x2c50, 0x3c50], 0x446e => ['BBC2 future 14', 'UK', 0x2c6e, 0x3c6e], 0x4452 => ['BBC2 future 15', 'UK', 0x2c52, 0x3c52], 0x446c => ['BBC2 future 16', 'UK', 0x2c6c, 0x3c6c], 0x4454 => ['BBC2 future 17', 'UK', 0x2c54, 0x3c54], 0x446a => ['BBC2 future 18', 'UK', 0x2c6a, 0x3c6a], 0x4456 => ['BBC2 future 19', 'UK', 0x2c56, 0x3c56], 0x447e => ['BBC2 NI', 'UK', 0x2c7e, 0x3c7e], 0x4444 => ['BBC2 Scotland', 'UK', 0x2c44, 0x3c44], 0x4442 => ['BBC2 Wales', 'UK', 0x2c42, 0x3c42], 0xb7f7 => ['BORDER TV', 'UK', 0x2c27, 0x3c27], 0x4405 => ['BRAVO', 'UK', 0x5bef, 0x3b6f], 0x82e2 => ['CARLTON SEL. future use', 'UK', 0x2c06, 0x3c06], 0x82e1 => ['CARLTON SELECT', 'UK', 0x2c05, 0x3c05], 0x82dd => ['CARLTON TV', 'UK', 0x2c1d, 0x3c1d], 0x82de => ['CARLTON TV future use', 'UK', 0x5bcf, 0x3b4f], 0x82df => ['CARLTON TV future use', 'UK', 0x5bd0, 0x3b50], 0x82e0 => ['CARLTON TV future use', 'UK', 0x5bd1, 0x3b51], 0x2f27 => ['CENTRAL TV', 'UK', 0x2c37, 0x3c37], 0x5699 => ['CENTRAL TV future use', 'UK', 0x2c16, 0x3c16], 0xfcd1 => ['CHANNEL 4', 'UK', 0x2c11, 0x3c11], 0x9602 => ['CHANNEL 5 (1)', 'UK', 0x2c02, 0x3c02], 0x1609 => ['CHANNEL 5 (2)', 'UK', 0x2c09, 0x3c09], 0x28eb => ['CHANNEL 5 (3)', 'UK', 0x2c2b, 0x3c2b], 0xc47b => ['CHANNEL 5 (4)', 'UK', 0x2c3b, 0x3c3b], 0xfce4 => ['CHANNEL TV', 'UK', 0x2c24, 0x3c24], 0x4404 => ['CHILDREN\'S CHANNEL', 'UK', 0x5bf0, 0x3b70], 0x01f2 => ['CNNI', 'UK', 0x5bf1, 0x3b71], 0x4407 => ['DISCOVERY', 'UK', 0x5bf2, 0x3b72], 0x4420 => ['Discovery Home & Leisure', 'UK'], 0x4421 => ['Animal Planet', 'UK'], 0x44d1 => ['DISNEY CHANNEL UK', 'UK', 0x5bcc, 0x3b4c], 0x4408 => ['FAMILY CHANNEL', 'UK', 0x5bf3, 0x3b73], 0xc4f4 => ['FilmFour', 'UK', 0x42f4, 0x3274], 0xaddc => ['GMTV', 'UK', 0x5bd2, 0x3b52], 0xaddd => ['GMTV future use', 'UK', 0x5bd3, 0x3b53], 0xadde => ['GMTV future use', 'UK', 0x5bd4, 0x3b54], 0xaddf => ['GMTV future use', 'UK', 0x5bd5, 0x3b55], 0xade0 => ['GMTV future use', 'UK', 0x5bd6, 0x3b56], 0xade1 => ['GMTV future use', 'UK', 0x5bd7, 0x3b57], 0xf33a => ['GRAMPIAN TV', 'UK', 0x2c3a, 0x3c3a], 0x4d5a => ['GRANADA PLUS', 'UK', 0x5bf4, 0x3b74], 0x4d5b => ['GRANADA Timeshare', 'UK', 0x5bf5, 0x3b75], 0xadd8 => ['GRANADA TV', 'UK', 0x2c18, 0x3c18], 0xadd9 => ['GRANADA TV future use', 'UK', 0x5bd8, 0x3b58], 0xfcf4 => ['HISTORY Ch.', 'UK', 0x5bf6, 0x3b76], 0x5aaf => ['HTV', 'UK', 0x2c3f, 0x3c3f], 0xf258 => ['HTV future use', 'UK', 0x2c38, 0x3c38], 0xc8de => ['ITV NETWORK', 'UK', 0x2c1e, 0x3c1e], 0x4406 => ['LEARNING CHANNEL', 'UK', 0x5bf7, 0x3b77], 0x4409 => ['Live TV', 'UK', 0x5bf8, 0x3b78], 0x884b => ['LWT', 'UK', 0x2c0b, 0x3c0b], 0x884c => ['LWT future use', 'UK', 0x5bd9, 0x3b59], 0x884d => ['LWT future use', 'UK', 0x5bda, 0x3b5a], 0x884f => ['LWT future use', 'UK', 0x5bdb, 0x3b5b], 0x8850 => ['LWT future use', 'UK', 0x5bdc, 0x3b5c], 0x8851 => ['LWT future use', 'UK', 0x5bdd, 0x3b5d], 0x8852 => ['LWT future use', 'UK', 0x5bde, 0x3b5e], 0x8853 => ['LWT future use', 'UK', 0x5bdf, 0x3b5f], 0x8854 => ['LWT future use', 'UK', 0x5be0, 0x3b60], 0x10e4 => ['MERIDIAN', 'UK', 0x2c34, 0x3c34], 0xdd50 => ['MERIDIAN future use', 'UK', 0x2c10, 0x3c10], 0xdd51 => ['MERIDIAN future use', 'UK', 0x5be1, 0x3b61], 0xdd52 => ['MERIDIAN future use', 'UK', 0x5be2, 0x3b62], 0xdd53 => ['MERIDIAN future use', 'UK', 0x5be3, 0x3b63], 0xdd54 => ['MERIDIAN future use', 'UK', 0x5be4, 0x3b64], 0xdd55 => ['MERIDIAN future use', 'UK', 0x5be5, 0x3b65], 0xfcfb => ['MOVIE CHANNEL', 'UK', 0x2c1b, 0x3c1b], 0x4d54 => ['MTV', 'UK', 0x2c14, 0x3c14], 0x4d55 => ['MTV future use', 'UK', 0x2c33, 0x3c33], 0x4d56 => ['MTV future use', 'UK', 0x2c36, 0x3c36], 0x320b => ['National Geographic Channel', 'UK'], 0x8e71 => ['NBC Europe', 'UK', 0x2c31, 0x3c31], 0x5343 => ['NBC Europe future use', 'UK', 0x2c03, 0x3c03], 0x8e79 => ['NBC Europe future use', 'UK', 0x2c23, 0x3c23], 0x8e78 => ['NBC Europe future use', 'UK', 0x2c26, 0x3c26], 0x8e77 => ['NBC Europe future use', 'UK', 0x2c28, 0x3c28], 0x8e76 => ['NBC Europe future use', 'UK', 0x2c29, 0x3c29], 0x8e75 => ['NBC Europe future use', 'UK', 0x2c2a, 0x3c2a], 0x8e74 => ['NBC Europe future use', 'UK', 0x2c2e, 0x3c2e], 0x8e73 => ['NBC Europe future use', 'UK', 0x2c32, 0x3c32], 0x8e72 => ['CNBC Europe', 'UK', 0x2c35, 0x3c35], 0xa460 => ['Nickelodeon UK', 'UK'], 0xa465 => ['Paramount Comedy Channel UK', 'UK'], 0x5c33 => ['QVC future use', 'UK'], 0x5c34 => ['QVC future use', 'UK'], 0x5c39 => ['QVC future use', 'UK'], 0x5c44 => ['QVC UK', 'UK'], 0xfcf3 => ['RACING Ch.', 'UK', 0x2c13, 0x3c13], 0xb4c7 => ['S4C', 'UK', 0x2c07, 0x3c07], 0xfcf5 => ['SCI FI CHANNEL', 'UK', 0x2c15, 0x3c15], 0xf9d2 => ['SCOTTISH TV', 'UK', 0x2c12, 0x3c12], 0xfcf9 => ['SKY GOLD', 'UK', 0x2c19, 0x3c19], 0xfcfc => ['SKY MOVIES PLUS', 'UK', 0x2c0c, 0x3c0c], 0xfcfd => ['SKY NEWS', 'UK', 0x2c0d, 0x3c0d], 0xfcfe => ['SKY ONE', 'UK', 0x2c0e, 0x3c0e], 0xfcf7 => ['SKY SOAPS', 'UK', 0x2c17, 0x3c17], 0xfcfa => ['SKY SPORTS', 'UK', 0x2c1a, 0x3c1a], 0xfcf8 => ['SKY SPORTS 2', 'UK', 0x2c08, 0x3c08], 0xfcf6 => ['SKY TRAVEL', 'UK', 0x5bf9, 0x3b79], 0xfcff => ['SKY TWO', 'UK', 0x2c0f, 0x3c0f], 0x37e5 => ['SSVC', 'UK', 0x2c25, 0x3c25], 0x44c1 => ['TNT / Cartoon Network', 'UK'], 0xa82c => ['TYNE TEES TV', 'UK', 0x2c2c, 0x3c2c], 0xa82d => ['TYNE TEES TV future use', 'UK', 0x5be6, 0x3b66], 0xa82e => ['TYNE TEES TV future use', 'UK', 0x5be7, 0x3b67], 0x4401 => ['UK GOLD', 'UK', 0x5bfa, 0x3b7a], 0x4411 => ['UK GOLD future use', 'UK', 0x5bfb, 0x3b7b], 0x4412 => ['UK GOLD future use', 'UK', 0x5bfc, 0x3b7c], 0x4413 => ['UK GOLD future use', 'UK', 0x5bfd, 0x3b7d], 0x4414 => ['UK GOLD future use', 'UK', 0x5bfe, 0x3b7e], 0x4415 => ['UK GOLD future use', 'UK', 0x5bff, 0x3b7f], 0x4402 => ['UK LIVING', 'UK', 0x2c01, 0x3c01], 0x833b => ['ULSTER TV', 'UK', 0x2c3d, 0x3c3d], 0x4d58 => ['VH-1', 'UK', 0x2c20, 0x3c20], 0x4d59 => ['VH-1 (German language)', 'UK', 0x2c21, 0x3c21], 0x4d57 => ['VH-1 future use', 'UK', 0x2c22, 0x3c22], 0x25d1 => ['WESTCOUNTRY future use', 'UK', 0x5be8, 0x3b68], 0x25d2 => ['WESTCOUNTRY future use', 'UK', 0x5be9, 0x3b69], 0x25d0 => ['WESTCOUNTRY TV', 'UK', 0x2c30, 0x3c30], 0x4403 => ['WIRE TV', 'UK', 0x2c3c, 0x3c3c], 0xfa2c => ['YORKSHIRE TV', 'UK', 0x2c2d, 0x3c2d], 0xfa2d => ['YORKSHIRE TV future use', 'UK', 0x5bea, 0x3b6a], 0xfa2e => ['YORKSHIRE TV future use', 'UK', 0x5beb, 0x3b6b], 0xfa2f => ['YORKSHIRE TV future use', 'UK', 0x5bec, 0x3b6c], 0xfa30 => ['YORKSHIRE TV future use', 'UK', 0x5bed, 0x3b6d], 0xfa31 => ['YORKSHIRE TV future use', 'UK', 0x5bee, 0x3b6e], 0x7700 => ['1+1', 'Ukraine'], 0x7701 => ['1+1 future use', 'Ukraine'], 0x7702 => ['1+1 future use', 'Ukraine'], 0x7703 => ['1+1 future use', 'Ukraine'], 0x7705 => ['M1', 'Ukraine'], 0x7707 => ['ICTV', 'Ukraine'], 0x7708 => ['Novy Kanal', 'Ukraine']); # unofficial addition(s) $VPS_CNI{0xe86} ||= "Das Vierte"; } package Video::Capture::VBI::VT; use Video::Capture::VBI; sub new { my $class = shift; my $self = bless {}, $class; $self; } sub feed(@) { my $self = shift; my @r; for (@_) { if ($_->[0] == VBI_VT) { my $y = $_->[2]; if ($y == 0) { if (defined $self->{curpage}{page}) { if ($_->[5] & VTX_C11 || ($self->{curpage}->{page} ^ $_->[4]) & 0xf00) { $self->enter_page($self->{curpage}) unless ($self->{curpage}->{page} & 0xff) == 0xff; } } $self->{curpage} = { packet => [$_->[3]], page => $_->[4], ctrl => $_->[5], }; } elsif($y<=25) { $self->{curpage}{packet}[$y] = $_->[3]; } elsif($y<=32) { $self->enter_packet($_); } else { #print "P$y: @$_\n"; } } else { push @r, $_; } } @r; } sub enter_page {} sub enter_packet {} 1; Video-Capture-V4l-0.902/VBI/VBI.xs0000644000000000000000000011464010331711745014760 0ustar rootroot#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #include "../gppport.h" /* loosely based on the program vbidecode.cc by Ralph Metzler */ typedef unsigned int UI; typedef unsigned char u8; typedef U16 u16; /* calculates odd parity, medium-efficient */ static int parodd(U32 data) { u8 p4[16] = { 0,1,1,0, 1,0,0,1, 1,0,0,1, 0,1,1,0 }; int parity = 1; do { parity ^= p4[data & 15]; data >>= 4; } while (data); return parity; } static u8 invtab[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, }; static u8 unhamtab[256] = { 0x01, 0xff, 0x81, 0x01, 0xff, 0x00, 0x01, 0xff, 0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07, 0xff, 0x00, 0x01, 0xff, 0x00, 0x80, 0xff, 0x00, 0x06, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x03, 0xff, 0xff, 0x0c, 0x01, 0xff, 0x04, 0xff, 0xff, 0x07, 0x06, 0xff, 0xff, 0x07, 0xff, 0x07, 0x07, 0x87, 0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff, 0x86, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07, 0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09, 0x02, 0x82, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff, 0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff, 0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x83, 0x03, 0x04, 0xff, 0xff, 0x05, 0x84, 0x04, 0x04, 0xff, 0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07, 0xff, 0x05, 0x05, 0x85, 0x04, 0xff, 0xff, 0x05, 0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff, 0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09, 0x0a, 0xff, 0xff, 0x0b, 0x8a, 0x0a, 0x0a, 0xff, 0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff, 0xff, 0x0b, 0x0b, 0x8b, 0x0a, 0xff, 0xff, 0x0b, 0x0c, 0x8c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff, 0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07, 0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x8d, 0x0d, 0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff, 0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x89, 0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09, 0x88, 0x08, 0x08, 0xff, 0x08, 0xff, 0xff, 0x09, 0x08, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x03, 0xff, 0xff, 0x0c, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x09, 0x0f, 0xff, 0x8f, 0x0f, 0xff, 0x0e, 0x0f, 0xff, 0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff, 0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x8e, 0xff, 0x0e, }; #define VBI_BPL 2048 #define FREQ_PAL 35.468950 #define FREQ_NTSC 28.636363 #define FREQ FREQ_PAL #define FREQ_VT_PAL 6.9375 #define FREQ_VT_NTSC 5.72725 #define FREQ_VT FREQ_VT_PAL /* Replace by FREQ_VT_NTSC and pray that it works */ /*#define FREQ_VT 6.165*/ /* teletext-like signal on france, 0xe7 instead of 0x27 */ #define FREQ_CRYPT 4.5 /* found on premiere */ #define FREQ_VPS 2.5 /* probably only pal */ #define FREQ_VDAT 2.0 /* videodat */ #define FREQ_VC 0.77 /* videocrypt, just ignore */ #define VBI_VT 0x0001 #define VBI_VPS 0x0002 #define VBI_VDAT 0x0004 #define VBI_VC 0x0008 #define VBI_OTHER 0x0010 #define VBI_EMPTY 0x8000 typedef long FP; #define FP_BITS 16 #define FP_0_5 D2FP(0.5) #define D2FP(d) ((FP)((d) * (1<> FP_BITS) #define VT_COLS 40 #define VT_LINES 36 typedef struct { UI types; /* required types */ int offset; /* signal offset */ int did_agc : 1; /* did we already do agc this frame? */ int y; /* the line number */ u8 *line; /* the current line */ FP step; /* the bit step */ FP pos; /* position */ } decoder; static void decoder_init (decoder *dec, UI types) { dec->types = types; dec->did_agc = 0; } static void decoder_scan_start (decoder *dec, UI a, UI b) { u8 *p = dec->line + a; UI med = 128 - dec->offset; do { if (*p >= med) break; } while (++p < dec->line + b); /* find maximum */ while (p[1] > p[0]) p++; dec->pos = I2FP (p - dec->line); } static u8 get_byte (decoder *dec) { u8 byte; int bit = 8; /* if the next bit is a one bit, try to re-center the decoder on it */ if ((dec->offset + dec->line[FP2I(dec->pos)]) & 0x80) { /*if (dec->line[FP2I(dec->pos)] < dec->line[FP2I(dec->pos)+1]) dec->pos += I2FP(1);*/ /* why is this casuing checksum errors? */ /*if (dec->line[FP2I(dec->pos)] < dec->line[FP2I(dec->pos)-1]) dec->pos -= I2FP(1);*/ } byte=0; do { byte >>= 1; byte |= ((dec->offset + dec->line[FP2I(dec->pos)]) & 0x80); dec->pos += dec->step; } while (--bit); return byte; } /* get shift-encoded byte */ static u8 get_byte_SE (decoder *dec) { u8 byte; int bit = 8; do { byte >>= 1; byte |= (dec->line[FP2I(dec->pos)] > dec->line[FP2I(dec->pos + dec->step/2)]) << 7; dec->pos += dec->step; } while (--bit); /* if the next bit is a one bit, try to re-center the decoder on it */ if (dec->line[FP2I(dec->pos)] > 128-dec->offset) { if (dec->line[FP2I(dec->pos)] > dec->line[FP2I(dec->pos)+1]) dec->pos += I2FP(1); if (dec->line[FP2I(dec->pos)] < dec->line[FP2I(dec->pos)-1]) dec->pos -= I2FP(1); } return byte; } static u8 unham4(u8 a) { return unhamtab[a] & 15; } static u8 unham8(u8 a, u8 b) { u8 c1 = unhamtab[a]; u8 c2 = unhamtab[b]; if ( (c1|c2) & 0x40) /* 2 bit error */; return (c1 & 15) | (c2 << 4); } static u16 unham16(u8 a, u8 b, u8 c) { U32 d = (((c << 8) | b) << 8) | c; int A = parodd (d & 0x555555); int B = parodd (d & 0x666666); int C = parodd (d & 0x787878); int D = parodd (d & 0x007f80); int E = parodd (d & 0x7f8000); int F = parodd (d & 0xffffff); int bit; d = (((d >> 16) & 0x7f) << 11) | (((d >> 8) & 0x7f) << 4) | (((d >> 4) & 0x07) << 1) | (((d >> 2) & 0x01) ); if (A&B&C&D&E) return d; if (F) return -1; /* double bit error */ /* correct the single bit error */ return d ^ (1 << (31 - 16*E + 8*D + 4*C + 2*B + A)); } #define rev(byte) (invtab [(u8)(byte)]) static SV * decode_vps (u8 *data) { AV *av = newAV (); char name = rev (data[3]); av_push (av, newSViv (VBI_VPS)); av_push (av, newSVpvn (&name, 1)); av_push (av, newSViv (data[4] & 3)); /* "unknown", "stereo ", "mono ", "dual " */ /* ch, day, mon, hour, min */ av_push (av, newSViv (data[ 4] <<12 & 0xf000 | data[10] & 0x00c0 | data[12] <<10 & 0x0c00 | data[13] << 2 & 0x0300 | data[13] & 0x003f)); av_push (av, newSViv (rev (data[10]) >> 1 & 31)); av_push (av, newSViv (rev (data[10]) << 3 & 8 | rev (data[11]) >> 5)); av_push (av, newSViv (rev (data[11]) & 31)); av_push (av, newSViv (rev (data[12]) >> 2)); av_push (av, newSViv (rev (data[14]))); return newRV_noinc ((SV*)av); } static SV * decode_vt (u8 *data) { AV *av = newAV (); u8 mpag = unham8 (data[3], data[4]); u8 mag = mpag & 7; u8 pack = (mpag & 0xf8) >> 3; av_push (av, newSViv (VBI_VT)); av_push (av, newSViv (mag)); av_push (av, newSViv (pack)); switch (pack) { /* ets300-706 */ case 0: av_push (av, newSVpvn (data+5, 40)); av_push (av, newSViv (unham8 (data[5], data[6]) | (mag << 8))); av_push (av, newSViv (unham8 (data[7], data[8]) | (unham8 (data[9], data[10]) << 8) | (unham8 (data[11], data[12]) << 16))); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: av_push (av, newSVpvn (data+5, 40)); break; case 26: case 27: case 28: case 29: /* enhancement packets */ av_push (av, newSViv (unham4 (data[5]))); av_push (av, newSViv (unham16 (data[ 6], data[ 7], data[ 8]))); av_push (av, newSViv (unham16 (data[ 9], data[10], data[11]))); av_push (av, newSViv (unham16 (data[12], data[13], data[14]))); av_push (av, newSViv (unham16 (data[15], data[16], data[17]))); av_push (av, newSViv (unham16 (data[18], data[19], data[20]))); av_push (av, newSViv (unham16 (data[21], data[22], data[23]))); av_push (av, newSViv (unham16 (data[24], data[25], data[26]))); av_push (av, newSViv (unham16 (data[27], data[28], data[29]))); av_push (av, newSViv (unham16 (data[30], data[31], data[32]))); av_push (av, newSViv (unham16 (data[33], data[34], data[35]))); av_push (av, newSViv (unham16 (data[36], data[37], data[38]))); av_push (av, newSViv (unham16 (data[39], data[40], data[41]))); av_push (av, newSViv (unham16 (data[42], data[43], data[44]))); break; /* ets300-706 & ets300-231 */ case 30: { UI dc = unham4 (data[5]); av_push (av, newSViv (dc)); if ((dc >> 1) == 0) { av_push (av, newSViv (unham8 (data[6], data[7]) | (mag << 8))); av_push (av, newSViv (unham8 (data[8], data[9]) | unham8 (data[10], data[11]) << 8)); av_push (av, newSViv (rev (data[12]) << 8 | rev (data[13]))); } else if ((dc >> 1) == 8) { /* pdc */ } } break; case 31: { UI ft = unham4 (data[5]); UI al = unham4 (data[6]); UI i, addr = 0; /* ets300-708, IDL */ /* http://sunsite.cnlab-switch.ch/ftp/mirror/internet-drafts/draft-ietf-ipvbi-tv-signal-00.txt */ for(i=0; ipos; u8 data[6]; av_push (av, newSViv (VBI_OTHER)); dec->step = D2FP (FREQ / FREQ_CRYPT); /* found on premiere */ data [0] = get_byte (dec); data [1] = get_byte (dec); data [2] = get_byte (dec); if (data[0] == 0x55 && data[1] == 0xd0 && data[2] == 0x18) { /* premiere */ av_push (av, newSViv (1)); } else av_push (av, newSViv (0)); return newRV_noinc ((SV*)av); } static SV * decode_empty () { AV *av = newAV (); av_push (av, newSViv (VBI_EMPTY)); return newRV_noinc ((SV*)av); } static SV * decoder_decode (decoder *dec, UI y, u8 *line) { UI type; u8 data[45]; /* 45 bytes per line are max. */ UI i; int did_agc; type = VBI_VT | VBI_EMPTY | VBI_OTHER | VBI_VC; /* can be everywhere */ if (y == 16 - 7) type |= VBI_VPS; if (y > 17 - 7) type |= VBI_VDAT; type &= dec->types; /* don't do anything unless we need to */ if (type) { dec->line = line; dec->y = y; dec->pos = 0; did_agc = dec->did_agc; /* maybe do agc? */ if (!dec->did_agc || y == 20-7) { u8 *n = line + 120; u8 max = 0, min = 255; do { if (*n > max) max = *n; if (*n < min) min = *n; } while (++n < line + 300); if (max > min + 30) { dec->offset = 128 - (((int)max + (int)min) >> 1); dec->did_agc = 1; } } if (dec->did_agc) { if (type & VBI_VT) { dec->step = D2FP (FREQ / FREQ_VT); decoder_scan_start (dec, 50, 350); data[0] = get_byte (dec); if ((data[0] & 0xfe) == 0x54) { data[1] = get_byte (dec); switch (data[1]) { case 0x27: dec->pos -= dec->step * 2; case 0x4e: dec->pos -= dec->step * 2; case 0x9d: dec->pos -= dec->step * 2; case 0x75: dec->pos -= dec->step * 2; case 0xd5: dec->pos -= dec->step * 2; data[1] = 0x55; case 0x55: break; default: ; /* no teletext page */ } if (data[1] == 0x55) { data[2] = get_byte (dec); if (data[2] == 0x27 || data[2] == 0xe7) { for (i = 3; i < 45; i++) data[i] = get_byte (dec); return decode_vt (data); } } } } if (type & VBI_VPS) { decoder_scan_start (dec, 150, 260); dec->step = D2FP (FREQ / FREQ_VPS); /* shift encoding, two "pixels"/bit (skip the 2nd) */ data[0] = get_byte_SE (dec); if (data[0] == 0xff) { data[1] = get_byte_SE (dec); if (data[1] == 0x5d || data[1] == 0x5f) { for (i = 2; i < 16; i++) data[i] = get_byte_SE (dec); return decode_vps (data); } } } #if 0 if (type & VBI_VDAT) { dec->step = D2FP (FREQ / FREQ_VDAT); decoder_scan_start (dec, 150, 200); } if (type & VBI_VC) { dec->step = D2FP (FREQ / FREQ_VC); decoder_scan_start (dec, 150, 200); } #endif /* watch out for empty lines, test signals etc.. */ if (type & VBI_OTHER) { dec->did_agc = did_agc; /* other signals do not affect agc, yet */ dec->step = D2FP (FREQ); decoder_scan_start (dec, 100, 500); if (dec->pos < I2FP (450)) return decoder_decode_other (dec); } } dec->did_agc = did_agc; if (type & VBI_EMPTY) return decode_empty (); } return 0; } /* vtx decoding routines taken from videotext-0.6.971023, * Copyright (c) 1994-96 Martin Buck */ #define VTX_COLMASK 0x07 #define VTX_BGMASK (0x07 << 3) #define VTX_G1 (1 << 6) #define VTX_GRSEP (1 << 8) #define VTX_HIDDEN (1 << 9) #define VTX_BOX (1 << 10) #define VTX_FLASH (1 << 11) #define VTX_DOUBLE1 (1 << 12) #define VTX_DOUBLE2 (1 << 13) #define VTX_INVERT (1 << 14) #define VTX_DOUBLE (VTX_DOUBLE1 | VTX_DOUBLE2) static const u8 g0_to_iso_table[256] = " " " !\"#$%&'()*+,-./0123456789:;<=>?" "@ABCDEFGHIJKLMNOPQRSTUVWXYZAOU^#" "-abcdefghijklmnopqrstuvwxyzaous#" " " " " " " " "; /* one-to-one copy */ static int decode_vtpage (u8 *src, UI lines, u8 *chr, u16 *attr) { UI line, col, pos, graphics, grhold, doubleht, nextattr = 0; u16 *lastattr, default_attrib = 7, next_attrib; u8 c, *lastchr, default_chr = ' '; UI lang; lang = 4; pos = 0; doubleht = 0; for (line = 0; line < lines; line++) { lastchr = &default_chr; lastattr = &default_attrib; graphics = grhold = 0; if (doubleht && pos > 40) { for (col = 0; col <= 39; col++) { if (attr[pos - 40] & VTX_DOUBLE1) { chr[pos] = chr[pos - 40]; chr[pos - 40] = ' '; attr[pos] = (attr[pos - 40] & ~VTX_DOUBLE1) | VTX_DOUBLE2; } else { chr[pos] = ' '; attr[pos] = attr[pos - 40]; } pos++; } doubleht = 0; } else { for (col = 0; col <= 39; col++) { c = src[pos]; if (parodd(c)) { chr[pos] = 254; /* Parity error */ attr[pos] = 7; /* return 0 */ /*?*/ } else if ((c & 0x7f) >= 32) { /* Normal character */ c &= 0x7f; if (!graphics || (c >= 64 && c <= 95)) { chr[pos] = g0_to_iso_table [c]; attr[pos] = *lastattr; } else { chr[pos] = c + (c >= 96 ? 64 : 96); attr[pos] = *lastattr | VTX_G1; } } else { c &= 0x7f; chr[pos] = ((grhold && graphics ) ? *lastchr : ' '); if (c <= 7) { /* Set alphanumerics-color */ attr[pos] = *lastattr; next_attrib = (*lastattr & ~(VTX_COLMASK | VTX_HIDDEN)) + c; nextattr = 1; graphics = 0; } else if (c == 8 || c == 9) { /* Flash on/off */ attr[pos] = (*lastattr & ~VTX_FLASH) + VTX_FLASH * (c == 8); } else if (c == 10 || c == 11) { /* End/start box */ attr[pos] = (*lastattr & ~VTX_BOX) + VTX_BOX * (c == 11); } else if (c == 12 || c == 13) { /* Normal/double height */ attr[pos] = (*lastattr & ~VTX_DOUBLE1) + VTX_DOUBLE1 * (c == 13); if (c == 13) doubleht = 1; } else if (c == 14 || c == 15 || c == 27) { /* SO, SI, ESC (ignored) */ attr[pos] = *lastattr; } else if (c >= 16 && c <= 23) { /* Set graphics-color */ attr[pos] = *lastattr; next_attrib = (*lastattr & ~(VTX_COLMASK | VTX_HIDDEN)) + c - 16; nextattr = 1; graphics = 1; } else if (c == 24) { /* Conceal display */ attr[pos] = *lastattr | VTX_HIDDEN; } else if (c == 25 || c == 26) { /* Contiguous/separated graphics */ attr[pos] = (*lastattr & ~VTX_GRSEP) + VTX_GRSEP * (c == 26); } else if (c == 28) { /* Black background */ attr[pos] = *lastattr & ~VTX_BGMASK; } else if (c == 29) { /* Set background */ attr[pos] = (*lastattr & ~VTX_BGMASK) + ((*lastattr & VTX_COLMASK) << 3); } else if (c == 30 || c == 31) { /* Hold/release graphics */ attr[pos] = *lastattr; grhold = (c == 30); if (grhold && graphics) chr[pos] = *lastchr; } else { return 0; } } lastchr = chr + pos; if (nextattr) { lastattr = &next_attrib; nextattr = 0; } else { lastattr = attr + pos; } pos++; } } } return 1; } static SV * decode_ansi (u8 *chr, u16 *atr) { UI x; SV *sv = newSVpvn ("", 0); u16 o; for (x=0; x < VT_COLS; x++) { u16 a = *atr++; if (x == 0 || (a & 0x07) != (o & 0x07)) sv_catpvf (sv, "\x1b[3%dm", a & 7); if (x == 0 || (a & 0x38) != (o & 0x38)) sv_catpvf (sv, "\x1b[4%dm", (o & 0x38)>>3); if (x == 0 || (a & VTX_FLASH) != (o & VTX_FLASH)) sv_catpvf (sv, "\x1b[%sm", a & VTX_FLASH ? "7" : ""); sv_catpvf (sv, "%c", a & VTX_G1 ? 'x' : *chr); chr++; o = a; } sv_catpv (sv, "\x1b[37;40;0m"); return sv; } #define valid_packet(sv) (SvPOK(packet) && SvCUR(packet) == 40) #define consume_byte(store) \ if (bp >= 39) \ { \ SV **sv = av_fetch(stream, pi, 0); pi++; \ if (!sv) \ goto eostream; \ packet = *sv; \ if (!valid_packet (pascket)) \ goto skip; \ p = SvPV_nolen (packet); \ bp = 0; \ } \ (store) = p[++bp] static void decode_stream (AV *stream) { dSP; while (av_len (stream) >= 0) { UI pi = 1; SV *packet = *av_fetch(stream, 0, 1); if (valid_packet (packet)) { u8 *p = SvPV_nolen(packet); u8 bp = p[0] == 0xff ? p[1] : unham4 (p[0])*3+1; if (bp <= 12*3+1 && p[bp] == 0xa1) { u8 buf[4]; consume_byte (buf[0]); consume_byte (buf[1]); consume_byte (buf[2]); consume_byte (buf[3]); { u16 sh = unham8 (buf[0], buf[1]) | unham8 (buf[2], buf[3]) << 8; u8 bt = sh & 0x1f; u16 bl = sh >> 5; SV *block = sv_2mortal (newSVpvn (&bt, 1)); while (bl--) { consume_byte (buf[0]); sv_catpvn (block, buf, 1); } EXTEND (SP, 1); PUSHs (block); /* optimize, do only when still in first packet! */ do { if (bp >= 39) break; bp++; if (p[bp] == 0xa1) { p[0] = 0xff; p[1] = bp; pi--; break; } } while (p[bp] = 0x5e); } } } skip: while (pi--) SvREFCNT_dec(av_shift(stream)); } eostream: PUTBACK; } static u8 * unham_block (u8 *src, UI len, u8 *dst, UI dlen) { u16 sh = *src | (len-1)<<5; u8 sum = ( sh & 15) + ((sh >> 4) & 15) + ((sh >> 8) & 15) + ((sh >> 12) & 15); if (len < 5) return 0; sum += unham8 (src[1], src[2]); src += 3; len -= 3; dlen--; if (len < dlen) return 0; while (dlen) { *dst = unham8 (src[0], src[1]); sum += (*dst >> 4) + (*dst & 15); #if 0 printf ("%02x ", *dst); #endif dst++; src += 2; dlen--; } #if 0 printf ("\n"); printf ("sh = %04x, len = %02x, sum = %02x\n", sh, len, sum); #endif if (sum) return 0; return src; } /* must not be a macro, see nvec */ static U32 vec(u8 *d, UI bit, UI len) { U32 word = bit >> 3; /*printf ("vec(%d,%d) %d (%d)\n",bit,len,(bit & 7) + len,(bit & 7) + len < 32);*/ assert ((bit & 7) + len < 32); word = (d[word] ) | (d[word+1] << 8) | (d[word+2] << 16) | (d[word+3] << 24); return (word >> (bit & 7)) & (((U32)1 << len) - 1); } #define hv_store_sv(name,value) hv_store (hv, #name, strlen(#name), (SV*)(value), 0) #define hv_store_iv(name,value) hv_store_sv (name, newSViv (value)) #define nvec(bits) vec (c, (ofs += (bits)) - (bits), (bits)) #define decode_escape_sequences(av) \ { \ UI no_escapes = nvec (8); \ av = newAV (); \ while (no_escapes--) \ { \ AV *esc = newAV (); \ av_push (esc, newSViv (nvec (10))); \ av_push (esc, newSViv (nvec (6))); \ av_push (esc, newSViv (nvec (8))); \ av_push (av, newRV_noinc((SV*)esc)); \ } \ } #define decode_transparent_string(sv, len) \ { \ UI l = len; \ sv = newSVpvn (s, l); \ s += l; \ while (l--) \ SvPV_nolen (sv)[l] &= 0x7f; \ } #define decode_descriptor_loop(av, ll) \ av = newAV (); \ while (ll--) \ { \ AV *desc = newAV (); \ av_push (desc, newSViv (nvec (6))); \ av_push (desc, newSViv (nvec (6))); \ av_push (desc, newSViv (nvec (8))); \ av_push (av, newRV_noinc((SV*)desc)); \ } static void decode_epg (HV *hv, UI appid, u8 *c, u8 *s) { UI ofs = 16; UI len; AV *av; SV *sv; hv_store_iv (ca_mode, nvec(2)); hv_store_iv (_copyright, nvec(1)); ofs++; /* reserved */ switch (appid) { case 1: { hv_store_iv (epg_version, nvec( 6)); hv_store_iv (epg_version_swo, nvec( 6)); hv_store_iv (no_navigation, nvec(16)); hv_store_iv (no_osd, nvec(16)); hv_store_iv (no_message, nvec(16)); hv_store_iv (no_navigation_swo,nvec(16)); hv_store_iv (no_osd_swo, nvec(16)); hv_store_iv (no_message_swo, nvec(16)); len = nvec(8); hv_store_iv (this_network_op, nvec( 8)); decode_transparent_string (sv, nvec (5)); hv_store_sv (service_name, sv); hv_store_iv (no_updates, nvec( 1)); ofs += 2; av = newAV (); while (len--) { HV *hv = newHV (); int LTO; hv_store_iv (cni, nvec (16)); LTO = nvec (7) * 15; if (nvec(1)) LTO = -LTO; hv_store_iv (lto, LTO); hv_store_iv (no_days, nvec( 5)); decode_transparent_string (sv, nvec( 5)); hv_store_sv (netwop_name, sv); hv_store_iv (default_alphabet, nvec( 7)); hv_store_iv (prog_start_no, nvec(16)); hv_store_iv (prog_stop_no, nvec(16)); hv_store_iv (prog_stop_no_swo, nvec(16)); hv_store_iv (network_add_info, nvec(11)); av_push (av, newRV_noinc ((SV*)hv)); } hv_store_sv (networks, newRV_noinc ((SV*)av)); break; } case 2: { UI background_reuse; hv_store_iv (block_no, nvec(16)); hv_store_iv (audio_mode, vec(c, ofs, 12) & 3); hv_store_iv (feature_flags, nvec(12)); hv_store_iv (netwop_no, nvec( 8)); hv_store_iv (start_time, nvec(16)); hv_store_iv (start_date, nvec(16)); hv_store_iv (stop_time, nvec(16)); hv_store_iv (_pil, nvec(20)); hv_store_iv (parental_rating, nvec( 4)); hv_store_iv (editorial_rating,nvec( 3)); { UI no_themes = nvec( 3); UI no_sortcrit = nvec( 3); UI descriptor_looplength = nvec( 6); background_reuse = nvec( 1); av = newAV (); while (no_themes--) av_push (av, newSViv (nvec (8))); hv_store_sv (themes, newRV_noinc((SV*)av)); av = newAV (); while (no_sortcrit--) av_push (av, newSViv (nvec (8))); hv_store_sv (sortcrits, newRV_noinc((SV*)av)); decode_descriptor_loop (av, descriptor_looplength); hv_store_sv (descriptors, newRV_noinc((SV*)av)); ofs = (ofs+7) & ~7; decode_escape_sequences (av); hv_store_sv (title_escape_sequences, newRV_noinc((SV*)av)); decode_transparent_string (sv, nvec (8)); hv_store_sv (title, sv); } if (background_reuse) hv_store_iv (title_length, nvec (16)); else { decode_escape_sequences (av); hv_store_sv (shortinfo_escape_sequences, newRV_noinc((SV*)av)); decode_transparent_string (sv, nvec (8)); hv_store_sv (shortinfo, sv); len = nvec (3); ofs += 2; switch (len) { case 0: decode_escape_sequences (av); hv_store_sv (longinfo_escape_sequences, newRV_noinc((SV*)av)); decode_transparent_string (sv, nvec (8)); hv_store_sv (longinfo, sv); break; case 1: decode_escape_sequences (av); hv_store_sv (longinfo_escape_sequences, newRV_noinc((SV*)av)); decode_transparent_string (sv, nvec (10)); hv_store_sv (longinfo, sv); break; default: printf ("UNKNOWN LONGINFO TYPE %d\n", len); } } break; } case 3: { UI descriptor_ll; hv_store_iv (block_no, nvec(16)); hv_store_iv (header_size, nvec( 2)); len = nvec(4); hv_store_iv (message_size, nvec( 3)); ofs++; descriptor_ll = nvec(6); decode_descriptor_loop (av, descriptor_ll); hv_store_sv (descriptors, newRV_noinc((SV*)av)); ofs = (ofs+7) & ~7; decode_escape_sequences (av); hv_store_sv (header_escape_sequences, newRV_noinc((SV*)av)); decode_transparent_string (sv, nvec(8)); hv_store_sv (header, sv); hv_store_iv (message_attribute,nvec(8)); av = newAV (); while (len--) { AV *av2; UI len; HV *hv = newHV (); hv_store_iv (next_id, nvec(16)); hv_store_iv (next_type, nvec( 4)); len = nvec(4); av2 = newAV (); while (len--) { UI kind = nvec(8); av_push (av2, newSViv (kind)); switch (kind) { case 0x02: case 0x10: case 0x11: case 0x18: case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x40: case 0x41: av_push (av2, newSViv (nvec ( 8))); break; case 0x80: case 0x81: av_push (av2, newSViv (nvec (16))); break; case 0xc0: av_push (av2, newSViv (nvec (12))); av_push (av2, newSViv (nvec (12))); break; case 0xc8: case 0xc9: av_push (av2, newSViv (nvec (24))); break; default: abort (); } } hv_store_sv (attributes, newRV_noinc((SV*)av2)); decode_escape_sequences (av2); hv_store_sv (header_escape_sequences, newRV_noinc((SV*)av2)); decode_transparent_string (sv, nvec(8)); hv_store_sv (event, sv); av_push (av, newRV_noinc((SV*)hv)); } hv_store_sv (events, newRV_noinc((SV*)av)); break; } case 4: { UI block_no = nvec (16); UI descriptor_ll; UI msg_len; hv_store_iv (block_no, block_no); hv_store_iv (message_attribute,nvec(8)); hv_store_iv (header_size, nvec(3)); hv_store_iv (message_size, nvec(3)); descriptor_ll = nvec(6); if (!block_no) { decode_escape_sequences (av); hv_store_sv (message_escape_sequences, newRV_noinc((SV*)av)); msg_len = nvec(10); ofs += 6; } decode_escape_sequences (av); hv_store_sv (header_escape_sequences, newRV_noinc((SV*)av)); decode_transparent_string (sv, nvec(8)); hv_store_sv (header, sv); if (!block_no) { decode_transparent_string (sv, msg_len); hv_store_sv (message, sv); } decode_descriptor_loop (av, descriptor_ll); hv_store_sv (descriptors, newRV_noinc((SV*)av)); break; } case 5: { UI descriptor_ll; hv_store_iv (block_no, nvec(16)); descriptor_ll = nvec(6); decode_descriptor_loop (av, descriptor_ll); hv_store_sv (descriptors, newRV_noinc((SV*)av)); ofs = (ofs+7) & ~7; decode_escape_sequences (av); hv_store_sv (message_escape_sequences, newRV_noinc((SV*)av)); decode_transparent_string (sv, nvec(10)); hv_store_sv (message, sv); break; } default: printf ("UNKNOWN EPG DATATYPE ($%02x)\n", appid); } } static SV * decode_block(u8 *b, UI len, AV *bi) { dSP; u8 ctrl[1024]; u8 bt = *b; if (bt == 0) { if ((b = unham_block (b, len, ctrl, (len-1)>>1 ))) { UI app_no = ctrl[0]; UI app; av_clear (bi); for (app=1; app<=app_no; app++) av_store (bi, app, newSViv (vec (ctrl, app*16-8, 16))); } } else if (len >= 5) { if (bt <= av_len (bi) && SvOK(*av_fetch (bi, bt, 0))) { u16 appid = SvIV (*av_fetch (bi, bt, 0)); if (appid == 0) /* EPG */ { if ((b = unham_block (b, len, ctrl, unham8 (b[3], b[4]) | (unham4 (b[5]) << 8) & 1023))) { HV *hv = newHV (); /* _now_ we have an epg structure. decode it */ appid = vec(ctrl,10,6); EXTEND (SP, 2); PUSHs (sv_2mortal (newSViv (appid))); PUSHs (sv_2mortal (newRV_noinc ((SV*)hv))); decode_epg (hv, appid, ctrl, b); } else printf ("checksum error found block %d, len %d, appid = %d (clen 0)\n", bt, len, appid); } else /* other applications not defined (to my knowledge) */; } else /* no bundle info: can't parse yet */; } PUTBACK; } MODULE = Video::Capture::VBI PACKAGE = Video::Capture::VBI PROTOTYPES: ENABLE int unham4(data) SV * data CODE: STRLEN len; unsigned char *d = (unsigned char *)SvPV (data, len); if (len < 1) croak ("unham4: length must be at least 1"); RETVAL = unham4 (*d); OUTPUT: RETVAL int unham8(data) SV * data CODE: STRLEN len; unsigned char *d = (unsigned char *)SvPV (data, len); if (len < 2) croak ("unham8: length must be at least 2"); RETVAL = unham8 (d[0], d[1]); OUTPUT: RETVAL void decode_field(field, types) SV * field unsigned int types PPCODE: { UI lines = SvCUR(field) / VBI_BPL; UI line; decoder dec; decoder_init (&dec, types); EXTEND (SP, lines); for (line = 0; line < lines; line++) { SV *sv = decoder_decode (&dec, line, ((u8*)SvPV_nolen(field)) + line * VBI_BPL); if (sv) PUSHs (sv_2mortal (sv)); } } SV * decode_vps(char *data) SV * decode_vt(char *data) void decode_vtpage(data) SV * data PPCODE: { u8 chr[VT_COLS*VT_LINES]; u16 atr[VT_COLS*VT_LINES]; UI lines; if (!SvPOK(data)) XSRETURN_EMPTY; lines = SvCUR(data) / VT_COLS; if (lines > VT_LINES) croak ("videotext cannot have more than %d lines (argument has %d lines)\n", VT_LINES, lines); Zero(chr, VT_COLS*VT_LINES, u8); Zero(atr, VT_COLS*VT_LINES, u16); if (decode_vtpage (SvPV_nolen(data), lines, chr, atr)) { AV *av = newAV (); UI n; for (n = 0; n < VT_COLS*lines; n++) av_push (av, newSViv (atr[n])); EXTEND (SP, 2); PUSHs (sv_2mortal (newSVpvn (chr, VT_COLS*lines))); PUSHs (sv_2mortal (newRV_noinc ((SV*)av))); } } PROTOTYPES: DISABLE void decode_ansi(chr, atr) SV * chr SV * atr PPCODE: { UI lines = SvCUR(chr) / VT_COLS; UI attr_i = 0; u8 *_chr = SvPV_nolen (chr); u16 _atr[VT_COLS]; EXTEND (SP, lines); while (lines--) { UI attr_j; for(attr_j = 0; attr_j < VT_COLS; attr_j++) _atr[attr_j] = SvIV (*av_fetch ((AV*)SvRV (atr), attr_i+attr_j, 1)); PUSHs (sv_2mortal (decode_ansi (_chr, _atr))); _chr += VT_COLS; attr_i += VT_COLS; } } unsigned int bcd2dec(bcd) unsigned int bcd CODE: { UI digit = 1; RETVAL = 0; while (bcd) { if ((bcd & 15) > 9) XSRETURN_EMPTY; RETVAL += (bcd & 15) * digit; digit *= 10; bcd >>= 4; } } OUTPUT: RETVAL PROTOTYPES: ENABLE MODULE = Video::Capture::VBI PACKAGE = Video::Capture::VBI::EPG void decode_stream(stream) SV * stream PPCODE: if (!SvROK(stream) || SvTYPE(SvRV(stream)) != SVt_PVAV) croak ("decode_epg stream works on arrayrefs"); PUTBACK; decode_stream ((AV*)SvRV(stream)); SPAGAIN; SV * decode_block(block, bundle) SV * block SV * bundle PPCODE: if (!SvROK(bundle) || SvTYPE(SvRV(bundle)) != SVt_PVAV) croak ("bundle info must be arrayref"); PUTBACK; decode_block (SvPV_nolen(block), SvCUR(block), (AV*)SvRV(bundle)); SPAGAIN; BOOT: { HV *stash = gv_stashpvn("Video::Capture::VBI", 19, TRUE); newCONSTSUB(stash,"VBI_VT", newSViv(VBI_VT)); newCONSTSUB(stash,"VBI_VPS", newSViv(VBI_VPS)); newCONSTSUB(stash,"VBI_VDAT", newSViv(VBI_VDAT)); newCONSTSUB(stash,"VBI_VC", newSViv(VBI_VC)); newCONSTSUB(stash,"VBI_EMPTY", newSViv(VBI_EMPTY)); newCONSTSUB(stash,"VBI_OTHER", newSViv(VBI_OTHER)); newCONSTSUB(stash,"VTX_COLMASK",newSViv(VTX_COLMASK)); newCONSTSUB(stash,"VTX_GRSEP", newSViv(VTX_GRSEP)); newCONSTSUB(stash,"VTX_HIDDEN", newSViv(VTX_HIDDEN)); newCONSTSUB(stash,"VTX_BOX", newSViv(VTX_BOX)); newCONSTSUB(stash,"VTX_FLASH", newSViv(VTX_FLASH)); newCONSTSUB(stash,"VTX_DOUBLE1",newSViv(VTX_DOUBLE1)); newCONSTSUB(stash,"VTX_DOUBLE2",newSViv(VTX_DOUBLE2)); newCONSTSUB(stash,"VTX_INVERT", newSViv(VTX_INVERT)); newCONSTSUB(stash,"VTX_DOUBLE", newSViv(VTX_DOUBLE)); } Video-Capture-V4l-0.902/VBI/Makefile.PL0000644000000000000000000000016110211641046015717 0ustar rootrootuse ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'Video::Capture::VBI', 'VERSION_FROM' => 'VBI.pm', ); Video-Capture-V4l-0.902/TODO0000644000000000000000000000003210211640742014014 0ustar rootrootmake && perl -Mblib grab Video-Capture-V4l-0.902/Frequencies.pm0000644000000000000000000005230110211646347016150 0ustar rootrootpackage Video::Frequencies; =head1 NAME Video::Frequencies - Many, many frequency constants and lists. =head1 SYNOPSIS use Video::Frequencies; while (my($name,$list) = each %CHANLIST) { print "$name\n"; while (my($channel,$freq) = each %$list) { printf " %-4s %9d\n", $channel, $freq; } print "\n"; } =head1 DESCRIPTION This module exports (yes, exports!) frequency constants as well as hashes with channel => frequency relations for digital and analog video and audio broadcast. Another, shorter way to put it is "worldwide channel/frequency list". All frequencies are given in kHz. It's a good idea to use C to get an idea on how the various constants and lists look like. =head1 Exported Audio Carrier Frequencies NTSC_AUDIO_CARRIER PAL_AUDIO_CARRIER_I PAL_AUDIO_CARRIER_BGHN PAL_AUDIO_CARRIER_MN PAL_AUDIO_CARRIER_D SEACAM_AUDIO_DKK1L SEACAM_AUDIO_BG NICAM728_PAL_BGH NICAM728_PAL_I NICAM 728 32-kHz, 14-bit digital stereo audio is transmitted in 1ms frames containing 8 bits frame sync, 5 bits control, 11 bits additional data, and 704 bits audio data. The bit rate is reduced by transmitting only 10 bits plus parity of each 14 bit sample, the largest sample in a frame determines which 10 bits are transmitted. The parity bits for audio samples also specify the scaling factor used for that channel during that frame. The companded audio data is interleaved to reduce the influence of dropouts and the whole frame except for sync bits is scrambled for spectrum shaping. Data is modulated using QPSK, at below following subcarrier freqs =head1 Broadcast Format by Country =over 4 =item (M) NTSC Antigua, Aruba, Bahamas, Barbados, Belize, Bermuda, Bolivia, Burma, Canada, Chile, Colombia, Costa Rica, Cuba, Curacao, Dominican Republic, Ecuador, El Salvador, Guam Guatemala, Honduras, Jamaica, Japan, South Korea, Mexico, Montserrat, Myanmar, Nicaragua, Panama, Peru, Philippines, Puerto Rico, St Christopher and Nevis, Samoa, Suriname, Taiwan, Trinidad/Tobago, United States, Venezuela, Virgin Islands =item (B) PAL Albania, Algeria, Australia, Austria, Bahrain, Bangladesh, Belgium, Bosnia-Herzegovinia, Brunei Darussalam, Cambodia, Cameroon, Croatia, Cyprus, Denmark, Egypt, Ethiopia, Equatorial Guinea, Finland, Germany, Ghana, Gibraltar, Greenland, Iceland, India, Indonesia, Israel, Italy, Jordan, Kenya, Kuwait, Liberia, Libya, Luxembourg, Malaysa, Maldives, Malta, Nepal, Netherlands, New Zeland, Nigeria, Norway, Oman, Pakistan, Papua New Guinea, Portugal, Qatar, Sao Tome and Principe, Saudi Arabia, Seychelles, Sierra Leone, Singapore, Slovenia, Somali, Spain, Sri Lanka, Sudan, Swaziland, Sweden, Switzeland, Syria, Thailand, Tunisia, Turkey, Uganda, United Arab Emirates, Yemen =item (N) PAL Argentina (Combination N), Paraguay, Uruguay =item (M) PAL (525/60, 3.57MHz burst) Brazil =item (G) PAL Albania, Algeria, Austria, Bahrain, Bosnia/Herzegovinia, Cambodia, Cameroon, Croatia, Cyprus, Denmark, Egypt, Ethiopia, Equatorial Guinea, Finland, Germany, Gibraltar, Greenland, Iceland, Israel, Italy, Jordan, Kenya, Kuwait, Liberia, Libya, Luxembourg, Malaysia, Monaco, Mozambique, Netherlands, New Zealand, Norway, Oman, Pakistan, Papa New Guinea, Portugal, Qatar, Romania, Sierra Leone, Singapore, Slovenia, Somalia, Spain, Sri Lanka, Sudan, Swaziland, Sweeden, Switzerland, Syria, Thailand, Tunisia, Turkey, United Arab Emirates, Yemen, Zambia, Zimbabwe =item (D) PAL China, North Korea, Romania, Czech Republic =item (H) PAL Belgium =item (I) PAL Angola, Botswana, Gambia, Guinea-Bissau, Hong Kong, Ireland, Lesotho, Malawi, Nambia, Nigeria, South Africa, Tanzania, United Kingdom, Zanzibar =item (B) SECAM Djibouti, Greece, Iran, Iraq, Lebanon, Mali, Mauritania, Mauritus, Morocco =item (D) SECAM Afghanistan, Armenia, Azerbaijan, Belarus, Bulgaria, Estonia, Georgia, Hungary, Zazakhstan, Lithuania, Mongolia, Moldova, Poland, Russia, Slovak Republic, Ukraine, Vietnam =item (G) SECAM Greece, Iran, Iraq, Mali, Mauritus, Morocco, Saudi Arabia =item (K) SECAM Armenia, Azerbaijan, Bulgaria, Estonia, Georgia, Hungary, Kazakhstan, Lithuania, Madagascar, Moldova, Poland, Russia, Slovak Republic, Ukraine, Vietnam =item (K1) SECAM Benin, Burkina Faso, Burundi, Chad, Cape Verde, Central African Republic, Comoros, Congo, Gabon, Madagascar, Niger, Rwanda, Senegal, Togo, Zaire =item (L) SECAM France =back =head1 Channel->Frequency Relations The Channel->Frequency relations are stored in the following hashes. The keys are the Channel names, the values are the corresponding frequency in kHz. For example, "arte" is channel "SE6" in the town in Germany I live in, so, consequently, $PAL_EUROPE{SE6} equals 140250, the frequency I have to tune my receiver. US broadcast %NTSC_BCAST US cable %NTSC_CABLE US HRC %NTSC_HRC JP broadcast %NTSC_BCAST_JP JP cable %NTSC_CABLE_JP Australia %PAL_AUSTRALIA Europe %PAL_EUROPE Europe East %PAL_EUROPE_EAST Italy %PAL_ITALY Ireland %PAL_IRELAND Newzealand %PAL_NEWZEALAND CCIR frequencies %FREQ_CCIR_I_III %FREQ_CCIR_SL_SH %FREQ_CCIR_H OIRT frequencies %FREQ_OIRT_I_III %FREQ_OIRT_SL_SH %FREQ_UHF =head1 The List of Lists The hash %CHANLIST contains name => channel-list pairs, e.g. $CHANLIST{"ntsc-bcast"} contains a reference to %NTSC_BCAST. =head1 AUTHOR Nathan Laredo (laredo@broked.net), adapted to perl by Marc Lehmann =cut require Exporter; @ISA = 'Exporter'; $VERSION = 0.01; @EXPORT = qw( NTSC_AUDIO_CARRIER PAL_AUDIO_CARRIER_I PAL_AUDIO_CARRIER_BGHN PAL_AUDIO_CARRIER_MN PAL_AUDIO_CARRIER_D SEACAM_AUDIO_DKK1L SEACAM_AUDIO_BG NICAM728_PAL_BGH NICAM728_PAL_I %NTSC_BCAST %NTSC_CABLE %NTSC_HRC %NTSC_BCAST_JP %NTSC_CABLE_JP %FREQ_CCIR_I_III %FREQ_CCIR_SL_SH %FREQ_CCIR_H %FREQ_OIRT_I_III %FREQ_OIRT_SL_SH %FREQ_UHF %PAL_AUSTRALIA %PAL_EUROPE %PAL_EUROPE_EAST %PAL_ITALY %PAL_IRELAND %PAL_NEWZEALAND %CHANLIST ); sub NTSC_AUDIO_CARRIER() {4500} sub PAL_AUDIO_CARRIER_I() {6000} sub PAL_AUDIO_CARRIER_BGHN() {5500} sub PAL_AUDIO_CARRIER_MN() {4500} sub PAL_AUDIO_CARRIER_D() {6500} sub SEACAM_AUDIO_DKK1L() {6500} sub SEACAM_AUDIO_BG() {5500} sub NICAM728_PAL_BGH() {5850} sub NICAM728_PAL_I() {6552} %NTSC_BCAST = ( "2", 55250, "3", 61250, "4", 67250, "5", 77250, "6", 83250, "7", 175250, "8", 181250, "9", 187250, "10", 193250, "11", 199250, "12", 205250, "13", 211250, "14", 471250, "15", 477250, "16", 483250, "17", 489250, "18", 495250, "19", 501250, "20", 507250, "21", 513250, "22", 519250, "23", 525250, "24", 531250, "25", 537250, "26", 543250, "27", 549250, "28", 555250, "29", 561250, "30", 567250, "31", 573250, "32", 579250, "33", 585250, "34", 591250, "35", 597250, "36", 603250, "37", 609250, "38", 615250, "39", 621250, "40", 627250, "41", 633250, "42", 639250, "43", 645250, "44", 651250, "45", 657250, "46", 663250, "47", 669250, "48", 675250, "49", 681250, "50", 687250, "51", 693250, "52", 699250, "53", 705250, "54", 711250, "55", 717250, "56", 723250, "57", 729250, "58", 735250, "59", 741250, "60", 747250, "61", 753250, "62", 759250, "63", 765250, "64", 771250, "65", 777250, "66", 783250, "67", 789250, "68", 795250, "69", 801250, "70", 807250, "71", 813250, "72", 819250, "73", 825250, "74", 831250, "75", 837250, "76", 843250, "77", 849250, "78", 855250, "79", 861250, "80", 867250, "81", 873250, "82", 879250, "83", 885250, ); %NTSC_CABLE = ( "1", 73250, "2", 55250, "3", 61250, "4", 67250, "5", 77250, "6", 83250, "7", 175250, "8", 181250, "9", 187250, "10", 193250, "11", 199250, "12", 205250, "13", 211250, "14", 121250, "15", 127250, "16", 133250, "17", 139250, "18", 145250, "19", 151250, "20", 157250, "21", 163250, "22", 169250, "23", 217250, "24", 223250, "25", 229250, "26", 235250, "27", 241250, "28", 247250, "29", 253250, "30", 259250, "31", 265250, "32", 271250, "33", 277250, "34", 283250, "35", 289250, "36", 295250, "37", 301250, "38", 307250, "39", 313250, "40", 319250, "41", 325250, "42", 331250, "43", 337250, "44", 343250, "45", 349250, "46", 355250, "47", 361250, "48", 367250, "49", 373250, "50", 379250, "51", 385250, "52", 391250, "53", 397250, "54", 403250, "55", 409250, "56", 415250, "57", 421250, "58", 427250, "59", 433250, "60", 439250, "61", 445250, "62", 451250, "63", 457250, "64", 463250, "65", 469250, "66", 475250, "67", 481250, "68", 487250, "69", 493250, "70", 499250, "71", 505250, "72", 511250, "73", 517250, "74", 523250, "75", 529250, "76", 535250, "77", 541250, "78", 547250, "79", 553250, "80", 559250, "81", 565250, "82", 571250, "83", 577250, "84", 583250, "85", 589250, "86", 595250, "87", 601250, "88", 607250, "89", 613250, "90", 619250, "91", 625250, "92", 631250, "93", 637250, "94", 643250, "95", 91250, "96", 97250, "97", 103250, "98", 109250, "99", 115250, "100", 649250, "101", 655250, "102", 661250, "103", 667250, "104", 673250, "105", 679250, "106", 685250, "107", 691250, "108", 697250, "109", 703250, "110", 709250, "111", 715250, "112", 721250, "113", 727250, "114", 733250, "115", 739250, "116", 745250, "117", 751250, "118", 757250, "119", 763250, "120", 769250, "121", 775250, "122", 781250, "123", 787250, "124", 793250, "125", 799250, "T7", 8250, "T8", 14250, "T9", 20250, "T10", 26250, "T11", 32250, "T12", 38250, "T13", 44250, "T14", 50250, ); %NTSC_HRC = ( "1", 72000, "2", 54000, "3", 60000, "4", 66000, "5", 78000, "6", 84000, "7", 174000, "8", 180000, "9", 186000, "10", 192000, "11", 198000, "12", 204000, "13", 210000, "14", 120000, "15", 126000, "16", 132000, "17", 138000, "18", 144000, "19", 150000, "20", 156000, "21", 162000, "22", 168000, "23", 216000, "24", 222000, "25", 228000, "26", 234000, "27", 240000, "28", 246000, "29", 252000, "30", 258000, "31", 264000, "32", 270000, "33", 276000, "34", 282000, "35", 288000, "36", 294000, "37", 300000, "38", 306000, "39", 312000, "40", 318000, "41", 324000, "42", 330000, "43", 336000, "44", 342000, "45", 348000, "46", 354000, "47", 360000, "48", 366000, "49", 372000, "50", 378000, "51", 384000, "52", 390000, "53", 396000, "54", 402000, "55", 408000, "56", 414000, "57", 420000, "58", 426000, "59", 432000, "60", 438000, "61", 444000, "62", 450000, "63", 456000, "64", 462000, "65", 468000, "66", 474000, "67", 480000, "68", 486000, "69", 492000, "70", 498000, "71", 504000, "72", 510000, "73", 516000, "74", 522000, "75", 528000, "76", 534000, "77", 540000, "78", 546000, "79", 552000, "80", 558000, "81", 564000, "82", 570000, "83", 576000, "84", 582000, "85", 588000, "86", 594000, "87", 600000, "88", 606000, "89", 612000, "90", 618000, "91", 624000, "92", 630000, "93", 636000, "94", 642000, "95", 900000, "96", 960000, "97", 102000, "98", 108000, "99", 114000, "100", 648000, "101", 654000, "102", 660000, "103", 666000, "104", 672000, "105", 678000, "106", 684000, "107", 690000, "108", 696000, "109", 702000, "110", 708000, "111", 714000, "112", 720000, "113", 726000, "114", 732000, "115", 738000, "116", 744000, "117", 750000, "118", 756000, "119", 762000, "120", 768000, "121", 774000, "122", 780000, "123", 786000, "124", 792000, "125", 798000, "T7", 7000, "T8", 13000, "T9", 19000, "T10", 25000, "T11", 31000, "T12", 37000, "T13", 43000, "T14", 49000, ); %NTSC_BCAST_JP = ( "1", 91250, "2", 97250, "3", 103250, "4", 171250, "5", 177250, "6", 183250, "7", 189250, "8", 193250, "9", 199250, "10", 205250, "11", 211250, "12", 217250, "13", 471250, "14", 477250, "15", 483250, "16", 489250, "17", 495250, "18", 501250, "19", 507250, "20", 513250, "21", 519250, "22", 525250, "23", 531250, "24", 537250, "25", 543250, "26", 549250, "27", 555250, "28", 561250, "29", 567250, "30", 573250, "31", 579250, "32", 585250, "33", 591250, "34", 597250, "35", 603250, "36", 609250, "37", 615250, "38", 621250, "39", 627250, "40", 633250, "41", 639250, "42", 645250, "43", 651250, "44", 657250, "45", 663250, "46", 669250, "47", 675250, "48", 681250, "49", 687250, "50", 693250, "51", 699250, "52", 705250, "53", 711250, "54", 717250, "55", 723250, "56", 729250, "57", 735250, "58", 741250, "59", 747250, "60", 753250, "61", 759250, "62", 765250, ); %NTSC_CABLE_JP = ( "13", 109250, "14", 115250, "15", 121250, "16", 127250, "17", 133250, "18", 139250, "19", 145250, "20", 151250, "21", 157250, "22", 165250, "23", 223250, "24", 231250, "25", 237250, "26", 243250, "27", 249250, "28", 253250, "29", 259250, "30", 265250, "31", 271250, "32", 277250, "33", 283250, "34", 289250, "35", 295250, "36", 301250, "37", 307250, "38", 313250, "39", 319250, "40", 325250, "41", 331250, "42", 337250, "43", 343250, "44", 349250, "45", 355250, "46", 361250, "47", 367250, "48", 373250, "49", 379250, "50", 385250, "51", 391250, "52", 397250, "53", 403250, "54", 409250, "55", 415250, "56", 421250, "57", 427250, "58", 433250, "59", 439250, "60", 445250, "61", 451250, "62", 457250, "63", 463250, ); %PAL_AUSTRALIA = ( "0", 46250, "1", 57250, "2", 64250, "3", 86250, "4", 95250, "5", 102250, "6", 175250, "7", 182250, "8", 189250, "9", 196250, "10", 209250, "11", 216250, "28", 527250, "29", 534250, "30", 541250, "31", 548250, "32", 555250, "33", 562250, "34", 569250, "35", 576250, "39", 604250, "40", 611250, "41", 618250, "42", 625250, "43", 632250, "44", 639250, "45", 646250, "46", 653250, "47", 660250, "48", 667250, "49", 674250, "50", 681250, "51", 688250, "52", 695250, "53", 702250, "54", 709250, "55", 716250, "56", 723250, "57", 730250, "58", 737250, "59", 744250, "60", 751250, "61", 758250, "62", 765250, "63", 772250, "64", 779250, "65", 786250, "66", 793250, "67", 800250, "68", 807250, "69", 814250, ); %FREQ_CCIR_I_III = ( "E2", 48250, "E3", 55250, "E4", 62250, "S01", 69250, "S02", 76250, "S03", 83250, "E5", 175250, "E6", 182250, "E7", 189250, "E8", 196250, "E9", 203250, "E10", 210250, "E11", 217250, "E12", 224250, ); %FREQ_CCIR_SL_SH = ( "SE1", 105250, "SE2", 112250, "SE3", 119250, "SE4", 126250, "SE5", 133250, "SE6", 140250, "SE7", 147250, "SE8", 154250, "SE9", 161250, "SE10", 168250, "SE11", 231250, "SE12", 238250, "SE13", 245250, "SE14", 252250, "SE15", 259250, "SE16", 266250, "SE17", 273250, "SE18", 280250, "SE19", 287250, "SE20", 294250, ); %FREQ_CCIR_H = ( "S21", 303250, "S22", 311250, "S23", 319250, "S24", 327250, "S25", 335250, "S26", 343250, "S27", 351250, "S28", 359250, "S29", 367250, "S30", 375250, "S31", 383250, "S32", 391250, "S33", 399250, "S34", 407250, "S35", 415250, "S36", 423250, "S37", 431250, "S38", 439250, "S39", 447250, "S40", 455250, "S41", 463250, ); %FREQ_OIRT_I_III = ( "R1", 49750, "R2", 59250, "R3", 77250, "R4", 84250, "R5", 93250, "R6", 175250, "R7", 183250, "R8", 191250, "R9", 199250, "R10", 207250, "R11", 215250, "R12", 223250, ); %FREQ_OIRT_SL_SH = ( "SR1", 111250, "SR2", 119250, "SR3", 127250, "SR4", 135250, "SR5", 143250, "SR6", 151250, "SR7", 159250, "SR8", 167250, "SR11", 231250, "SR12", 239250, "SR13", 247250, "SR14", 255250, "SR15", 263250, "SR16", 271250, "SR17", 279250, "SR18", 287250, "SR19", 295250, ); %FREQ_UHF = ( "21", 471250, "22", 479250, "23", 487250, "24", 495250, "25", 503250, "26", 511250, "27", 519250, "28", 527250, "29", 535250, "30", 543250, "31", 551250, "32", 559250, "33", 567250, "34", 575250, "35", 583250, "36", 591250, "37", 599250, "38", 607250, "39", 615250, "40", 623250, "41", 631250, "42", 639250, "43", 647250, "44", 655250, "45", 663250, "46", 671250, "47", 679250, "48", 687250, "49", 695250, "50", 703250, "51", 711250, "52", 719250, "53", 727250, "54", 735250, "55", 743250, "56", 751250, "57", 759250, "58", 767250, "59", 775250, "60", 783250, "61", 791250, "62", 799250, "63", 807250, "64", 815250, "65", 823250, "66", 831250, "67", 839250, "68", 847250, "69", 855250, ); %PAL_EUROPE = ( %FREQ_CCIR_I_III, %FREQ_CCIR_SL_SH, %FREQ_CCIR_H, %FREQ_UHF ); %PAL_EUROPE_EAST = ( %FREQ_OIRT_I_III, %FREQ_OIRT_SL_SH, %FREQ_CCIR_H, %FREQ_UHF ); %PAL_ITALY = ( "2", 53750, "3", 62250, "4", 82250, "5", 175250, "6", 183750, "7", 192250, "8", 201250, "9", 210250, "10", 210250, "11", 217250, "12", 224250, ); %PAL_IRELAND = ( "0", 45750, "1", 53750, "2", 61750, "3", 175250, "4", 183250, "5", 191250, "6", 199250, "7", 207250, "8", 215250, %FREQ_UHF, ); %PAL_NEWZEALAND = ( "1", 45250, "2", 55250, "3", 62250, "4", 175250, "5", 182250, "5A", 138250, "6", 189250, "7", 196250, "8", 203250, "9", 210250, "10", 217250, ); %CHANLIST = ( "ntsc-bcast", \%NTSC_BCAST, "ntsc-cable", \%NTSC_CABLE, "ntsc-cable-hrc", \%NTSC_HRC, "ntsc-bcast-jp", \%NTSC_BCAST_JP, "ntsc-cable-jp", \%NTSC_CABLE_JP, "pal-europe", \%PAL_EUROPE, "pal-europe-east", \%PAL_EUROPE_EAST, "pal-italy", \%PAL_ITALY, "pal-newzealand", \%PAL_NEWZEALAND, "pal-australia", \%PAL_AUSTRALIA, "pal-ireland", \%PAL_IRELAND, ); 1; Video-Capture-V4l-0.902/README0000644000000000000000000000342011042166057014215 0ustar rootrootNAME Video::Capture::V4l - Perl interface to the Video4linux framegrabber interface. SYNOPSIS use Video::Capture::V4l; DESCRIPTION Not documentation AGAIN! Please see the scripts grab, inexer or vbi that are packaged in the distribution and direct any question and feature requests (as well as bug reports) to the author. Exported constants The following hideous constants are defined in the "Video::Capture::V4l" package, but you rarely need to use them. AUDIO_BASS AUDIO_MUTABLE AUDIO_MUTE AUDIO_TREBLE AUDIO_VOLUME CAPTURE_EVEN CAPTURE_ODD MAX_FRAME MODE_AUTO MODE_NTSC MODE_PAL MODE_SECAM PALETTE_COMPONENT PALETTE_GREY PALETTE_HI240 PALETTE_PLANAR PALETTE_RAW PALETTE_RGB24 PALETTE_RGB32 PALETTE_RGB555 PALETTE_RGB565 PALETTE_UYVY PALETTE_YUV410P PALETTE_YUV411 PALETTE_YUV411P PALETTE_YUV420 PALETTE_YUV420P PALETTE_YUV422 PALETTE_YUV422P PALETTE_YUYV SOUND_LANG1 SOUND_LANG2 SOUND_MONO SOUND_STEREO TUNER_LOW TUNER_MBS_ON TUNER_NORM TUNER_NTSC TUNER_PAL TUNER_RDS_ON TUNER_SECAM TUNER_STEREO_ON TYPE_CAMERA TYPE_TV VC_AUDIO VC_TUNER TYPE_CAPTURE TYPE_CHROMAKEY TYPE_CLIPPING TYPE_FRAMERAM TYPE_MONOCHROME TYPE_OVERLAY TYPE_SCALES TYPE_SUBCAPTURE TYPE_TELETEXT TYPE_TUNER AUTHOR Marc Lehmann LICENSE This module is available under GPL only (see the file COPYING for details), if you want an exception please contact the author, who might grant exceptions freely ;) SEE ALSO perl(1). Video-Capture-V4l-0.902/RTjpeg/0000755000000000000000000000000011042166057014531 5ustar rootrootVideo-Capture-V4l-0.902/RTjpeg/codec/0000755000000000000000000000000011042166057015606 5ustar rootrootVideo-Capture-V4l-0.902/RTjpeg/codec/README0000644000000000000000000001460007057727374016507 0ustar rootroot[release 0.1.2] RTjpeg (C) 1998 Justin Schoeman (justin@suntiger.ee.up.ac.za) License+Disclaimer ================== This code is distributed under GPLv2 (in other words, do what you like with it, but don't sell it, and give credit if you use it). THIS SOFTWARE IS IN NO WAY GUARANTEED TO WORK. IF YOU USE IT AND IT DOESN'T WORK, OR MESSES UP YOUR COMPUTER, IT'S YOUR OWN PROBLEM. General: ======== This is still a rather developmental real time compressor. It is based on the jpeg compressor by the IJG (see LICENSE.jpeg for license details). The only real difference is the encoder. This compressor uses a home brew redundant data coder (makes use of the fact that some co-efficients have a limited range) to very quickly (but not that efficiently) encode the data. Basic interframe coding (only coefficients that have varied significantly are transmitted) is included. This codec is currently real time at CIF resolutions on anything faster than a pentium 200 (on most P133s too now). Installation: ============= A number of modules are avaliable (in the modules directory). Some work better on different architectures. Select the module of your choice by editing compose.sh . Please benchmark these routines on various machines and send me your compression/decompression rate (and machine type). Applications: ============= test: *out of date* captures from bttv0 and compresses to out.pgm (1 image). test2 : compresses to stdout with Q factor Q. The input file is a PPM with 2h2v subsapled Cr and Cb attached to the end. test3 : capture compressed stream to "ostr" with Q factor Q and motion threshold "M". test3d: play "ostr" on X display. Hard coded for 32bpp, change Rtjpeg_yuvrgb32 to the conversion of your choice. TC(subdir): experimental constrained rate encoder. VS(subdir): experimental compressed Vstream version. Using the library: ================== (see below for function descriptions) To compress single images: 1) RTjpeg_init_compress 2) (it is a good idea to save the tables with the image) 3) RTjpeg_compress 4) save result. To decompress a single image: 1) Read saved tables (or call RTjpeg_init_compress with the same Q factor as was used to compress the data) 2) RTjpeg_init_decompress 3) store the YUV420 image, or 3) RTjpeg_yuvrgbXX where XX is the desired RGB depth (8 (grey) 16 (565) 24 and 32) 4) (possible) RTjpeg_doubleXX to double the image size. To compress an image stream (with interframe coding): As for single image except: 1) RTjpeg_init_mcompress AFTER RTjpeg_init compress. 2) Use RTjpeg_mcompress instead of RTjpeg_compress To decompress an image stream (with interframe coding): As for single frame except: 1) Initialise output buffer to 0's 2) do not modify the output buffer except by RTjpeg_decompress. RTjpeg Functions: ================= (some functions may not yet be implemented for all module types) extern void RTjpeg_init_Q(__u8 Q); ---------------------------------- Change the quality factor for future compressions/decompressions to Q. Q=255 ==> IJG jpeg 75% (max) Q=128 ==> IJG jpeg 50% Q=32 (min usable) Q=1 (abstract art) extern void RTjpeg_init_compress(__u32 *buf, int width, int height, __u8 Q); ---------------------------------------------------------------------------- Initialise the compressor. *buf is a pointer to 128 ints. The de-quantizer values are stored in this array. It is best to save these with the image for reliable decompression between versions (although it is probably not necessary). width is the width of the Y component of the image. height is the height of the Y component of the image. Q is the quality factor (see above) extern void RTjpeg_init_decompress(__u32 *buf, int width, int height); ---------------------------------------------------------------------- Initialise decompressor (and color convertor). *buf is a pointer to the 128 ints produced by init_compress. width and height, as before. extern int RTjpeg_compress(__s8 *sp, unsigned char *bp); -------------------------------------------------------- Compress the image. *sp is a pointer to the output data (for safety, this buffer should be as large as the uncompressed data). *bp is a pointer to the input data (YUV420P format). RETURN: the number of bytes actually used for the output stream. extern void RTjpeg_decompress(__s8 *sp, __u8 *bp); -------------------------------------------------- Decompress the image. as before (no RETURN). extern void RTjpeg_init_mcompress(void); ---------------------------------------- Initialise interframe compression. extern int RTjpeg_mcompress(__s8 *sp, unsigned char *bp, __u16 lmask, __u16 cmask); ----------------------------------------------------------------------------------- Perform interframe compression. *sp, *bp as for compress lmask, cmask threshold value for change in quantized luma and chroma components before transmitting the block. NB works on quantized values, so use lower thresholds for lower Q values. extern void RTjpeg_set_test(int i); ----------------------------------- Enable test-compressions. i=0: disable test mode i=1: enable test mode (In test mode interframe compression is performed WITHOUT updating the local copy of the reference image. This is used for constrained rate encoding to test multiple compression factors for compressed block size. Remember to call mcompress with test mode = 0 BEFORE transmitting an encoded block.) extern void RTjpeg_yuvrgb(__u8 *buf, __u8 *rgb); ------------------------------------------------ Convert decompressed YUV420P data to RGB data *buf pointer to YUV420P data *rgb pointer to RGB data extern void RTjpeg_yuvrgb32(__u8 *buf, __u8 *rgb); -------------------------------------------------- convert to RGB32 data (display order) extern void RTjpeg_yuvrgb24(__u8 *buf, __u8 *rgb); -------------------------------------------------- convert to RGB24 (display order) extern void RTjpeg_yuvrgb16(__u8 *buf, __u8 *rgb); -------------------------------------------------- convert to RGB 565 extern void RTjpeg_yuvrgb8(__u8 *buf, __u8 *rgb); ------------------------------------------------- convert to grey-scale (grin) extern void RTjpeg_double32(__u32 *buf); extern void RTjpeg_double24(__u8 *buf); extern void RTjpeg_double16(__u16 *buf); extern void RTjpeg_double8(__u8 *buf); -------------------------------------- convert the image pointed to by *buf to double size (size is determined by with and height from init_decompress). Video-Capture-V4l-0.902/RTjpeg/codec/RTjpeg.h0000644000000000000000000000165710211641103017146 0ustar rootroot#include "stdint.h" typedef int8_t s8; typedef int16_t s16; typedef int32_t s32; typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; typedef u32 RTjpeg_tables[128]; void RTjpeg_init_Q(u8 Q); void RTjpeg_init_compress(u32 *buf, int width, int height, u8 Q); void RTjpeg_init_decompress(u32 *buf, int width, int height); int RTjpeg_compress(s8 *sp, unsigned char *bp); void RTjpeg_decompress(s8 *sp, u8 *bp); void RTjpeg_init_mcompress(void); int RTjpeg_mcompress(s8 *sp, unsigned char *bp, u16 lmask, u16 cmask, int x, int y, int w, int h); void RTjpeg_set_test(int i); void RTjpeg_yuvrgb(u8 *buf, u8 *rgb); void RTjpeg_yuvrgb32(u8 *buf, u8 *rgb); void RTjpeg_yuvrgb24(u8 *buf, u8 *rgb); void RTjpeg_yuvrgb16(u8 *buf, u8 *rgb); void RTjpeg_yuvrgb8(u8 *buf, u8 *rgb); void RTjpeg_double32(u32 *buf); void RTjpeg_double24(u8 *buf); void RTjpeg_double16(u16 *buf); void RTjpeg_double8(u8 *buf); Video-Capture-V4l-0.902/RTjpeg/codec/LICENSE.jpeg0000644000000000000000000004731406613115436017553 0ustar rootrootThis is the origional README file for the libjpeg source. Some of the modules used in RTjpeg have been taken from this package. The changes are in most cases too extensive to document, however, the core logic stays the same. The affected modules are RTdct.c and RTidct.c -Justin Schoeman 1998 The Independent JPEG Group's JPEG software ========================================== README for release 6a of 7-Feb-96 ================================= This distribution contains the sixth public release of the Independent JPEG Group's free JPEG software. You are welcome to redistribute this software and to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. Serious users of this software (particularly those incorporating it into larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to our electronic mailing list. Mailing list members are notified of updates and have a chance to participate in technical discussions, etc. This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi, Ge' Weijers, and other members of the Independent JPEG Group. IJG is not affiliated with the official ISO JPEG standards committee. DOCUMENTATION ROADMAP ===================== This file contains the following sections: OVERVIEW General description of JPEG and the IJG software. LEGAL ISSUES Copyright, lack of warranty, terms of distribution. REFERENCES Where to learn more about JPEG. ARCHIVE LOCATIONS Where to find newer versions of this software. RELATED SOFTWARE Other stuff you should get. FILE FORMAT WARS Software *not* to get. TO DO Plans for future IJG releases. Other documentation files in the distribution are: User documentation: install.doc How to configure and install the IJG software. usage.doc Usage instructions for cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom. *.1 Unix-style man pages for programs (same info as usage.doc). wizard.doc Advanced usage instructions for JPEG wizards only. change.log Version-to-version change highlights. Programmer and internal documentation: libjpeg.doc How to use the JPEG library in your own programs. example.c Sample code for calling the JPEG library. structure.doc Overview of the JPEG library's internal structure. filelist.doc Road map of IJG files. coderules.doc Coding style rules --- please read if you contribute code. Please read at least the files install.doc and usage.doc. Useful information can also be found in the JPEG FAQ (Frequently Asked Questions) article. See ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. If you want to understand how the JPEG code works, we suggest reading one or more of the REFERENCES, then looking at the documentation files (in roughly the order listed) before diving into the code. OVERVIEW ======== This package contains C software to implement JPEG image compression and decompression. JPEG (pronounced "jay-peg") is a standardized compression method for full-color and gray-scale images. JPEG is intended for compressing "real-world" scenes; line drawings, cartoons and other non-realistic images are not its strong suit. JPEG is lossy, meaning that the output image is not exactly identical to the input image. Hence you must not use JPEG if you have to have identical output bits. However, on typical photographic images, very good compression levels can be obtained with no visible change, and remarkably high compression levels are possible if you can tolerate a low-quality image. For more details, see the references, or just experiment with various compression settings. This software implements JPEG baseline, extended-sequential, and progressive compression processes. Provision is made for supporting all variants of these processes, although some uncommon parameter settings aren't implemented yet. For legal reasons, we are not distributing code for the arithmetic-coding variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting the hierarchical or lossless processes defined in the standard. We provide a set of library routines for reading and writing JPEG image files, plus two sample applications "cjpeg" and "djpeg", which use the library to perform conversion between JPEG and some other popular image file formats. The library is intended to be reused in other applications. In order to support file conversion and viewing software, we have included considerable functionality beyond the bare JPEG coding/decoding capability; for example, the color quantization modules are not strictly part of JPEG decoding, but they are essential for output to colormapped file formats or colormapped displays. These extra functions can be compiled out of the library if not required for a particular application. We have also included "jpegtran", a utility for lossless transcoding between different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple applications for inserting and extracting textual comments in JFIF files. The emphasis in designing this software has been on achieving portability and flexibility, while also making it fast enough to be useful. In particular, the software is not intended to be read as a tutorial on JPEG. (See the REFERENCES section for introductory material.) Rather, it is intended to be reliable, portable, industrial-strength code. We do not claim to have achieved that goal in every aspect of the software, but we strive for it. We welcome the use of this software as a component of commercial products. No royalty is required, but we do ask for an acknowledgement in product documentation, as described under LEGAL ISSUES. LEGAL ISSUES ============ In plain English: 1. We don't promise that this software works. (But if you find any bugs, please let us know!) 2. You can use this software for whatever you want. You don't have to pay us. 3. You may not pretend that you wrote this software. If you use it in a program, you must acknowledge somewhere in your documentation that you've used the IJG code. In legalese: The authors make NO WARRANTY or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. This software is provided "AS IS", and you, its user, assume the entire risk as to its quality and accuracy. This software is copyright (C) 1991-1996, Thomas G. Lane. All Rights Reserved except as specified below. Permission is hereby granted to use, copy, modify, and distribute this software (or portions thereof) for any purpose, without fee, subject to these conditions: (1) If any part of the source code for this software is distributed, then this README file must be included, with this copyright and no-warranty notice unaltered; and any additions, deletions, or changes to the original files must be clearly indicated in accompanying documentation. (2) If only executable code is distributed, then the accompanying documentation must state that "this software is based in part on the work of the Independent JPEG Group". (3) Permission for use of this software is granted only if the user accepts full responsibility for any undesirable consequences; the authors accept NO LIABILITY for damages of any kind. These conditions apply to any software derived from or based on the IJG code, not just to the unmodified library. If you use our work, you ought to acknowledge us. Permission is NOT granted for the use of any IJG author's name or company name in advertising or publicity relating to this software or products derived from it. This software may be referred to only as "the Independent JPEG Group's software". We specifically permit and encourage the use of this software as the basis of commercial products, provided that all warranty or liability claims are assumed by the product vendor. ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. ansi2knr.c is NOT covered by the above copyright and conditions, but instead by the usual distribution terms of the Free Software Foundation; principally, that you must include source code if you redistribute it. (See the file ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part of any program generated from the IJG code, this does not limit you more than the foregoing paragraphs do. The configuration script "configure" was produced with GNU Autoconf. It is copyright by the Free Software Foundation but is freely distributable. It appears that the arithmetic coding option of the JPEG spec is covered by patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot legally be used without obtaining one or more licenses. For this reason, support for arithmetic coding has been removed from the free JPEG software. (Since arithmetic coding provides only a marginal gain over the unpatented Huffman mode, it is unlikely that very many implementations will support it.) So far as we are aware, there are no patent restrictions on the remaining code. WARNING: Unisys has begun to enforce their patent on LZW compression against GIF encoders and decoders. You will need a license from Unisys to use the included rdgif.c or wrgif.c files in a commercial or shareware application. At this time, Unisys is not enforcing their patent against freeware, so distribution of this package remains legal. However, we intend to remove GIF support from the IJG package as soon as a suitable replacement format becomes reasonably popular. We are required to state that "The Graphics Interchange Format(c) is the Copyright property of CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated." REFERENCES ========== We highly recommend reading one or more of these references before trying to understand the innards of the JPEG software. The best short technical introduction to the JPEG compression algorithm is Wallace, Gregory K. "The JPEG Still Picture Compression Standard", Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. (Adjacent articles in that issue discuss MPEG motion picture compression, applications of JPEG, and related topics.) If you don't have the CACM issue handy, a PostScript file containing a revised version of Wallace's article is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually a preprint for an article that appeared in IEEE Trans. Consumer Electronics) omits the sample images that appeared in CACM, but it includes corrections and some added material. Note: the Wallace article is copyright ACM and IEEE, and it may not be used for commercial purposes. A somewhat less technical, more leisurely introduction to JPEG can be found in "The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and example C code for a multitude of compression methods including JPEG. It is an excellent source if you are comfortable reading C code but don't know much about data compression in general. The book's JPEG sample code is far from industrial-strength, but when you are ready to look at a full implementation, you've got one here... The best full description of JPEG is the textbook "JPEG Still Image Data Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG standards (DIS 10918-1 and draft DIS 10918-2). This is by far the most complete exposition of JPEG in existence, and we highly recommend it. The JPEG standard itself is not available electronically; you must order a paper copy through ISO or ITU. (Unless you feel a need to own a certified official copy, we recommend buying the Pennebaker and Mitchell book instead; it's much cheaper and includes a great deal of useful explanatory material.) In the USA, copies of the standard may be ordered from ANSI Sales at (212) 642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI doesn't take credit card orders, but Global does.) It's not cheap: as of 1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7% shipping/handling. The standard is divided into two parts, Part 1 being the actual specification, while Part 2 covers compliance testing methods. Part 1 is titled "Digital Compression and Coding of Continuous-tone Still Images, Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS 10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of Continuous-tone Still Images, Part 2: Compliance testing" and has document numbers ISO/IEC IS 10918-2, ITU-T T.83. Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO document. Part 3 is undergoing ISO balloting and is expected to be approved by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T T.84. IJG currently does not support any Part 3 extensions. The JPEG standard does not specify all details of an interchangeable file format. For the omitted details we follow the "JFIF" conventions, revision 1.02. A copy of the JFIF spec is available from: Literature Department C-Cube Microsystems, Inc. 1778 McCarthy Blvd. Milpitas, CA 95035 phone (408) 944-6300, fax (408) 944-6314 A PostScript version of this document is available at ftp.uu.net, file graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" to the server to obtain the JFIF document; send the message "help" if you have trouble. The TIFF 6.0 file format specification can be obtained by FTP from sgi.com (192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed copy from Aldus Corp. at (206) 628-6593. The JPEG incorporation scheme found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 (Compression tag 7). Copies of this Note can be obtained from sgi.com or from ftp.uu.net:/graphics/jpeg/. It is expected that the next revision of the TIFF spec will replace the 6.0 JPEG design with the Note's design. Although IJG's own code does not support TIFF/JPEG, the free libtiff library uses our library to implement TIFF/JPEG per the Note. libtiff is available from sgi.com:/graphics/tiff/. ARCHIVE LOCATIONS ================= The "official" archive site for this software is ftp.uu.net (Internet address 192.48.96.9). The most recent released version can always be found there in directory graphics/jpeg. This particular version will be archived as graphics/jpeg/jpegsrc.v6a.tar.gz. If you are on the Internet, you can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't have FTP access, UUNET's archives are also available via UUCP; contact help@uunet.uu.net for information on retrieving files that way. Numerous Internet sites maintain copies of the UUNET files. However, only ftp.uu.net is guaranteed to have the latest official version. You can also obtain this software in DOS-compatible "zip" archive format from the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net release. The JPEG FAQ (Frequently Asked Questions) article is a useful source of general information about JPEG. It is updated constantly and therefore is not included in this distribution. The FAQ is posted every two weeks to Usenet newsgroups comp.graphics.misc, news.answers, and other groups. You can always obtain the latest version from the news.answers archive at rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and .../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu with body send usenet/news.answers/jpeg-faq/part1 send usenet/news.answers/jpeg-faq/part2 RELATED SOFTWARE ================ Numerous viewing and image manipulation programs now support JPEG. (Quite a few of them use this library to do so.) The JPEG FAQ described above lists some of the more popular free and shareware viewers, and tells where to obtain them on Internet. If you are on a Unix machine, we highly recommend Jef Poskanzer's free PBMPLUS image software, which provides many useful operations on PPM-format image files. In particular, it can convert PPM images to and from a wide range of other formats. You can obtain this package by FTP from ftp.x.org (contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also a newer update of this package called NETPBM, available from wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/. Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is; you are likely to have difficulty making it work on any non-Unix machine. A different free JPEG implementation, written by the PVRG group at Stanford, is available from havefun.stanford.edu in directory pub/jpeg. This program is designed for research and experimentation rather than production use; it is slower, harder to use, and less portable than the IJG code, but it is easier to read and modify. Also, the PVRG code supports lossless JPEG, which we do not. FILE FORMAT WARS ================ Some JPEG programs produce files that are not compatible with our library. The root of the problem is that the ISO JPEG committee failed to specify a concrete file format. Some vendors "filled in the blanks" on their own, creating proprietary formats that no one else could read. (For example, none of the early commercial JPEG implementations for the Macintosh were able to exchange compressed files.) The file format we have adopted is called JFIF (see REFERENCES). This format has been agreed to by a number of major commercial JPEG vendors, and it has become the de facto standard. JFIF is a minimal or "low end" representation. We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF Technical Note #2) for "high end" applications that need to record a lot of additional data about an image. TIFF/JPEG is fairly new and not yet widely supported, unfortunately. The upcoming JPEG Part 3 standard defines a file format called SPIFF. SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should be able to read the most common variant of SPIFF. SPIFF has some technical advantages over JFIF, but its major claim to fame is simply that it is an official standard rather than an informal one. At this point it is unclear whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto standard. IJG intends to support SPIFF once the standard is frozen, but we have not decided whether it should become our default output format or not. (In any case, our decoder will remain capable of reading JFIF indefinitely.) Various proprietary file formats incorporating JPEG compression also exist. We have little or no sympathy for the existence of these formats. Indeed, one of the original reasons for developing this free software was to help force convergence on common, open format standards for JPEG files. Don't use a proprietary file format! TO DO ===== In future versions, we are considering supporting some of the upcoming JPEG Part 3 extensions --- principally, variable quantization and the SPIFF file format. Tuning the software for better behavior at low quality/high compression settings is also of interest. The current method for scaling the quantization tables is known not to be very good at low Q values. As always, speeding things up is high on our priority list. Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net. Video-Capture-V4l-0.902/RTjpeg/codec/compose.sh0000755000000000000000000000135007057752703017623 0ustar rootroot#!/bin/sh #DCTOBJS="RTdct_std RTidct_std" DCTOBJS="RTdct_aan RTidct_aan" #YUVOBJS="RTcolor_std" #YUVOBJS="RTcolor_tbl" #YUVOBJS="RTcolor_tbl2" YUVOBJS="RTcolor_int" #YUVOBJS="RTcolor_grey" QOBJS="RTquant" #QOBJS="RTquant_mmx" BOBJS="RTb2s RTs2b" #BOBJS="RTb2s_raw RTs2b_raw" OBJS="RTinc ${BOBJS} ${QOBJS} ${YUVOBJS} ${DCTOBJS} RTmain" echo "/* Autogenerated by compose.sh */" > RTjpeg.c echo "#include \"RTjpeg.h\"" >> RTjpeg.c echo "" >> RTjpeg.c echo "**** Init files ****" for i in ${OBJS}; do if [ -f modules/${i}.ct ]; then echo ${i}.ct cat modules/$i.ct >> RTjpeg.c fi done echo "**** Code files ****" for i in ${OBJS}; do if [ -f modules/${i}.c ]; then echo ${i}.c cat modules/$i.c >> RTjpeg.c fi done Video-Capture-V4l-0.902/RTjpeg/codec/modules/0000755000000000000000000000000011042166057017256 5ustar rootrootVideo-Capture-V4l-0.902/RTjpeg/codec/modules/RTmain.ct0000644000000000000000000000223407057751631021012 0ustar rootrootu8 RTjpeg_alldata[2*64+4*64+4*64+4*64+4*64+32]; s16 *RTjpeg_block; s32 *RTjpeg_lqt; s32 *RTjpeg_cqt; u32 *RTjpeg_liqt; u32 *RTjpeg_ciqt; unsigned char RTjpeg_lb8; unsigned char RTjpeg_cb8; int RTjpeg_width, RTjpeg_height; s16 *RTjpeg_old=NULL; #ifdef MMX mmx_t RTjpeg_lmask; mmx_t RTjpeg_cmask; #else u16 RTjpeg_lmask; u16 RTjpeg_cmask; #endif int RTjpeg_mtest=0; static const unsigned char RTjpeg_lum_quant_tbl[64] = { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99 }; static const unsigned char RTjpeg_chrom_quant_tbl[64] = { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }; Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTb2s.ct0000644000000000000000000000044307057751631020554 0ustar rootrootstatic const unsigned char RTjpeg_ZZ[64]={ 0, 8, 1, 2, 9, 16, 24, 17, 10, 3, 4, 11, 18, 25, 32, 40, 33, 26, 19, 12, 5, 6, 13, 20, 27, 34, 41, 48, 56, 49, 42, 35, 28, 21, 14, 7, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63 }; Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTdct_aan.ct0000644000000000000000000000201207057751631021451 0ustar rootrootstatic const u64 RTjpeg_aan_tab[64]={ 4294967296ULL, 5957222912ULL, 5611718144ULL, 5050464768ULL, 4294967296ULL, 3374581504ULL, 2324432128ULL, 1184891264ULL, 5957222912ULL, 8263040512ULL, 7783580160ULL, 7005009920ULL, 5957222912ULL, 4680582144ULL, 3224107520ULL, 1643641088ULL, 5611718144ULL, 7783580160ULL, 7331904512ULL, 6598688768ULL, 5611718144ULL, 4408998912ULL, 3036936960ULL, 1548224000ULL, 5050464768ULL, 7005009920ULL, 6598688768ULL, 5938608128ULL, 5050464768ULL, 3968072960ULL, 2733115392ULL, 1393296000ULL, 4294967296ULL, 5957222912ULL, 5611718144ULL, 5050464768ULL, 4294967296ULL, 3374581504ULL, 2324432128ULL, 1184891264ULL, 3374581504ULL, 4680582144ULL, 4408998912ULL, 3968072960ULL, 3374581504ULL, 2651326208ULL, 1826357504ULL, 931136000ULL, 2324432128ULL, 3224107520ULL, 3036936960ULL, 2733115392ULL, 2324432128ULL, 1826357504ULL, 1258030336ULL, 641204288ULL, 1184891264ULL, 1643641088ULL, 1548224000ULL, 1393296000ULL, 1184891264ULL, 931136000ULL, 641204288ULL, 326894240ULL, }; static s32 RTjpeg_ws[64+31]; Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTb2s_raw.ct0000644000000000000000000000044307057751631021425 0ustar rootrootstatic const unsigned char RTjpeg_ZZ[64]={ 0, 8, 1, 2, 9, 16, 24, 17, 10, 3, 4, 11, 18, 25, 32, 40, 33, 26, 19, 12, 5, 6, 13, 20, 27, 34, 41, 48, 56, 49, 42, 35, 28, 21, 14, 7, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63 }; Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTb2s.c0000644000000000000000000000141611042165752020361 0ustar rootrootint RTjpeg_b2s(s16 *data, s8 *strm, u8 bt8) { int ci=1, co=1, tmp; strm[0]=(u8)(data[RTjpeg_ZZ[0]]>254) ? 254:((data[RTjpeg_ZZ[0]]<0)?0:data[RTjpeg_ZZ[0]]); for(ci=1; ci<=bt8; ci++) if(data[RTjpeg_ZZ[ci]]>0) { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]>127)?127:data[RTjpeg_ZZ[ci]]; } else { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]<-128)?-128:data[RTjpeg_ZZ[ci]]; } for(; ci<64; ci++) if(data[RTjpeg_ZZ[ci]]>0) { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]>63)?63:data[RTjpeg_ZZ[ci]]; } else if(data[RTjpeg_ZZ[ci]]<0) { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]<-64)?-64:data[RTjpeg_ZZ[ci]]; } else /* compress zeros */ { tmp=ci; do { ci++; } while((ci<64)&&(data[RTjpeg_ZZ[ci]]==0)); strm[co++]=(s8)(63+(ci-tmp)); ci--; } return (int)co; } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTs2b.c0000644000000000000000000000070007057751631020364 0ustar rootrootint RTjpeg_s2b(s16 *data, s8 *strm, u8 bt8, u32 *qtbl) { int ci=1, co=1, tmp; register int i; i=RTjpeg_ZZ[0]; data[i]=((u8)strm[0])*qtbl[i]; for(co=1; co<=bt8; co++) { i=RTjpeg_ZZ[co]; data[i]=strm[ci++]*qtbl[i]; } for(; co<64; co++) { if(strm[ci]>63) { tmp=co+strm[ci]-63; for(; co #include #include #include #ifdef MMX #include #endif Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTcolor_grey.c0000644000000000000000000000244207057751631022047 0ustar rootrootvoid RTjpeg_color_init(void) { } #define KcrR 76284 #define KcrG 53281 #define KcbG 25625 #define KcbB 132252 #define Ky 76284 void RTjpeg_yuvrgb(u8 *buf, u8 *rgb) { int i; u8 *bufy, *bufout; bufy=&buf[0]; bufout=rgb; for(i=0; i> 3); tmp|=(int)(((int)*bufy >> 2) << 5); tmp|=(int)(((int)*(bufy++) >> 3) << 11); *(bufout++)=tmp&0xff;; *(bufout++)=tmp>>8; } } void RTjpeg_yuvrgb8(u8 *buf, u8 *rgb) { int i; u8 *bufy, *bufout; bufy=&buf[0]; bufout=rgb; for(i=0; i> 5; dptr = dptr << 5; /* cache align data */ RTjpeg_block = (s16 *) dptr; dptr += sizeof (s16) * 64; RTjpeg_lqt = (s32 *) dptr; dptr += sizeof (s32) * 64; RTjpeg_cqt = (s32 *) dptr; dptr += sizeof (s32) * 64; RTjpeg_liqt = (u32 *) dptr; dptr += sizeof (u32) * 64; RTjpeg_ciqt = (u32 *) dptr; } /* External Function Re-set quality factor Input: buf -> pointer to 128 ints for quant values store to pass back to init_decompress. Q -> quality factor (192=best, 32=worst) */ void RTjpeg_init_Q (u8 Q) { int i; u64 qual; qual = (u64) Q << (32 - 7); /* 32 bit FP, 255=2, 0=0 */ for (i = 0; i < 64; i++) { RTjpeg_lqt[i] = (s32) ((qual / ((u64) RTjpeg_lum_quant_tbl[i] << 16)) >> 3); if (RTjpeg_lqt[i] == 0) RTjpeg_lqt[i] = 1; RTjpeg_cqt[i] = (s32) ((qual / ((u64) RTjpeg_chrom_quant_tbl[i] << 16)) >> 3); if (RTjpeg_cqt[i] == 0) RTjpeg_cqt[i] = 1; RTjpeg_liqt[i] = (1 << 16) / (RTjpeg_lqt[i] << 3); RTjpeg_ciqt[i] = (1 << 16) / (RTjpeg_cqt[i] << 3); RTjpeg_lqt[i] = ((1 << 16) / RTjpeg_liqt[i]) >> 3; RTjpeg_cqt[i] = ((1 << 16) / RTjpeg_ciqt[i]) >> 3; } RTjpeg_lb8 = 0; while (RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]] <= 8); RTjpeg_lb8--; RTjpeg_cb8 = 0; while (RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]] <= 8); RTjpeg_cb8--; RTjpeg_dct_init (); RTjpeg_idct_init (); RTjpeg_quant_init (); } /* External Function Initialise compression. Input: buf -> pointer to 128 ints for quant values store to pass back to init_decompress. width -> width of image height -> height of image Q -> quality factor (192=best, 32=worst) */ void RTjpeg_init_compress (u32 * buf, int width, int height, u8 Q) { int i; u64 qual; RTjpeg_init_data (); RTjpeg_width = width; RTjpeg_height = height; qual = (u64) Q << (32 - 7); /* 32 bit FP, 255=2, 0=0 */ for (i = 0; i < 64; i++) { RTjpeg_lqt[i] = (s32) ((qual / ((u64) RTjpeg_lum_quant_tbl[i] << 16)) >> 3); if (RTjpeg_lqt[i] == 0) RTjpeg_lqt[i] = 1; RTjpeg_cqt[i] = (s32) ((qual / ((u64) RTjpeg_chrom_quant_tbl[i] << 16)) >> 3); if (RTjpeg_cqt[i] == 0) RTjpeg_cqt[i] = 1; RTjpeg_liqt[i] = (1 << 16) / (RTjpeg_lqt[i] << 3); RTjpeg_ciqt[i] = (1 << 16) / (RTjpeg_cqt[i] << 3); RTjpeg_lqt[i] = ((1 << 16) / RTjpeg_liqt[i]) >> 3; RTjpeg_cqt[i] = ((1 << 16) / RTjpeg_ciqt[i]) >> 3; } RTjpeg_lb8 = 0; while (RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]] <= 8); RTjpeg_lb8--; RTjpeg_cb8 = 0; while (RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]] <= 8); RTjpeg_cb8--; RTjpeg_dct_init (); RTjpeg_quant_init (); for (i = 0; i < 64; i++) buf[i] = RTjpeg_liqt[i]; for (i = 0; i < 64; i++) buf[64 + i] = RTjpeg_ciqt[i]; } void RTjpeg_init_decompress (u32 * buf, int width, int height) { int i; RTjpeg_init_data (); RTjpeg_width = width; RTjpeg_height = height; for (i = 0; i < 64; i++) { RTjpeg_liqt[i] = buf[i]; RTjpeg_ciqt[i] = buf[i + 64]; } RTjpeg_lb8 = 0; while (RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]] <= 8); RTjpeg_lb8--; RTjpeg_cb8 = 0; while (RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]] <= 8); RTjpeg_cb8--; RTjpeg_idct_init (); RTjpeg_color_init (); } int RTjpeg_compress (s8 * sp, unsigned char *bp) { s8 *sb; int i, j; #ifdef MMX emms (); #endif sb = sp; /* Y */ for (i = 0; i < RTjpeg_height; i += 8) { for (j = 0; j < RTjpeg_width; j += 8) { RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width); RTjpeg_quant (RTjpeg_block, RTjpeg_lqt); sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_lb8); } bp += RTjpeg_width << 3; } /* Cr */ for (i = 0; i < (RTjpeg_height >> 1); i += 8) { for (j = 0; j < (RTjpeg_width >> 1); j += 8) { RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1); RTjpeg_quant (RTjpeg_block, RTjpeg_cqt); sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8); } bp += RTjpeg_width << 2; } /* Cb */ for (i = 0; i < (RTjpeg_height >> 1); i += 8) { for (j = 0; j < (RTjpeg_width >> 1); j += 8) { RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1); RTjpeg_quant (RTjpeg_block, RTjpeg_cqt); sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8); } bp += RTjpeg_width << 2; } #ifdef MMX emms (); #endif return (sp - sb); } void RTjpeg_decompress (s8 * sp, u8 * bp) { int i, j; #ifdef MMX emms (); #endif /* Y */ for (i = 0; i < RTjpeg_height; i += 8) { for (j = 0; j < RTjpeg_width; j += 8) if (*sp == -1) sp++; else { sp += RTjpeg_s2b (RTjpeg_block, sp, RTjpeg_lb8, RTjpeg_liqt); RTjpeg_idct (bp + j, RTjpeg_block, RTjpeg_width); } bp += RTjpeg_width << 3; } /* Cr */ for (i = 0; i < (RTjpeg_height >> 1); i += 8) { for (j = 0; j < (RTjpeg_width >> 1); j += 8) if (*sp == -1) sp++; else { sp += RTjpeg_s2b (RTjpeg_block, sp, RTjpeg_cb8, RTjpeg_ciqt); RTjpeg_idct (bp + j, RTjpeg_block, RTjpeg_width >> 1); } bp += RTjpeg_width << 2; } /* Cb */ for (i = 0; i < (RTjpeg_height >> 1); i += 8) { for (j = 0; j < (RTjpeg_width >> 1); j += 8) if (*sp == -1) sp++; else { sp += RTjpeg_s2b (RTjpeg_block, sp, RTjpeg_cb8, RTjpeg_ciqt); RTjpeg_idct (bp + j, RTjpeg_block, RTjpeg_width >> 1); } bp += RTjpeg_width << 2; } #ifdef MMX emms (); #endif } /* External Function Initialise additional data structures for motion compensation */ void RTjpeg_init_mcompress (void) { unsigned long tmp; if (!RTjpeg_old) { RTjpeg_old = malloc (((RTjpeg_width * RTjpeg_height) << 1) + (RTjpeg_width * RTjpeg_height) + 32); tmp = (unsigned long) RTjpeg_old; tmp += 32; tmp = tmp >> 5; RTjpeg_old = (s16 *) (tmp << 5); } if (!RTjpeg_old) { fprintf (stderr, "RTjpeg: Could not allocate memory\n"); exit (-1); } bzero (RTjpeg_old, ((RTjpeg_width * RTjpeg_height) + ((RTjpeg_width * RTjpeg_height) >> 1)) << 1); } #ifdef MMX int RTjpeg_bcomp (s16 * old, mmx_t * mask) { int i; mmx_t *mold = (mmx_t *) old; mmx_t *mblock = (mmx_t *) RTjpeg_block; mmx_t result; static mmx_t neg = (mmx_t) (unsigned long long) 0xffffffffffffffffULL; movq_m2r (*mask, mm7); movq_m2r (neg, mm6); pxor_r2r (mm5, mm5); for (i = 0; i < 8; i++) { movq_m2r (*(mblock++), mm0); movq_m2r (*(mblock++), mm2); movq_m2r (*(mold++), mm1); movq_m2r (*(mold++), mm3); psubsw_r2r (mm1, mm0); psubsw_r2r (mm3, mm2); movq_r2r (mm0, mm1); movq_r2r (mm2, mm3); pcmpgtw_r2r (mm7, mm0); pcmpgtw_r2r (mm7, mm2); pxor_r2r (mm6, mm1); pxor_r2r (mm6, mm3); pcmpgtw_r2r (mm7, mm1); pcmpgtw_r2r (mm7, mm3); por_r2r (mm0, mm5); por_r2r (mm2, mm5); por_r2r (mm1, mm5); por_r2r (mm3, mm5); } movq_r2m (mm5, result); if (result.q) { if (!RTjpeg_mtest) for (i = 0; i < 16; i++) ((u64 *) old)[i] = ((u64 *) RTjpeg_block)[i]; return 0; } // printf("."); return 1; } #else int RTjpeg_bcomp (s16 * old, u16 * mask) { int i; for (i = 0; i < 64; i++) if (abs (old[i] - RTjpeg_block[i]) > *mask) { if (!RTjpeg_mtest) for (i = 0; i < 16; i++) ((u64 *) old)[i] = ((u64 *) RTjpeg_block)[i]; return 0; } return 1; } #endif void RTjpeg_set_test (int i) { RTjpeg_mtest = i; } int RTjpeg_mcompress (s8 * sp, unsigned char *bp, u16 lmask, u16 cmask, int x, int y, int w, int h) { s8 *sb; s16 *block; int i, j; #ifdef MMX emms (); RTjpeg_lmask = (mmx_t) (((u64) lmask << 48) | ((u64) lmask << 32) | ((u64) lmask << 16) | lmask); RTjpeg_cmask = (mmx_t) (((u64) cmask << 48) | ((u64) cmask << 32) | ((u64) cmask << 16) | cmask); #else RTjpeg_lmask = lmask; RTjpeg_cmask = cmask; #endif w += x; h += y; sb = sp; block = RTjpeg_old; /* Y */ for (i = 0; i < RTjpeg_height; i += 8) { if (i >= y && i < h) { for (j = x; j < w; j += 8) { RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width); RTjpeg_quant (RTjpeg_block, RTjpeg_lqt); if (RTjpeg_bcomp (block, &RTjpeg_lmask)) *((u8 *) sp++) = 255; else sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_lb8); block += 64; } } bp += RTjpeg_width << 3; } y >>= 1; h >>= 1; /* Cr */ for (i = 0; i < (RTjpeg_height >> 1); i += 8) { if (i >= y && i < h) { for (j = x >> 1; j < (w >> 1); j += 8) { RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1); RTjpeg_quant (RTjpeg_block, RTjpeg_cqt); if (RTjpeg_bcomp (block, &RTjpeg_cmask)) *((u8 *) sp++) = 255; else sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8); block += 64; } } bp += RTjpeg_width << 2; } /* Cb */ for (i = 0; i < (RTjpeg_height >> 1); i += 8) { if (i >= y && i < h) { for (j = x >> 1; j < (w >> 1); j += 8) { RTjpeg_dct (bp + j, RTjpeg_block, RTjpeg_width >> 1); RTjpeg_quant (RTjpeg_block, RTjpeg_cqt); if (RTjpeg_bcomp (block, &RTjpeg_cmask)) *((u8 *) sp++) = 255; else sp += RTjpeg_b2s (RTjpeg_block, sp, RTjpeg_cb8); block += 64; } } bp += RTjpeg_width << 2; } #ifdef MMX emms (); #endif return (sp - sb); } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTdct_aan.c0000644000000000000000000000674207057751631021303 0ustar rootroot#define FIX_0_382683433 ((s32) 98) /* FIX(0.382683433) */ #define FIX_0_541196100 ((s32) 139) /* FIX(0.541196100) */ #define FIX_0_707106781 ((s32) 181) /* FIX(0.707106781) */ #define FIX_1_306562965 ((s32) 334) /* FIX(1.306562965) */ #define DESCALE10(x) (s16)( ((x)+128) >> 8) #define DESCALE20(x) (s16)(((x)+32768) >> 16) #define D_MULTIPLY(var,const) ((s32) ((var) * (const))) void RTjpeg_dct_init(void) { int i; for(i=0; i<64; i++) { RTjpeg_lqt[i]=(((u64)RTjpeg_lqt[i]<<32)/RTjpeg_aan_tab[i]); RTjpeg_cqt[i]=(((u64)RTjpeg_cqt[i]<<32)/RTjpeg_aan_tab[i]); } } void RTjpeg_dct (u8 *idata, s16 *odata, int rskip) { s32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; s32 tmp10, tmp11, tmp12, tmp13; s32 z1, z2, z3, z4, z5, z11, z13; u8 *idataptr; s16 *odataptr; s32 *wsptr; int ctr; idataptr = idata; wsptr = RTjpeg_ws; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = idataptr[0] + idataptr[7]; tmp7 = idataptr[0] - idataptr[7]; tmp1 = idataptr[1] + idataptr[6]; tmp6 = idataptr[1] - idataptr[6]; tmp2 = idataptr[2] + idataptr[5]; tmp5 = idataptr[2] - idataptr[5]; tmp3 = idataptr[3] + idataptr[4]; tmp4 = idataptr[3] - idataptr[4]; tmp10 = (tmp0 + tmp3); /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = (tmp1 + tmp2); tmp12 = tmp1 - tmp2; wsptr[0] = (tmp10 + tmp11)<<8; /* phase 3 */ wsptr[4] = (tmp10 - tmp11)<<8; z1 = D_MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ wsptr[2] = (tmp13<<8) + z1; /* phase 5 */ wsptr[6] = (tmp13<<8) - z1; tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; z5 = D_MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ z2 = D_MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ z4 = D_MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ z3 = D_MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ z11 = (tmp7<<8) + z3; /* phase 5 */ z13 = (tmp7<<8) - z3; wsptr[5] = z13 + z2; /* phase 6 */ wsptr[3] = z13 - z2; wsptr[1] = z11 + z4; wsptr[7] = z11 - z4; idataptr += rskip; /* advance pointer to next row */ wsptr += 8; } wsptr = RTjpeg_ws; odataptr=odata; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = wsptr[0] + wsptr[56]; tmp7 = wsptr[0] - wsptr[56]; tmp1 = wsptr[8] + wsptr[48]; tmp6 = wsptr[8] - wsptr[48]; tmp2 = wsptr[16] + wsptr[40]; tmp5 = wsptr[16] - wsptr[40]; tmp3 = wsptr[24] + wsptr[32]; tmp4 = wsptr[24] - wsptr[32]; tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; odataptr[0] = DESCALE10(tmp10 + tmp11); /* phase 3 */ odataptr[32] = DESCALE10(tmp10 - tmp11); z1 = D_MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ odataptr[16] = DESCALE20((tmp13<<8) + z1); /* phase 5 */ odataptr[48] = DESCALE20((tmp13<<8) - z1); tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; z5 = D_MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ z2 = D_MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ z4 = D_MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ z3 = D_MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ z11 = (tmp7<<8) + z3; /* phase 5 */ z13 = (tmp7<<8) - z3; odataptr[40] = DESCALE20(z13 + z2); /* phase 6 */ odataptr[24] = DESCALE20(z13 - z2); odataptr[8] = DESCALE20(z11 + z4); odataptr[56] = DESCALE20(z11 - z4); odataptr++; /* advance pointer to next column */ wsptr++; } } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTdct_std.c0000644000000000000000000001126207057751631021327 0ustar rootroot#define FIX_0_298631336 ((s32) 2446) /* FIX(0.298631336) */ #define FIX_0_390180644 ((s32) 3196) /* FIX(0.390180644) */ #define FIX_0_541196100 ((s32) 4433) /* FIX(0.541196100) */ #define FIX_0_765366865 ((s32) 6270) /* FIX(0.765366865) */ #define FIX_0_899976223 ((s32) 7373) /* FIX(0.899976223) */ #define FIX_1_175875602 ((s32) 9633) /* FIX(1.175875602) */ #define FIX_1_501321110 ((s32) 12299) /* FIX(1.501321110) */ #define FIX_1_847759065 ((s32) 15137) /* FIX(1.847759065) */ #define FIX_1_961570560 ((s32) 16069) /* FIX(1.961570560) */ #define FIX_2_053119869 ((s32) 16819) /* FIX(2.053119869) */ #define FIX_2_562915447 ((s32) 20995) /* FIX(2.562915447) */ #define FIX_3_072711026 ((s32) 25172) /* FIX(3.072711026) */ #define MULTIPLY(var,const) ( (s32) ((var)*(const)) ) #define DESCALE(x,n) ((x)>>(n)) void RTjpeg_dct_init(void) { } void RTjpeg_dct(u8 *idata, s16 *odata, int rskip) { s32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; s32 tmp10, tmp11, tmp12, tmp13; s32 z1, z2, z3, z4, z5; u8 *idataptr; s16 * odataptr; int ctr; idataptr = idata; odataptr = odata; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = idataptr[0] + idataptr[7]; tmp7 = idataptr[0] - idataptr[7]; tmp1 = idataptr[1] + idataptr[6]; tmp6 = idataptr[1] - idataptr[6]; tmp2 = idataptr[2] + idataptr[5]; tmp5 = idataptr[2] - idataptr[5]; tmp3 = idataptr[3] + idataptr[4]; tmp4 = idataptr[3] - idataptr[4]; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; odataptr[0] = (s32) ((tmp10 + tmp11) << 2); odataptr[4] = (s32) ((tmp10 - tmp11) << 2); z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); odataptr[2] = (s32) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), 11); odataptr[6] = (s32) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), 11); z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; odataptr[7] = (s32) DESCALE(tmp4 + z1 + z3, 11); odataptr[5] = (s32) DESCALE(tmp5 + z2 + z4, 11); odataptr[3] = (s32) DESCALE(tmp6 + z2 + z3, 11); odataptr[1] = (s32) DESCALE(tmp7 + z1 + z4, 11); odataptr += 8; /* advance pointer to next row */ idataptr += rskip; } odataptr = odata; for (ctr = 7; ctr >= 0; ctr--) { tmp0 = odataptr[0] + odataptr[56]; tmp7 = odataptr[0] - odataptr[56]; tmp1 = odataptr[8] + odataptr[48]; tmp6 = odataptr[8] - odataptr[48]; tmp2 = odataptr[16] + odataptr[40]; tmp5 = odataptr[16] - odataptr[40]; tmp3 = odataptr[24] + odataptr[32]; tmp4 = odataptr[24] - odataptr[32]; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; odataptr[0] = (s32) DESCALE(tmp10 + tmp11, 2); odataptr[32] = (s32) DESCALE(tmp10 - tmp11, 2); z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); odataptr[16] = (s32) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), 15); odataptr[48] = (s32) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), 15); z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; odataptr[56] = (s32) DESCALE(tmp4 + z1 + z3, 15); odataptr[40] = (s32) DESCALE(tmp5 + z2 + z4, 15); odataptr[24] = (s32) DESCALE(tmp6 + z2 + z3, 15); odataptr[8] = (s32) DESCALE(tmp7 + z1 + z4, 15); odataptr++; /* advance pointer to next column */ } } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTb2s_raw.c0000644000000000000000000000140207057751631021235 0ustar rootrootint RTjpeg_b2s(s16 *data, s8 *strm, u8 bt8) { int ci=1, co=1, tmp; (u8)strm[0]=(u8)(data[RTjpeg_ZZ[0]]>254) ? 254:((data[RTjpeg_ZZ[0]]<0)?0:data[RTjpeg_ZZ[0]]); for(ci=1; ci<=63; ci++) if(data[RTjpeg_ZZ[ci]]>0) { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]>127)?127:data[RTjpeg_ZZ[ci]]; } else { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]<-128)?-128:data[RTjpeg_ZZ[ci]]; } /* for(; ci<64; ci++) if(data[RTjpeg_ZZ[ci]]>0) { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]>63)?63:data[RTjpeg_ZZ[ci]]; } else if(data[RTjpeg_ZZ[ci]]<0) { strm[co++]=(s8)(data[RTjpeg_ZZ[ci]]<-64)?-64:data[RTjpeg_ZZ[ci]]; } else { tmp=ci; do { ci++; } while((ci<64)&&(data[RTjpeg_ZZ[ci]]==0)); strm[co++]=(s8)(63+(ci-tmp)); ci--; } */ return (int)co; } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTcolor_int.c0000644000000000000000000002017607057751631021677 0ustar rootrootvoid RTjpeg_color_init(void) { } #define KcrR 76284 #define KcrG 53281 #define KcbG 25625 #define KcbB 132252 #define Ky 76284 void RTjpeg_yuvrgb(u8 *buf, u8 *rgb) { int tmp; int i, j; s32 y, crR, crG, cbG, cbB; u8 *bufcr, *bufcb, *bufy, *bufoute, *bufouto; int oskip, yskip; oskip=RTjpeg_width*3; yskip=RTjpeg_width; bufcb=&buf[RTjpeg_width*RTjpeg_height]; bufcr=&buf[RTjpeg_width*RTjpeg_height+(RTjpeg_width*RTjpeg_height)/4]; bufy=&buf[0]; bufoute=rgb; bufouto=rgb+oskip; for(i=0; i<(RTjpeg_height>>1); i++) { for(j=0; j>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+cbB)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); y=(bufy[j+1]-16)*Ky; tmp=(y+crR)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+cbB)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); y=(bufy[j+yskip]-16)*Ky; tmp=(y+crR)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+cbB)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); y=(bufy[j+1+yskip]-16)*Ky; tmp=(y+crR)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+cbB)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); } bufoute+=oskip; bufouto+=oskip; bufy+=yskip<<1; } } void RTjpeg_yuvrgb32(u8 *buf, u8 *rgb) { int tmp; int i, j; s32 y, crR, crG, cbG, cbB; u8 *bufcr, *bufcb, *bufy, *bufoute, *bufouto; int oskip, yskip; oskip=RTjpeg_width*4; yskip=RTjpeg_width; bufcb=&buf[RTjpeg_width*RTjpeg_height]; bufcr=&buf[RTjpeg_width*RTjpeg_height+(RTjpeg_width*RTjpeg_height)/4]; bufy=&buf[0]; bufoute=rgb; bufouto=rgb+oskip; for(i=0; i<(RTjpeg_height>>1); i++) { for(j=0; j>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); bufoute++; y=(bufy[j+1]-16)*Ky; tmp=(y+cbB)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); bufoute++; y=(bufy[j+yskip]-16)*Ky; tmp=(y+cbB)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); bufouto++; y=(bufy[j+1+yskip]-16)*Ky; tmp=(y+cbB)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); bufouto++; } bufoute+=oskip; bufouto+=oskip; bufy+=yskip<<1; } } void RTjpeg_yuvrgb24(u8 *buf, u8 *rgb) { int tmp; int i, j; s32 y, crR, crG, cbG, cbB; u8 *bufcr, *bufcb, *bufy, *bufoute, *bufouto; int oskip, yskip; oskip=RTjpeg_width*3; yskip=RTjpeg_width; bufcb=&buf[RTjpeg_width*RTjpeg_height]; bufcr=&buf[RTjpeg_width*RTjpeg_height+(RTjpeg_width*RTjpeg_height)/4]; bufy=&buf[0]; bufoute=rgb; bufouto=rgb+oskip; for(i=0; i<(RTjpeg_height>>1); i++) { for(j=0; j>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); y=(bufy[j+1]-16)*Ky; tmp=(y+cbB)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufoute++)=(tmp>255)?255:((tmp<0)?0:tmp); y=(bufy[j+yskip]-16)*Ky; tmp=(y+cbB)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); y=(bufy[j+1+yskip]-16)*Ky; tmp=(y+cbB)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; *(bufouto++)=(tmp>255)?255:((tmp<0)?0:tmp); } bufoute+=oskip; bufouto+=oskip; bufy+=yskip<<1; } } void RTjpeg_yuvrgb16(u8 *buf, u8 *rgb) { int tmp; int i, j; s32 y, crR, crG, cbG, cbB; u8 *bufcr, *bufcb, *bufy, *bufoute, *bufouto; int oskip, yskip; unsigned char r, g, b; oskip=RTjpeg_width*2; yskip=RTjpeg_width; bufcb=&buf[RTjpeg_width*RTjpeg_height]; bufcr=&buf[RTjpeg_width*RTjpeg_height+(RTjpeg_width*RTjpeg_height)/4]; bufy=&buf[0]; bufoute=rgb; bufouto=rgb+oskip; for(i=0; i<(RTjpeg_height>>1); i++) { for(j=0; j>16; b=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; g=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; r=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(int)((int)b >> 3); tmp|=(int)(((int)g >> 2) << 5); tmp|=(int)(((int)r >> 3) << 11); *(bufoute++)=tmp&0xff; *(bufoute++)=tmp>>8; y=(bufy[j+1]-16)*Ky; tmp=(y+cbB)>>16; b=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; g=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; r=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(int)((int)b >> 3); tmp|=(int)(((int)g >> 2) << 5); tmp|=(int)(((int)r >> 3) << 11); *(bufoute++)=tmp&0xff; *(bufoute++)=tmp>>8; y=(bufy[j+yskip]-16)*Ky; tmp=(y+cbB)>>16; b=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; g=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; r=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(int)((int)b >> 3); tmp|=(int)(((int)g >> 2) << 5); tmp|=(int)(((int)r >> 3) << 11); *(bufouto++)=tmp&0xff; *(bufouto++)=tmp>>8; y=(bufy[j+1+yskip]-16)*Ky; tmp=(y+cbB)>>16; b=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y-crG-cbG)>>16; g=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(y+crR)>>16; r=(tmp>255)?255:((tmp<0)?0:tmp); tmp=(int)((int)b >> 3); tmp|=(int)(((int)g >> 2) << 5); tmp|=(int)(((int)r >> 3) << 11); *(bufouto++)=tmp&0xff; *(bufouto++)=tmp>>8; } bufoute+=oskip; bufouto+=oskip; bufy+=yskip<<1; } } void RTjpeg_yuvrgb8(u8 *buf, u8 *rgb) { bcopy(buf, rgb, RTjpeg_width*RTjpeg_height); } void RTjpeg_double32(u32 *buf) { int i, j; u32 *iptr, *optr1, *optr2; iptr=buf+(RTjpeg_width*RTjpeg_height)-1; optr1=buf+(RTjpeg_width*RTjpeg_height*4)-1; optr2=optr1-(2*RTjpeg_width); for(i=0; i> 3) /* clip yuv to 16..235 (should be 16..240 for cr/cb but ... */ #define RL(x) ((x)>235) ? 235 : (((x)<16) ? 16 : (x)) #define MULTIPLY(var,const) (((s32) ((var) * (const)) + 128)>>8) void RTjpeg_idct_init(void) { int i; for(i=0; i<64; i++) { RTjpeg_liqt[i]=((u64)RTjpeg_liqt[i]*RTjpeg_aan_tab[i])>>32; RTjpeg_ciqt[i]=((u64)RTjpeg_ciqt[i]*RTjpeg_aan_tab[i])>>32; } } void RTjpeg_idct(u8 *odata, s16 *data, int rskip) { s32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; s32 tmp10, tmp11, tmp12, tmp13; s32 z5, z10, z11, z12, z13; s16 *inptr; s32 *wsptr; u8 *outptr; int ctr; s32 dcval; s32 workspace[64]; inptr = data; wsptr = workspace; for (ctr = 8; ctr > 0; ctr--) { if ((inptr[8] | inptr[16] | inptr[24] | inptr[32] | inptr[40] | inptr[48] | inptr[56]) == 0) { dcval = inptr[0]; wsptr[0] = dcval; wsptr[8] = dcval; wsptr[16] = dcval; wsptr[24] = dcval; wsptr[32] = dcval; wsptr[40] = dcval; wsptr[48] = dcval; wsptr[56] = dcval; inptr++; wsptr++; continue; } tmp0 = inptr[0]; tmp1 = inptr[16]; tmp2 = inptr[32]; tmp3 = inptr[48]; tmp10 = tmp0 + tmp2; tmp11 = tmp0 - tmp2; tmp13 = tmp1 + tmp3; tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; tmp0 = tmp10 + tmp13; tmp3 = tmp10 - tmp13; tmp1 = tmp11 + tmp12; tmp2 = tmp11 - tmp12; tmp4 = inptr[8]; tmp5 = inptr[24]; tmp6 = inptr[40]; tmp7 = inptr[56]; z13 = tmp6 + tmp5; z10 = tmp6 - tmp5; z11 = tmp4 + tmp7; z12 = tmp4 - tmp7; tmp7 = z11 + z13; tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); z5 = MULTIPLY(z10 + z12, FIX_1_847759065); tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; tmp6 = tmp12 - tmp7; tmp5 = tmp11 - tmp6; tmp4 = tmp10 + tmp5; wsptr[0] = (s32) (tmp0 + tmp7); wsptr[56] = (s32) (tmp0 - tmp7); wsptr[8] = (s32) (tmp1 + tmp6); wsptr[48] = (s32) (tmp1 - tmp6); wsptr[16] = (s32) (tmp2 + tmp5); wsptr[40] = (s32) (tmp2 - tmp5); wsptr[32] = (s32) (tmp3 + tmp4); wsptr[24] = (s32) (tmp3 - tmp4); inptr++; wsptr++; } wsptr = workspace; for (ctr = 0; ctr < 8; ctr++) { outptr = &(odata[ctr*rskip]); tmp10 = wsptr[0] + wsptr[4]; tmp11 = wsptr[0] - wsptr[4]; tmp13 = wsptr[2] + wsptr[6]; tmp12 = MULTIPLY(wsptr[2] - wsptr[6], FIX_1_414213562) - tmp13; tmp0 = tmp10 + tmp13; tmp3 = tmp10 - tmp13; tmp1 = tmp11 + tmp12; tmp2 = tmp11 - tmp12; z13 = wsptr[5] + wsptr[3]; z10 = wsptr[5] - wsptr[3]; z11 = wsptr[1] + wsptr[7]; z12 = wsptr[1] - wsptr[7]; tmp7 = z11 + z13; tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); z5 = MULTIPLY(z10 + z12, FIX_1_847759065); tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; tmp6 = tmp12 - tmp7; tmp5 = tmp11 - tmp6; tmp4 = tmp10 + tmp5; outptr[0] = RL(DESCALE(tmp0 + tmp7)); outptr[7] = RL(DESCALE(tmp0 - tmp7)); outptr[1] = RL(DESCALE(tmp1 + tmp6)); outptr[6] = RL(DESCALE(tmp1 - tmp6)); outptr[2] = RL(DESCALE(tmp2 + tmp5)); outptr[5] = RL(DESCALE(tmp2 - tmp5)); outptr[4] = RL(DESCALE(tmp3 + tmp4)); outptr[3] = RL(DESCALE(tmp3 - tmp4)); wsptr += 8; } } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTidct_std.c0000644000000000000000000001206707057751631021504 0ustar rootroot#include #define FIX_0_298631336 ((s32) 2446) /* FIX(0.298631336) */ #define FIX_0_390180644 ((s32) 3196) /* FIX(0.390180644) */ #define FIX_0_541196100 ((s32) 4433) /* FIX(0.541196100) */ #define FIX_0_765366865 ((s32) 6270) /* FIX(0.765366865) */ #define FIX_0_899976223 ((s32) 7373) /* FIX(0.899976223) */ #define FIX_1_175875602 ((s32) 9633) /* FIX(1.175875602) */ #define FIX_1_501321110 ((s32) 12299) /* FIX(1.501321110) */ #define FIX_1_847759065 ((s32) 15137) /* FIX(1.847759065) */ #define FIX_1_961570560 ((s32) 16069) /* FIX(1.961570560) */ #define FIX_2_053119869 ((s32) 16819) /* FIX(2.053119869) */ #define FIX_2_562915447 ((s32) 20995) /* FIX(2.562915447) */ #define FIX_3_072711026 ((s32) 25172) /* FIX(3.072711026) */ #define MULTIPLY(var,const) ( (s32) ((var)*(const)) ) #define DESCALE(x,n) ((x)>>(n)) /* clip yuv to 16..235 (should be 16..240 for cr/cb but ... */ #define RL(x) ((x)>235) ? 235 : (((x)<16) ? 16 : (x)) void RTjpeg_idct_init(void) { } void RTjpeg_idct(u8 *odata, s16 *data, int rskip) { s32 tmp0, tmp1, tmp2, tmp3; s32 tmp10, tmp11, tmp12, tmp13; s32 z1, z2, z3, z4, z5; s16 *inptr; s32 *wsptr; u8 *outptr; int ctr; s32 dcval; s32 workspace[64]; inptr = data; wsptr = workspace; for (ctr = 8; ctr > 0; ctr--) { if ((inptr[8] | inptr[16] | inptr[24] | inptr[32] | inptr[40] | inptr[48] | inptr[56]) == 0) { dcval=inptr[0]<<2; wsptr[0] = dcval; wsptr[8] = dcval; wsptr[16] = dcval; wsptr[24] = dcval; wsptr[32] = dcval; wsptr[40] = dcval; wsptr[48] = dcval; wsptr[56] = dcval; inptr++; wsptr++; continue; } z2 = inptr[16]; z3 = inptr[48]; z1 = MULTIPLY(z2 + z3, FIX_0_541196100); tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); z2 = inptr[0]; z3 = inptr[32]; tmp0 = (z2 + z3) << 13; tmp1 = (z2 - z3) << 13; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; tmp0 = inptr[56]; tmp1 = inptr[40]; tmp2 = inptr[24]; tmp3 = inptr[8]; z1 = tmp0 + tmp3; z2 = tmp1 + tmp2; z3 = tmp0 + tmp2; z4 = tmp1 + tmp3; z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; tmp0 += z1 + z3; tmp1 += z2 + z4; tmp2 += z2 + z3; tmp3 += z1 + z4; wsptr[0] = (int) DESCALE(tmp10 + tmp3, 11); wsptr[56] = (int) DESCALE(tmp10 - tmp3, 11); wsptr[8] = (int) DESCALE(tmp11 + tmp2, 11); wsptr[48] = (int) DESCALE(tmp11 - tmp2, 11); wsptr[16] = (int) DESCALE(tmp12 + tmp1, 11); wsptr[40] = (int) DESCALE(tmp12 - tmp1, 11); wsptr[24] = (int) DESCALE(tmp13 + tmp0, 11); wsptr[32] = (int) DESCALE(tmp13 - tmp0, 11); inptr++; /* advance pointers to next column */ wsptr++; } wsptr = workspace; for (ctr = 0; ctr < 8; ctr++) { outptr=&(odata[ctr*rskip]); z2 = (s32) wsptr[2]; z3 = (s32) wsptr[6]; z1 = MULTIPLY(z2 + z3, FIX_0_541196100); tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065); tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865); tmp0 = ((s32) wsptr[0] + (s32) wsptr[4]) << 13; tmp1 = ((s32) wsptr[0] - (s32) wsptr[4]) << 13; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; tmp0 = (s32) wsptr[7]; tmp1 = (s32) wsptr[5]; tmp2 = (s32) wsptr[3]; tmp3 = (s32) wsptr[1]; z1 = tmp0 + tmp3; z2 = tmp1 + tmp2; z3 = tmp0 + tmp2; z4 = tmp1 + tmp3; z5 = MULTIPLY(z3 + z4, FIX_1_175875602); tmp0 = MULTIPLY(tmp0, FIX_0_298631336); tmp1 = MULTIPLY(tmp1, FIX_2_053119869); tmp2 = MULTIPLY(tmp2, FIX_3_072711026); tmp3 = MULTIPLY(tmp3, FIX_1_501321110); z1 = MULTIPLY(z1, - FIX_0_899976223); z2 = MULTIPLY(z2, - FIX_2_562915447); z3 = MULTIPLY(z3, - FIX_1_961570560); z4 = MULTIPLY(z4, - FIX_0_390180644); z3 += z5; z4 += z5; tmp0 += z1 + z3; tmp1 += z2 + z4; tmp2 += z2 + z3; tmp3 += z1 + z4; outptr[0] = (s32) RL(DESCALE(tmp10 + tmp3, 18)); outptr[7] = (s32) RL(DESCALE(tmp10 - tmp3, 18)); outptr[1] = (s32) RL(DESCALE(tmp11 + tmp2, 18)); outptr[6] = (s32) RL(DESCALE(tmp11 - tmp2, 18)); outptr[2] = (s32) RL(DESCALE(tmp12 + tmp1, 18)); outptr[5] = (s32) RL(DESCALE(tmp12 - tmp1, 18)); outptr[3] = (s32) RL(DESCALE(tmp13 + tmp0, 18)); outptr[4] = (s32) RL(DESCALE(tmp13 - tmp0, 18)); wsptr += 8; } } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTquant.c0000644000000000000000000000023707057751631021033 0ustar rootrootvoid RTjpeg_quant_init(void) { } void RTjpeg_quant(s16 *block, s32 *qtbl) { int i; for(i=0; i<64; i++) block[i]=(s16)((block[i]*qtbl[i]+32767)>>16); } Video-Capture-V4l-0.902/RTjpeg/codec/modules/RTs2b_raw.c0000644000000000000000000000070507057751631021242 0ustar rootrootint RTjpeg_s2b(s16 *data, s8 *strm, u8 bt8, u32 *qtbl) { int ci=1, co=1, tmp; register int i; i=RTjpeg_ZZ[0]; data[i]=((u8)strm[0])*qtbl[i]; for(co=1; co<64; co++) { i=RTjpeg_ZZ[co]; data[i]=strm[ci++]*qtbl[i]; } /* for(; co<64; co++) { if(strm[ci]>63) { tmp=co+strm[ci]-63; for(; co 'Video::RTjpeg', VERSION_FROM => 'RTjpeg.pm', OBJECT => '$(BASEEXT)$(OBJ_EXT) codec/RTjpeg.o', ); sub MY::postamble { < #include #include #include "../gppport.h" #include "codec/RTjpeg.h" static int fwidth, fheight; MODULE = Video::RTjpeg PACKAGE = Video::RTjpeg PREFIX = RTjpeg_ PROTOTYPES: ENABLE SV * RTjpeg_init_compress(width,height,Q) int width int height U8 Q CODE: fwidth = width; fheight = height; RETVAL = newSVpv ("", 0); SvGROW (RETVAL, sizeof (RTjpeg_tables)); SvCUR_set (RETVAL, sizeof (RTjpeg_tables)); RTjpeg_init_compress ((u32 *)SvPV_nolen (RETVAL), width, height, Q); OUTPUT: RETVAL void RTjpeg_init_decompress(tables,width,height) SV * tables int width int height CODE: fwidth = width; fheight = height; RTjpeg_init_decompress ((u32 *)SvPV_nolen (tables), width, height); SV * RTjpeg_compress(YCrCb422_data) SV * YCrCb422_data CODE: RETVAL = newSVpv ("", 0); SvGROW (RETVAL, (fwidth * fheight * 3 + 2) / 2); SvCUR_set (RETVAL, RTjpeg_compress (SvPV_nolen (RETVAL), SvPV_nolen (YCrCb422_data))); OUTPUT: RETVAL SV * RTjpeg_decompress(RTjpeg_data) SV * RTjpeg_data CODE: RETVAL = newSVpv ("", 0); SvGROW (RETVAL, fwidth * fheight * 2); SvCUR_set (RETVAL, fwidth * fheight * 2); RTjpeg_decompress (SvPV_nolen (RTjpeg_data), SvPV_nolen (RETVAL)); OUTPUT: RETVAL void RTjpeg_init_mcompress() SV * RTjpeg_mcompress(YCrCb422_data,lmask,cmask=(lmask)>>1,x=0,y=0,w=fwidth,h=fheight) SV * YCrCb422_data U16 lmask U16 cmask int x int y int w int h CODE: RETVAL = newSVpv ("", 0); SvGROW (RETVAL, (fwidth * fheight * 3 + 2) / 2); SvCUR_set (RETVAL, RTjpeg_mcompress (SvPV_nolen (RETVAL), SvPV_nolen (YCrCb422_data), lmask, cmask, x, y, w, h)); OUTPUT: RETVAL SV * RTjpeg_yuvrgb(yuv_data) SV * yuv_data CODE: RETVAL = newSVpv ("", 0); SvGROW (RETVAL, fwidth * fheight * 3); SvCUR_set (RETVAL, fwidth * fheight * 3); RTjpeg_yuvrgb (SvPV_nolen (yuv_data), SvPV_nolen (RETVAL)); OUTPUT: RETVAL void _exit(retcode=0) int retcode CODE: _exit (retcode); void fdatasync(fd) int fd CODE: #ifdef _POSIX_SYNCHRONIZED_IO fdatasync (fd); #endif BOOT: { HV *stash = gv_stashpvn("Video::RTjpeg", 13, TRUE); //newCONSTSUB(stash,"VBI_VT", newSViv(VBI_VT)); } Video-Capture-V4l-0.902/Changes0000644000000000000000000000600411042166015014623 0ustar rootrootRevision history for Perl extension Video::Capture::V4l. 0.902 Thu Jul 24 22:54:34 CEST 2008 - fix another lvalue-cast isn't lvalue bug in rtjpeg.c 0.901 Tue Jun 6 01:35:18 CEST 2006 - fix lvalue-cast isn't lvalue bug in rtjpeg.c 0.9 Fri Nov 4 22:20:53 CET 2005 - fix RTJpeg compilation flags. - expose decode_vps and decode_vt subfunctions. - fix CNI decoding. - updated VPS_CNI and 8/30 format 1 and format 2 codes, added X/26 codes, from TR-101-231 2005-10, and converted to utf-8. 0.225 Thu Mar 3 18:00:52 CET 2005 - change of contact address. 0.224 Sun Jun 13 18:02:32 CEST 2004 - fix some compile bugs, very very small documentation updates. - Video::Capture::V4l2 might replace this module in the future, details unclear. 0.222 Mon Feb 25 00:23:43 CET 2002 - work around missing cancellation bug in linux by explicitly calling testcancel. 0.221 Thu May 11 18:28:29 CEST 2000 - fixed oh so stupid bug reported by M C Lincoln. 0.22 Thu May 11 03:22:52 CEST 2000 - changed VBI_VT format so that the full data is always returned in slot #3. - updated GPL to version 2. - minor fixes. 0.21 Sun Apr 16 11:13:04 CEST 2000 - moved scripts to the example subdir, fixed a few bugs, writing an article in tpj ;) - added RTjpeg codec module. 0.20 Wed Dec 1 21:21:02 CET 1999 - fixed segfault problems due to non-reentrant malloc on many systems (by pre-allocating lotsamemory of cousre ;). 0.11 Wed Nov 24 18:45:23 CET 1999 - added epgview-simple (hack!), a regularly updated "coming next" screen. - added epgview, which requires Curses and is much nicer. - made it compile with perl-5.005_03. - removed epgview-simple again ;) - fixed "no dot in PATH" problem in V4l. 0.10 Sun Oct 24 21:18:00 CEST 1999 - added Video::XawTV. - backlog(0) now cancels vbi frame grabbing. - added autotune. - the automatic re-centering was causing too many bit errors. 0.08 Sat Sep 4 19:17:42 CEST 1999 - added dumpepg and renamed epg to getepg. - many bugfixes. - added VBI_OTHER (for other types of lines). - improved epg decoder & viewer. - fixed VPS/VT CNI code (damned %%&$& bit reversals). - vastly improved detection reliability. - added %VPS_CNI and %VT_NI tables. - preliminary premiere crypt data capturing. 0.04 Fri Aug 13 00:32:17 CEST 1999 - added more example apps: vbi-info, epg. - vastly improved teletext decoding. 0.03 Wed Aug 4 21:15:28 CEST 1999 - added VBI module and example videotext-decoder. - "cleaned" up file structure, as advised by Nick. - renamed Video::Capture::Frequencies to Video::Frequencies. 0.02 Wed Jul 14 14:21:37 CEST 1999 - added the Video::Capture::Frequencies module. - added finder/indexer sample applications. - the frequency formula was bogus. 0.01 Thu Jul 1 20:32:32 1999 - original version; created by h2xs 1.19 Video-Capture-V4l-0.902/test.pl0000644000000000000000000000020110211640742014636 0ustar rootrootBEGIN { $| = 1; print "1..1\n"; } END {print "not ok 1\n" unless $loaded;} use Video::Capture::V4l; $loaded = 1; print "ok 1\n"; Video-Capture-V4l-0.902/Makefile.PL0000644000000000000000000000065210331721157015311 0ustar rootrootuse ExtUtils::MakeMaker; WriteMakefile( 'dist' => { PREOP => 'pod2text V4l/V4l.pm | tee README > $(DISTVNAME)/README; chmod -R u=rwX,go=rX . ;', COMPRESS => 'gzip -9v', SUFFIX => '.gz', }, 'NAME' => 'Video::Frequencies', DISTNAME => 'Video-Capture-V4l', 'VERSION_FROM' => 'V4l/V4l.pm', linkext => {LINKTYPE => ''}, DIR => ['V4l','VBI','RTjpeg'], ); Video-Capture-V4l-0.902/META.yml0000644000000000000000000000052711042166057014613 0ustar rootroot--- #YAML:1.0 name: Video-Capture-V4l version: 0.902 abstract: ~ license: ~ author: ~ generated_by: ExtUtils::MakeMaker version 6.44 distribution_type: module requires: meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 Video-Capture-V4l-0.902/gppport.h0000644000000000000000000001740010211640742015177 0ustar rootroot #ifndef _G_P_P_PORTABILITY_H_ #define _G_P_P_PORTABILITY_H_ /* Perl/Pollution/Portability Version 1.0007-gimp-2 */ /* Copyright (C) 1999, Kenneth Albanowski. This code may be used and distributed under the same license as any version of Perl. */ /* For the latest version of this code, please retreive the Devel::PPPort module from CPAN, contact the author at , or check with the Perl maintainers. */ /* If you needed to customize this file for your project, please mention your changes, and visible alter the version number. */ /* In order for a Perl extension module to be as portable as possible across differing versions of Perl itself, certain steps need to be taken. Including this header is the first major one, then using dTHR is all the appropriate places and using a PL_ prefix to refer to global Perl variables is the second. */ /* If you use one of a few functions that were not present in earlier versions of Perl, please add a define before the inclusion of ppport.h for a static include, or use the GLOBAL request in a single module to produce a global definition that can be referenced from the other modules. Function: Static define: Extern define: newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL */ /* To verify whether ppport.h is needed for your module, and whether any special defines should be used, ppport.h can be run through Perl to check your source code. Simply say: perl -x ppport.h *.c *.h *.xs foo/any.c [etc] The result will be a list of patches suggesting changes that should at least be acceptable, if not necessarily the most efficient solution, or a fix for all possible problems. It won't catch where dTHR is needed, and doesn't attempt to account for global macro or function definitions, nested includes, typemaps, etc. In order to test for the need of dTHR, please try your module under a recent version of Perl that has threading compiled-in. */ /* #!/usr/bin/perl @ARGV = ("*.xs") if !@ARGV; %badmacros = %funcs = %macros = (); $replace = 0; foreach () { $funcs{$1} = 1 if /Provide:\s+(\S+)/; $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/; $replace = $1 if /Replace:\s+(\d+)/; $badmacros{$2}=$1 if $replace and /^#\s*define\s+([a-zA-Z0-9_]+).*?\s+([a-zA-Z0-9_]+)/; $badmacros{$1}=$2 if /Replace (\S+) with (\S+)/; } foreach $filename (map(glob($_),@ARGV)) { unless (open(IN, "<$filename")) { warn "Unable to read from $file: $!\n"; next; } print "Scanning $filename...\n"; $c = ""; while () { $c .= $_; } close(IN); $need_include = 0; %add_func = (); $changes = 0; $has_include = ($c =~ /#.*include.*ppport/m); foreach $func (keys %funcs) { if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) { if ($c !~ /\b$func\b/m) { print "If $func isn't needed, you don't need to request it.\n" if $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m); } else { print "Uses $func\n"; $need_include = 1; } } else { if ($c =~ /\b$func\b/m) { $add_func{$func} =1 ; print "Uses $func\n"; $need_include = 1; } } } if (not $need_include) { foreach $macro (keys %macros) { if ($c =~ /\b$macro\b/m) { print "Uses $macro\n"; $need_include = 1; } } } foreach $badmacro (keys %badmacros) { if ($c =~ /\b$badmacro\b/m) { $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm); print "Uses $badmacros{$badmacro} (instead of $badmacro)\n"; $need_include = 1; } } if (scalar(keys %add_func) or $need_include != $has_include) { if (!$has_include) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)). "#include \"ppport.h\"\n"; $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m; } elsif (keys %add_func) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)); $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m; } if (!$need_include) { print "Doesn't seem to need ppport.h.\n"; $c =~ s/^.*#.*include.*ppport.*\n//m; } $changes++; } if ($changes) { open(OUT,">/tmp/ppport.h.$$"); print OUT $c; close(OUT); open(DIFF, "diff -u $filename /tmp/ppport.h.$$|"); while () { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; } close(DIFF); unlink("/tmp/ppport.h.$$"); } else { print "Looks OK\n"; } } __DATA__ */ #ifndef PERL_REVISION # ifndef __PATCHLEVEL_H_INCLUDED__ # include "patchlevel.h" # endif # ifndef PERL_REVISION # define PERL_REVISION (5) /* Replace: 1 */ # define PERL_VERSION PATCHLEVEL # define PERL_SUBVERSION SUBVERSION /* Replace PERL_PATCHLEVEL with PERL_VERSION */ /* Replace: 0 */ # endif #endif #define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION) #ifndef ERRSV # define ERRSV perl_get_sv("@",FALSE) #endif #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)) /* Replace: 1 */ # define PL_sv_undef sv_undef # define PL_sv_yes sv_yes # define PL_sv_no sv_no # define PL_na na # define PL_stdingv stdingv # define PL_hints hints # define PL_curcop curcop # define PL_curstash curstash # define PL_copline copline # define PL_Sv Sv # define PL_perl_destruct_level perl_destruct_level /* Replace: 0 */ #endif #ifndef dTHR # ifdef WIN32 # define dTHR extern int Perl___notused # else # define dTHR extern int errno # endif #endif #ifndef boolSV # define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) #endif #ifndef gv_stashpvn # define gv_stashpvn(str,len,flags) gv_stashpv(str,flags) #endif #ifndef newSVpvn # define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0)) #endif #ifndef newRV_inc /* Replace: 1 */ # define newRV_inc(sv) newRV(sv) /* Replace: 0 */ #endif #ifndef newRV_noinc # ifdef __GNUC__ # define newRV_noinc(sv) \ ({ \ SV *nsv = (SV*)newRV(sv); \ SvREFCNT_dec(sv); \ nsv; \ }) # else # if defined(CRIPPLED_CC) || defined(USE_THREADS) static SV * newRV_noinc (SV * sv) { SV *nsv = (SV*)newRV(sv); SvREFCNT_dec(sv); return nsv; } # else # define newRV_noinc(sv) \ ((PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv) # endif # endif #endif /* Provide: newCONSTSUB */ /* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63)) #if defined(NEED_newCONSTSUB) static #else extern void newCONSTSUB _((HV * stash, char * name, SV *sv)); #endif #if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) void newCONSTSUB(stash,name,sv) HV *stash; char *name; SV *sv; { U32 oldhints = PL_hints; HV *old_cop_stash = PL_curcop->cop_stash; HV *old_curstash = PL_curstash; line_t oldline = PL_curcop->cop_line; PL_curcop->cop_line = PL_copline; PL_hints &= ~HINT_BLOCK_SCOPE; if (stash) PL_curstash = PL_curcop->cop_stash = stash; newSUB( #if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22)) /* before 5.003_22 */ start_subparse(), #else # if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22) /* 5.003_22 */ start_subparse(0), # else /* 5.003_23 onwards */ start_subparse(FALSE, 0), # endif #endif newSVOP(OP_CONST, 0, newSVpv(name,0)), newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) ); PL_hints = oldhints; PL_curcop->cop_stash = old_cop_stash; PL_curstash = old_curstash; PL_curcop->cop_line = oldline; } #endif #endif /* newCONSTSUB */ /*GIMP*/ #ifndef SvPV_nolen # define SvPV_nolen(b) SvPV((b),PL_na) #endif #endif /* _G_P_P_PORTABILITY_H_ */ Video-Capture-V4l-0.902/typemap0000644000000000000000000000041210211640742014730 0ustar rootrootTYPEMAP Video::Capture::V4l::Capability STRUCT Video::Capture::V4l::Channel STRUCT Video::Capture::V4l::Audio STRUCT Video::Capture::V4l::Tuner STRUCT Video::Capture::V4l::Picture STRUCT UI T_IV INPUT STRUCT $var = old_struct ($arg, \"$ntype\") Video-Capture-V4l-0.902/examples/0000755000000000000000000000000011042166057015154 5ustar rootrootVideo-Capture-V4l-0.902/examples/vbi0000755000000000000000000000245310211641046015657 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; use Video::Capture::VBI; package Decoder; use Video::Capture::VBI; # derive from videotext-decoder use base 'Video::Capture::VBI::VT'; # just display the page sub enter_page { my($self,$page)=@_; my $sub = $page->{ctrl} & VTX_SUB; #return unless $page->{page}>=0x110 && $page->{page}<=0x134; #return unless $page->{page}==0x150; my $x = join ("", map { $_ ne "" ? "*" : "-" } @{$page->{packet}}); printf "Teletext page %02x / %04x ($x)\n", $page->{page}, $sub; #return unless $page->{page} == 0x1df; # now print the page for ($y=0; $y<25; $y++) { my $x = $page->{packet}[$y]; print $x ? decode_ansi decode_vtpage $x : "","\n"; } } sub enter_packet { my $packet = $_; } package main; $vbi = new Video::Capture::V4l::VBI or die; # the next line is optional (it enables buffering) $vbi->backlog(25); # max. 1 second backlog (~900kB) $inp_fd = fileno STDIN; $vbi_fd = $vbi->fileno; $vt = new Decoder; print "Capturing VBI block. Make sure you have tuned in to a channel!\n"; for(;;) { my $r=""; vec($r,$inp_fd,1)=1; vec($r,$vbi_fd,1)=1; select $r,undef,undef,0.04; $vt->feed(decode_field $vbi->field, VBI_VT) while $vbi->queued; if (vec($r,$inp_fd,1)) { #print "HI\n"; #sleep 5; } } Video-Capture-V4l-0.902/examples/grab0000755000000000000000000000552610211641046016016 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; sub print_capability { my $c=shift; print "Device: "; print "name ",$c->name; print ", type"; for (qw(capture tuner teletext overlay chromakey clipping frameram scales monochrome subcapture)) { print " $_" if eval "\$c->$_"; } print ", channels ",$c->channels; print ", audios ",$c->audios; print ", sizes ",$c->minwidth,"x",$c->minheight,"-",$c->maxwidth,"x",$c->maxheight; print "\n"; } sub print_channel { my $c=shift; print "Channel ",$c->channel,": "; print "name ",$c->name; print ", tuners ",$c->tuners; print ", flags"; for (qw(tuner audio)) { print " $_" if eval "\$c->$_"; } print ", type"; for (qw(tv camera)) { print " $_" if eval "\$c->$_"; } # PAL, NTSC, SECAM, PAL-NC, PAL-M, PAL-N, NTSC-Japan print ", norm ",$c->norm; print "\n"; } sub print_tuner { my $c=shift; print "Tuner ",$c->tuner,": "; print "name ",$c->name; print ", range ",$c->rangelow,"-",$c->rangehigh; print ", flags"; for (qw(pal ntsc secam low norm stereo_on rds_on mbs_on)) { print " $_" if eval "\$c->$_"; } print ", mode ",$c->mode; print ", signal ",$c->signal; print "\n"; } sub print_audio { my $c=shift; print "Audio Channel ",$c->audio,": "; print "volume ",$c->volume; print ", bass ",$c->bass; print ", treble ",$c->treble; print ", flags"; for (qw(mute mutable volume bass treble)) { print " $_" if eval "\$c->$_"; } print ", name ",$c->name; print ", mode ",$c->mode; print ", balance ",$c->balance; print ", step ",$c->step; print "\n"; } sub print_picture { my $c=shift; print "Picture Settings: "; print "brightness ",$c->brightness; print ", hue ",$c->hue; print ", colour ",$c->colour; print ", contrast ",$c->contrast; print ", whiteness ",$c->whiteness; print ", depth ",$c->depth; print ", palette ",$c->palette; print "\n"; } $grab = new Video::Capture::V4l or die "Unable to open Videodevice: $!"; print_capability $grab->capability; for (0..$grab->capability->channels-1) { print_channel $grab->channel($_); } for($_=0; my $tuner = $grab->tuner($_); $_++) { last if $tuner->tuner != $_; print_tuner $tuner; } for($_=0; my $audio = $grab->audio($_); $_++) { last if $audio->audio != $_; print_audio $audio; } print_picture $grab->picture; my $channel = $grab->channel (0); my $tuner = $grab->tuner (0); $tuner->mode(TUNER_PAL); $channel->norm(MODE_PAL); $tuner->set; $channel->set; $RTL2 = 154250; $RTL2 = 196250; print $grab->freq ($RTL2),"\n"; $|=1; my $frame=0; my $fr=$grab->capture ($frame, 640, 480); for(;;) { my $nfr = $grab->capture (1-$frame, 640, 480); $grab->sync($frame) or die "unable to sync"; # save $fr now, as it contains the raw BGR data print "."; $frame = 1-$frame; $fr = $nfr; } Video-Capture-V4l-0.902/examples/linux-dsp-ioctl.ph0000644000000000000000000000574210211641046020541 0ustar rootrootsub SNDCTL_DSP_GETOSPACE (){0x8010500c} sub SNDCTL_DSP_GETISPACE (){0x8010500d} sub SNDCTL_DSP_NONBLOCK (){0x0000500e} sub SNDCTL_DSP_GETCAPS (){0x8004500f} sub DSP_CAP_REVISION (){0x000000ff} sub DSP_CAP_DUPLEX (){0x00000100} sub DSP_CAP_REALTIME (){0x00000200} sub DSP_CAP_BATCH (){0x00000400} sub DSP_CAP_COPROC (){0x00000800} sub DSP_CAP_TRIGGER (){0x00001000} sub DSP_CAP_MMAP (){0x00002000} sub SNDCTL_DSP_GETTRIGGER (){0x80045010} sub SNDCTL_DSP_SETTRIGGER (){0x40045010} sub PCM_ENABLE_INPUT (){0x00000001} sub PCM_ENABLE_OUTPUT (){0x00000002} sub SNDCTL_DSP_RESET (){0x00005000} sub SNDCTL_DSP_SYNC (){0x00005001} sub SNDCTL_DSP_SPEED (){0xc0045002} sub SNDCTL_DSP_STEREO (){0xc0045003} sub SNDCTL_DSP_GETBLKSIZE (){0xc0045004} sub SNDCTL_DSP_SAMPLESIZE (){0xc0045005} sub SNDCTL_DSP_CHANNELS (){0xc0045006} sub SOUND_PCM_WRITE_CHANNELS (){0xc0045006} sub SOUND_PCM_WRITE_FILTER (){0xc0045007} sub SNDCTL_DSP_POST (){0x00005008} sub SNDCTL_DSP_SUBDIVIDE (){0xc0045009} sub SNDCTL_DSP_SETFRAGMENT (){0xc004500a} sub SNDCTL_DSP_GETFMTS (){0x8004500b} sub SNDCTL_DSP_SETFMT (){0xc0045005} sub AFMT_QUERY (){0x00000000} sub AFMT_MU_LAW (){0x00000001} sub AFMT_A_LAW (){0x00000002} sub AFMT_IMA_ADPCM (){0x00000004} sub AFMT_U8 (){0x00000008} sub AFMT_S16_LE (){0x00000010} sub AFMT_S16_BE (){0x00000020} sub AFMT_S8 (){0x00000040} sub AFMT_U16_LE (){0x00000080} sub AFMT_U16_BE (){0x00000100} sub AFMT_MPEG (){0x00000200} sub SNDCTL_SEQ_RESET (){0x00005100} sub SNDCTL_SEQ_SYNC (){0x00005101} sub SNDCTL_SYNTH_INFO (){0xc08c5102} sub SNDCTL_SEQ_CTRLRATE (){0xc0045103} sub SNDCTL_SEQ_GETOUTCOUNT (){0x80045104} sub SNDCTL_SEQ_GETINCOUNT (){0x80045105} sub SNDCTL_SEQ_PERCMODE (){0x40045106} sub SNDCTL_FM_LOAD_INSTR (){0x40285107} sub SNDCTL_SEQ_TESTMIDI (){0x40045108} sub SNDCTL_SEQ_RESETSAMPLES (){0x40045109} sub SNDCTL_SEQ_NRSYNTHS (){0x8004510a} sub SNDCTL_SEQ_NRMIDIS (){0x8004510b} sub SNDCTL_MIDI_INFO (){0xc074510c} sub SNDCTL_SEQ_THRESHOLD (){0x4004510d} sub SNDCTL_SYNTH_MEMAVL (){0xc004510e} sub SNDCTL_FM_4OP_ENABLE (){0x4004510f} sub SNDCTL_SEQ_PANIC (){0x00005111} sub SNDCTL_SEQ_OUTOFBAND (){0x40085112} sub SNDCTL_SEQ_GETTIME (){0x80045113} sub SNDCTL_SYNTH_ID (){0xc08c5114} sub SNDCTL_SYNTH_CONTROL (){0xcfa45115} sub SNDCTL_SYNTH_REMOVESAMPLE (){0xc00c5116} 1; Video-Capture-V4l-0.902/examples/settv0000755000000000000000000000566310211641046016252 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; sub print_capability { my $c=shift; print "Device: "; print "name ",$c->name; print ", type"; for (qw(capture tuner teletext overlay chromakey clipping frameram scales monochrome subcapture)) { print " $_" if eval "\$c->$_"; } print ", channels ",$c->channels; print ", audios ",$c->audios; print ", sizes ",$c->minwidth,"x",$c->minheight,"-",$c->maxwidth,"x",$c->maxheight; print "\n"; } sub print_channel { my $c=shift; print "Channel ",$c->channel,": "; print "name ",$c->name; print ", tuners ",$c->tuners; print ", flags"; for (qw(tuner audio)) { print " $_" if eval "\$c->$_"; } print ", type"; for (qw(tv camera)) { print " $_" if eval "\$c->$_"; } # PAL, NTSC, SECAM, PAL-NC, PAL-M, PAL-N, NTSC-Japan print ", norm ",$c->norm; print "\n"; } sub print_tuner { my $c=shift; print "Tuner ",$c->tuner,": "; print "name ",$c->name; print ", range ",$c->rangelow,"-",$c->rangehigh; print ", flags"; for (qw(pal ntsc secam low norm stereo_on rds_on mbs_on)) { print " $_" if eval "\$c->$_"; } print ", mode ",$c->mode; print ", signal ",$c->signal; print "\n"; } sub print_audio { my $c=shift; print "Audio Channel ",$c->audio,": "; print "volume ",$c->volume; print ", bass ",$c->bass; print ", treble ",$c->treble; print ", flags"; for (qw(mute mutable volume bass treble)) { print " $_" if eval "\$c->$_"; } print ", name ",$c->name; print ", mode ",$c->mode; print ", balance ",$c->balance; print ", step ",$c->step; print "\n"; } sub print_picture { my $c=shift; print "Picture Settings: "; print "brightness ",$c->brightness; print ", hue ",$c->hue; print ", colour ",$c->colour; print ", contrast ",$c->contrast; print ", whiteness ",$c->whiteness; print ", depth ",$c->depth; print ", palette ",$c->palette; print "\n"; } $grab = new Video::Capture::V4l or die "Unable to open Videodevice: $!"; print_capability $grab->capability; for (0..$grab->capability->channels-1) { print_channel $grab->channel($_); } for($_=0; my $tuner = $grab->tuner($_); $_++) { last if $tuner->tuner != $_; print_tuner $tuner; } for($_=0; my $audio = $grab->audio($_); $_++) { last if $audio->audio != $_; print_audio $audio; } print_picture $grab->picture; my $channel = $grab->channel (0); $channel->norm(MODE_PAL); $channel->set; my $tuner = $grab->tuner (0); $tuner->mode(MODE_PAL); $tuner->set; my $channel = $grab->channel (1); $channel->norm(MODE_PAL); $channel->set; $RTL2 = 154250; print $grab->freq ($RTL2),"\n"; $|=1; my $frame=0; my $fr=$grab->capture ($frame, 64, 48); for(;;) { my $nfr = $grab->capture (1-$frame, 64, 48); $grab->sync($frame) or die "unable to sync"; open X, ">x"; print X $fr; close X; # save $fr now, as it contains the raw BGR data print "."; $frame = 1-$frame; $fr = $nfr; } Video-Capture-V4l-0.902/examples/autotune0000755000000000000000000001064510211641046016745 0ustar rootroot#!/usr/bin/perl # dumps "interesting" data about tv channels use Getopt::Long; use Video::Frequencies; use Video::Capture::V4l; use Video::Capture::VBI qw/:DEFAULT %VPS_CNI %VT_NI/; use Video::XawTV; GetOptions "+verbose|v" => \$verbose or exit 1; $rc = new Video::XawTV; eval { $rc->load("$ENV{HOME}/.xawtv") }; $ftab = $rc->opt('freqtab') || "pal-europe"; $freq = $CHANLIST{$ftab} or die "no such frequency table: $ftab"; $v4l = new Video::Capture::V4l; $tuner = $v4l->tuner(0); $channel = $v4l->channel(0); $tuner->mode(MODE_PAL); $tuner->set; $channel->norm(MODE_PAL); $channel->set; $vbi = new Video::Capture::V4l::VBI or die; $vbi_fd = $vbi->fileno; $|=1; my @channels; for $chan (sort keys %$freq) { my $f = $freq->{$chan}; print "tuning to $chan ($f)..."; $v4l->freq($f); select undef,undef,undef,0.2; # shit! $vbi->backlog (10); %fea = (); scan_vbi (50); $vbi->backlog (0); if ($tuner->signal > 30000) { my $cni = $VPS_CNI{$fea{CNI} & 0xfff}; my $ni = $VT_NI{$fea{NI}}; my $name; if (defined $ni) { $name = "$ni->[0] ($ni->[1])"; } elsif (defined $cni) { $name = $cni; } elsif ($fea{NAME}) { $name = $fea{NAME}; } elsif (length $fea{VT} > 1) { $name = $fea{VT}; } else { $name = "channel $chan"; } $name =~ s/\s*"\s*/ /g; $name =~ s/\s*\(.*?\)\s*/ /g; $name =~ s/^\s+//; $name =~ s/\s+$//; print " $name"; print " ["; while(my($k,$v)=each %fea) { print " $k","[$v]"; } print " ]"; my $c = { name => $name, channel => $chan, capture => 'on' }; if (1||$verbose) { $c->{features} = join(":", %fea); } my $key = find_key ($name); $c->{key} = $key if $key; push @channels, $c; } else { print " no signal"; } print "\n"; } $rc->channels(@channels); $rc->save("xawtvrc"); print "\nnew xawtvrc saved as ./xawtvrc\n"; sub scan_vbi { my $frames = shift; my($name_,$name,$name2); while ($frames) { my $vbi_alloc; $tuner->get; return if $tuner->signal < 30000; $frames--; return if (defined $VT_NI{$fea{NI}} || defined $VPS_CNI{$fea{CNI}}) && !$verbose; for (decode_field $vbi->field, VBI_VT|VBI_VPS|VBI_OTHER|VBI_EMPTY) { if ($_->[0] == VBI_VPS) { $fea{CNI}=$_->[3]; if (ord($_->[1]) > 127 or length $name_ >= 12) { if ($name eq $name_) { $fea{NAME}=$name; } $name = $name_; } $name_ .= $_->[1] & "\x7f"; $fea{VPS}=sprintf "%04x", $_->[3]; $vbi_alloc .= "V"; } elsif ($_->[0] == VBI_VT) { if ($_->[2] == 0) { if ($_->[4] == 0x1df) { $fea{EPG}=""; } else { $fea{VT}=vt_2_name($_->[3]); } } elsif ($_->[2] == 30) { if (($_->[3]>>1) == 0) { $fea{NI} = $_->[6]; $fea{'NI30/1'}=sprintf "%04x", $_->[6]; } elsif (($_->[3]>>1) == 8) { $fea{PDC}=""; } else { $fea{"30"}="$_->[3]"; } } elsif ($_->[2] == 31) { if ($_->[4] == 0x500) { $fea{"$_->[1]/IC"}=""; } else { $fea{sprintf "$_->[1]/31[%x]",$_->[4]}++; } } $vt++; $vbi_alloc .= "T"; } elsif ($_->[0] == VBI_OTHER) { $vbi_alloc .= $_->[1] == 1 ? "c" : "O"; } elsif ($_->[0] == VBI_EMPTY) { $vbi_alloc .= "."; } else { $others++; } } $fea{ALLOC}=$vbi_alloc; select undef,undef,undef,0.1 unless $vbi->queued; } } # try to guess sender name from videotext sub vt_2_name { local $_ = substr (shift, 8, 20) & ("\x7f") x 20; s/^\d+//; s/^[\x00-\x1f ]+//; s/\s*[\x00-\x1f].*//; s/\W?text.*//i; $_; } sub find_key { local $_ = shift; return '.' if /3sat/; return '1' if /ARD/; return '2' if /ZDF/; return '3' if /SW 3/; return '7' if /PRO 7/; return 'r' if /RTL Plus/; return 't' if /RTL 2/; return 'i' if /VIVA 2/; return 'v' if /VIVA/; return 'm' if /MTV/; return 's' if /SAT 1/; return 'k' if /Kabel 1/; return 'e' if /EuroNews/; return 'a' if /Arte/; return 'x' if /VOX/; (); } Video-Capture-V4l-0.902/examples/dumpepg0000755000000000000000000000632010211641046016535 0ustar rootroot#!/usr/bin/perl # dumpepg dumps the epg database given as first argument run "getepg" to # create it. use Storable; use POSIX 'strftime'; my $db_name = $ARGV[0]; $db_name .= ".epg" unless -e $db_name; print "Electronic Program Guide <$db_name>\n\n"; *db = Storable::retrieve($db_name); sub dump_ai { my $ai = shift; printf "EPG STREAM 1 <%d>", $ai->{epg_version}; printf " #ni %d, #oi %d, #mi %d\n", $ai->{no_navigation}, $ai->{no_osd}, $ai->{no_message}; printf "EPG STREAM 2 <%d>", $ai->{epg_version_swo}; printf " #ni %d, #oi %d, #mi %d\n", $ai->{no_navigation_swo}, $ai->{no_osd_swo}, $ai->{no_message_swo}; printf "this network #%d (%s) # updates %d\n", $ai->{this_network_op}, $ai->{service_name}, $ai->{no_updates}; for (@{$ai->{networks}}) { printf " network #%04x (%s), LTO %d, %d days, range<%d-%d/%d>, @%d, +%03x\n", @$_{qw/cni netwop_name LTO nodays prog_start_no prog_stop_no prog_stop_swo default_alphabet network_add_info/}; } print "\n"; } sub string2text { local $_ = shift; y/~{|}[]/ßaöäüÄÜ/; s/(.{40})/$1\n/g; s/([\x00-\x07])/sprintf " [%dm", ord($1)+30/ge; s/([\x00-\x09\x0b-\x1a\x1c-\x1f])/sprintf "·[%02x]",ord $1/ge; s/^ //g; $_.""; } sub date2unix { my($date,$time,$lto)=@_; 381283200 + ($date-45000) * 86400 + ($time >> 12 ) * 10 * 60 * 60 + ($time >> 8 & 15) * 60 * 60 + ($time >> 4 & 15) * 10 * 60 + ($time & 15) * 60 + $lto * 15; } sub date2text { sprintf "{%04x}", $_[0]; } sub time2text { sprintf "%02x:%02x", $_[0] >> 8, $_[0] & 0xff; } dump_ai($db{ai}); my @pi = map values %$_, values %{$db{pi}}; printf "Dump of %d program information structures\n\n", 1*@pi; for (sort { $a->{start_date} <=> $b->{start_date} || $a->{start_time} <=> $b->{start_time} || $a->{netwop_no} <=> $b->{netwop_no} } @pi) { my $ti = string2text($_->{title}); my $start = date2unix($_->{start_date}, $_->{start_time}, $db{ai}{networks}[$_->{netwop_no}]{LTO}); my $stop = date2unix($_->{start_date}, $_->{stop_time }, $db{ai}{networks}[$_->{netwop_no}]{LTO}); $stop += 86400 if $stop < $start; printf "PI #%d (%s) %s - %s \"%s\"\n", $_->{block_no}, $db{ai}{networks}[$_->{netwop_no}]{netwop_name}, strftime("%A %Y-%m-%d %H:%M", localtime $start), strftime("%H:%M", localtime $stop), $ti; my $si = string2text($_->{shortinfo}); $si =~ s/^/ /gm; print $si,"\n"; my $si = string2text($_->{longinfo}); $si =~ s/^/ /gm; print " =>",$si,"\n"; print " FLAGS <"; printf " editorial rating %d", $_->{editoral_rating} if $_->{editoral_rating}>0; printf " parental rating %d", $_->{parental_rating} if $_->{parental_rating}>0; print " Mono" if $_->{audio_flags}==0; print " 2 Channel" if $_->{audio_flags}==1; print " Stereo" if $_->{audio_flags}==2; print " Surround" if $_->{audio_flags}==3; print " Widescreen" if $_->{feature_flags}&4; print " PAL+" if $_->{feature_flags}&8; print " Digital" if $_->{feature_flags}&16; print " Encrypted" if $_->{feature_flags}&32; print " Live" if $_->{feature_flags}&64; print " Repeated" if $_->{feature_flags}&128; print " Subtitled" if $_->{feature_flags}&256; print " >\n"; print "\n"; } Video-Capture-V4l-0.902/examples/epgview0000755000000000000000000001273010211641046016544 0ustar rootroot#!/usr/bin/perl use Storable; use POSIX 'strftime'; use Carp; use Curses; my $pair = 0; my $db_name = $ARGV[0]; END { endwin }; initscr; start_color; cbreak; noecho; nonl; intrflush 0; keypad 1; immedok 0; idlok 1; scrollok 0; leaveok 1; clear; sub cattr($$) { return $cattr{$_[0],$_[1]} if defined $cattr{$_[0], $_[1]}; $pair++; init_pair ($pair, $_[0], $_[1]); $cattr{$_[0],$_[1]} = COLOR_PAIR($pair); } sub date2unix { my($date,$time,$lto)=@_; 381283200 + ($date-45000) * 86400 + ($time >> 12 ) * 10 * 60 * 60 + ($time >> 8 & 15) * 60 * 60 + ($time >> 4 & 15) * 10 * 60 + ($time & 15) * 60 + $lto * 15; } sub date2text { sprintf "{%04x}", $_[0]; } sub time2text { sprintf "%02x:%02x", $_[0] >> 8, $_[0] & 0xff; } my $wofs = -5*60; my $to; my $mtime = -1; my @pi; my $current = 1; my $shortinfo = 1; sub load_db { return if -M $db_name == $mtime; $mtime = -M $db_name; *db = eval { Storable::retrieve($db_name) } || { }; @pi = map values %$_, values %{$db{pi}}; for (@pi) { $_->{start_time} = date2unix($_->{start_date}, $_->{start_time}, $db{ai}{networks}[$_->{netwop_no}]{LTO}); $_->{stop_time} = date2unix($_->{start_date}, $_->{stop_time} , $db{ai}{networks}[$_->{netwop_no}]{LTO}); $_->{stop_time} += 86400 if $_->{stop_time} < $_->{start_time}; } @pi = sort { $a->{start_time} <=> $b->{start_time} || $a->{netwop_no} <=> $b->{netwop_no} } @pi; } move (1,0); standout; addch "=" for 1..$COLS; standend; for(;;) { load_db; $now = time; $to = $now + 60; move (0,0); addstr sprintf "%s (window offset %5d)\n", strftime("%H:%M:%S", localtime $now), int($wofs / 60); show_current(); move (0, 40); addstr ($to-$now); refresh; while (time < $to) { my $r = ""; vec ($r, fileno STDIN, 1) = 1; select $r,undef,undef,1; if (vec ($r, fileno STDIN, 1)) { my $key = getch; exit if $key eq "q" || $key eq "\x1b"; $current = !$current if $key eq "c"; $shortinfo = !$shortinfo if $key eq "s"; $wofs = -300 if $key eq "." || $key == KEY_HOME; $wofs -= 300 if $key eq "k" || $key == KEY_UP; $wofs += 300 if $key eq "j" || $key == KEY_DOWN; $wofs -= 3600 if $key eq ""|| $key == KEY_PPAGE; $wofs += 3600 if $key eq ""|| $key == KEY_NPAGE; last; } elsif (-M $db_name != $mtime) { last; } } } my ($y,$x); sub outstr { my $s = shift; my($l,$r); for (;;) { $l = length $s; $r = $COLS - $x; if ($l < $r) { addstr ($s); $x += $l; last; } addstr $1 if $s =~ s/^(.{1,$r})([\x00-\x20]+|$)//; $y++; move $y, 35; $x = 35; } } sub addttstr($$) { my ($fg, $bg) = (COLOR_WHITE, COLOR_BLACK); my $y1; local $_ = shift; y/~{|}[]/ßäöüÄÜÖ/; # buggy as hell :( s/\s*([\x00-\x20])\s*/$1/g; # wipe away superflous spaces getyx $y, $x; $y1 = $y; for(;;) { if (/\G([\x20-\xff]+)/gc) { attrset (cattr ($fg, $bg)); outstr $1; } elsif (/\G([\x00-\x07])/gc) { $fg = COLOR_BLACK if $1 eq "\x00"; $fg = COLOR_RED if $1 eq "\x01"; $fg = COLOR_GREEN if $1 eq "\x02"; $fg = COLOR_YELLOW if $1 eq "\x03"; $fg = COLOR_BLUE if $1 eq "\x04"; $fg = COLOR_MAGENTA if $1 eq "\x05"; $fg = COLOR_CYAN if $1 eq "\x06"; $fg = COLOR_WHITE if $1 eq "\x07"; outstr " "; } elsif (/\G\x1d/gc) { $bg = $fg; outstr " "; } elsif (/\G./gc) { # nop } else { last; } } attrset (cattr (COLOR_WHITE, COLOR_BLACK)); #s/([\x00-\x07])/sprintf " [%dm", ord($1)+30/ge; #s/([\x00-\x09\x0b-\x1a\x1c-\x1f])/sprintf "·[%02x]",ord $1/ge; #s/^ //g; #$_.""; $_[1] += $y-$y1; } sub show_current { my $trenn = 2; my $lines = $LINES - 2; move (2, 0); clrtobot; for (@pi) { if ($_->{start_time} < $now + $wofs) { next if !$current || $_->{stop_time} < $now; $to = $_->{stop_time} if $to > $_->{stop_time} && $_->{stop_time} >= $now; } else { $to = $_->{start_time} if $to > $_->{start_time} && $_->{start_time} > $now; } my $start = $_->{start_time}; my $stop = $_->{stop_time}; if ($start > $now) { if ($trenn == 1) { addch (ACS_HLINE) for 1..$COLS; $lines--; } $trenn = 0; } elsif ($trenn == 2) { $trenn = 1; } addstr sprintf "%s-%s (%+4d) %-10.10s ", strftime("%H:%M", localtime $start), strftime("%H:%M (%d)", localtime $stop), int (($start-$now)/60), $db{ai}{networks}[$_->{netwop_no}]{netwop_name}; my $si; if ($shortinfo) { unless ($_->{sinfo}) { $si = delete $_->{shortinfo}; my $li = delete $_->{longinfo}; for ($si, $li) { s/(.{40})/$1 /g; s/\s\s+/ /g; } for (my $x = length($si); $x; $x--) { if (substr ($si, -$x) eq substr ($li, 0, $x)) { substr ($si, -$x) = $li; last; } } $si =~ s/[\x00-\x20]+$//; $_->{sinfo} = $si; } $si = $_->{sinfo}; } addttstr ($_->{title}.$si, $lines); addch ("\n"); last unless --$lines; } clrtobot; } Video-Capture-V4l-0.902/examples/finder0000755000000000000000000000463010211641046016345 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; use Time::HiRes 'time'; $grab = new Video::Capture::V4l; my $channel = $grab->channel (0); my $tuner = $grab->tuner (0); $tuner->mode(MODE_PAL); $tuner->set; $channel->norm(MODE_PAL); $channel->set; $grab->picture->brightness(32768); $grab->picture->contrast(40000); $grab->picture->hue(32768); $grab->picture->colour(32768); $grab->picture->set; #$RTL2 = 855250; $RTL2 = 154250; print $grab->freq ($RTL2),"\n"; $|=1; open DB," }; my $frame=0; my $fr=$grab->capture ($frame,$w<<4,$h<<4); my $fps = 25; # glorious PAL my @reg; my ($expect_frame,$expect_count); my $start = time; my $next_frame = 0; my $this_frame; my $locked; my $minb1 = 10; for(;;) { my $nfr = $grab->capture (1-$frame,$w<<4,$h<<4); $this_frame = $next_frame; $next_frame = int((time-$start)*$fps); $grab->sync($frame) or die "unable to sync"; Video::Capture::V4l::reduce2($fr,$w<<4); Video::Capture::V4l::reduce2($fr,$w<<3); Video::Capture::V4l::reduce2($fr,$w<<2); Video::Capture::V4l::reduce2($fr,$w<<1); Video::Capture::V4l::normalize($fr); ($fr,$diff) = Video::Capture::V4l::findmin ($db, $fr, $expect_frame, $expect_count); if ($diff < 400*400) { push(@reg,$this_frame,$fr); if (@reg > $fps*2) { shift @reg; shift @reg; my ($a,$b,$r2) = Video::Capture::V4l::linreg(\@reg); if ($frame_zero) { $expect_frame = $this_frame + $frame_zero + 1; $expect_count = 25; } else { $expect_frame = $expect_count = 0; } printf "%9.2f + %7.2f * %6d =~ %4d (@%9.2f) EXPECT %6d - %4d ($minb1)",$a,$b,$this_frame,$fr,$r2,$frame_zero,$expect_frame; my $b1 = abs($b-1); if ($r2<100 && $b1<0.01) { $found++; print " LOCKED LOCKED LOCKED ($locked, $frame_zero)"; } if ($b1<$minb1) { $frame_zero=-$a; $minb1 = $b1; } print "\n"; } $jitter=0; } else { $jitter++; if ($jitter > 5) { $expect_frame=$expect_count=$frame_zero=0; } } if ($found && $this_frame>$frame_zero+2000) { print "KICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFFKICKOFF\n"; die; } $count++; $frame = 1-$frame; $fr = $nfr; } Video-Capture-V4l-0.902/examples/getepg0000755000000000000000000001067010211641046016352 0ustar rootroot#!/usr/bin/perl # EPG (Electronic Program Guide Decoder) # Commercial Name: nexTView use Video::Capture::V4l; use Video::Capture::VBI; package Video::Capture::VBI::EPG; use Video::Capture::VBI qw(:DEFAULT %VPS_CNI %VT_NI); use Storable; use base 'Video::Capture::VBI::VT'; sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self; } my $lastcni = -1; sub feed { my $self = shift; my @r; for ($self->SUPER::feed(@_)) { if ($_->[0] == VBI_VPS) { if ($_->[3] != $lastcni) { $lastcni = $_->[3]; printf "CNI %04x (%s)\n", $_->[3], $VPS_CNI{$_->[3] & 0xfff}; } } else { push @r, $_; } } @r; } sub mydump { local $_ = shift; if (ref $_ eq "HASH") { print "{ "; while(my($k,$v)=each %$_) { print ", $k => "; mydump($v); } print " }"; } elsif (ref $_ eq "ARRAY") { print "[ "; for (@$_) { print ", "; mydump($_); } print " ]"; } else { y/\x20-\x7e//cd; print $_; } } sub set_epg { my $self = shift; my $name = shift; my $new_db = main::gen_db_name ($name); print "SET_EPG $new_db <= ", $self->{db_name}, "\n"; if ($self->{db_name} and $new_db eq $self->{db_name}) { print "saving ",$new_db,"..."; Storable::nstore($self->db, "$new_db~"); rename "$new_db~", $new_db; print "ok\n"; } else { $self->{db_name} = $new_db; print "trying to load $new_db..."; $self->db(eval { $self->db(Storable::retrieve($new_db)) }); print "ok\n"; } } # just display the page sub enter_page { my($self,$page)=@_; $pages++; return unless $page->{page} == 0x1df; my $sub = $page->{ctrl}; my $stream = VTX_S3($sub); my $height = VTX_S4($sub)<<3 | VTX_S2($sub); my $seq = VTX_S1($sub); my $s = \%{$self->{stream}{$stream}}; delete $s->{raw} unless (($seq-1)&15) == $s->{seq}; $s->{seq}=$seq; push @{$s->{raw}}, @{$page->{packet}}[1..$height]; $packets[$stream]++; #print "stream $stream, height $height, seq $seq, ",scalar @{$s->{raw}},"<\n"; for(decode_stream $s->{raw}) { if (my ($dt, $bi) = decode_block $_, \@{$self->{bundle}}) { if ($dt == 1) { my $ai = $self->{db}{ai}; $self->set_epg($bi->{service_name}); if ($ai) { print "$ai->{epg_version}, $ai->{epg_version_swo}, $ai->{this_network_op}, $ai->{service_name}\n"; if ($bi->{epg_version} != $ai->{epg_version} || $bi->{epg_version_swo} != $ai->{epg_version_swo} || $bi->{this_network_op} != $ai->{this_network_op}) { print "CHANNEL SWITCH, WIPING DATABASE\n"; delete $self->{db}; } } $self->{db}{ai} = $bi; } elsif ($dt == 2) { $self->{db}{pi}{$bi->{netwop_no}}{$bi->{block_no}} = $bi; } elsif ($dt == 3) { $self->{db}{ni}{$bi->{block_no}} = $bi; } elsif ($dt == 4) { $self->{db}{oi}{$bi->{block_no}} = $bi; } elsif ($dt == 5) { $self->{db}{mi}{$bi->{block_no}} = $bi; } else { print "UNKNOWN BLOCK TYPE $dt found\n"; } } } $|=1; printf "%7d %6d %6d %5d %5d %5d %5d\r", $pages, $packets[0], $packets[1], 1*%{$self->{db}{pi}}, 1*%{$self->{db}{ni}}, 1*%{$self->{db}{oi}}, 1*%{$self->{db}{mi}}; #printf "received epg page %04x\n", $sub; } sub enter_packet { my $self = shift; my $p = shift; return unless $p->[3] <= 1 && $p->[2] == 30; #printf "packet(@$p %04x)", $p->[6]; print "\n"; } sub db { my $self = shift; $self->{db} = shift if @_; $self->{db}; } package main; $vbi = new Video::Capture::V4l::VBI or die; # the next line is optional (it enables buffering) $vbi->backlog(150); # max. 5 seconds backlog (~4.6Mb) $inp_fd = fileno STDIN; $vbi_fd = $vbi->fileno; $vt = new Video::Capture::VBI::EPG; sub gen_db_name { shift() . ".epg"; } print "Capturing VBI block. Make sure you have tuned in to a channel with EPG!\n"; print "Aquisition may take up to twenty minutes (and more)!\n"; for(;;) { my $r=""; vec($r,$inp_fd,1)=1; vec($r,$vbi_fd,1)=1; select $r,undef,undef,0.04; $vt->feed(decode_field $vbi->field, VBI_VT|VBI_VPS) while $vbi->queued; if (vec($r,$inp_fd,1)) { $_ = ; if (/^q/i) { last; } } } Video-Capture-V4l-0.902/examples/mp2enc0000755000000000000000000000104110211641046016253 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; use Video::RTjpeg; $|=1; $SIG{PIPE} = 'IGNORE'; $stream = "/tmp/vstream"; require $stream; my $mode = $channels > 1 ? "s" : "i"; my $br = 192; $audioencode = "/root/cvt/mpeg_movie-1.6.0/audio_in/encode"; $ENV{MPEGTABLES} = "/root/cvt/mpeg_movie-1.6.0/audio_in/tables"; system "dd", "if=$outprefix.a", "of=$outprefix.pcm", "conv=swab"; open ENC, "| $audioencode" or die; print ENC <backlog(50); # max. 1 second backlog (~900kB) open $fh, ">/dev/null" or die; # 162203 -> 162586 jinglesize (5000) # line 0 - relatively normal teletext line (80a Data) # line 1 - hhFFOOOOLLLLcccccc # h maybe vertical/horizontal ecc like in intercast? # F fileno? # O offset in file # L length of file # c checksum? my $head; my $body; for (;;) { for (decode_field $vbi->field, VBI_VT) { if ($_->[1] == 0) { if ($_->[2] == 0) { printf "\n %04x %s", $_->[5], (unpack "H*", $_->[3]); } elsif ($_->[2] == 1) { $head = $_->[3]; $body = ""; } else { print " ",unpack "H8", $_->[3]; $body .= substr ($_->[3], 1); if ($_->[2] == 23 && length($body) == (22*39) && $head) { my ($fno, $t2, $t3) = unpack "xxvVV", $head; my $seq = Video::Capture::VBI::unham8($head); if ($t2 <= $t3 && $fno) { (print "\n$seq X"), next if substr($head,0,1) eq "\xea"; (print "\n$seq Y"), next if substr($head,0,1) eq "\xfd"; my ($s) = unpack "H*", $head; printf "\n(%2x, %5d, %8d, %8d) # %s-%s", $seq, $fno, $t2, $t3, substr($s,12*2,6*2), substr($s,18*2); print "X" if substr($head,0,1) eq "\xea"; print "Y" if substr($head,0,1) eq "\xfd"; sysopen FH, "/tmp/nbc/$fno", O_CREAT|O_RDWR, 0666 or die "/tmp/nbc/$fno: $!"; seek FH, $t2, 0; print " offset $t2 appending (",tell(FH),")"; print FH substr($head, 18); print FH $body; close FH; } } } } } } Video-Capture-V4l-0.902/examples/mpgenc0000755000000000000000000001300110211641046016337 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; use Video::RTjpeg; $|=1; $SIG{PIPE} = 'IGNORE'; $stream = "/tmp/vstream"; require $stream; $mpegencode = "/root/cvt/mpeg_movie-1.6.0/video_in/mpeg_encode"; my $gop = 8; $tmpdir = "/tmp/encode$$/"; $tmpdir = "/tmp/encode"; mkdir $tmpdir, 0700; $fsize = $w*$h*2; $partlen = $fps*60; $partlen = $gop*100; my @dec; sub new_vdecoder { my $number = @dec; my $decp = do { local *DECODER_READER }; my $decc = do { local *DECODER_WRITER }; pipe $decp, $decc; if (fork==0) { my ($buf, $tables); open DATA, "<$outprefix.v$number" or die; read DATA, $buf, 4; my ($tlen) = unpack "N*", $buf; read DATA, $tables, $tlen; Video::RTjpeg::init_decompress($tables, $w, $h); while (read DATA, $buf, 8) { my ($time, $size) = unpack "N*", $buf; print $decc pack "N", $time; read DATA, $buf, $size; print $decc Video::RTjpeg::decompress $buf; } exit; } push @dec, $decp; } my @nframeid; sub next_frame { my $min = 1e30; my $buf; my $minid; for (0..$#dec) { unless (defined $nframeid[$_]) { read $dec[$_], $buf, 4; $nframeid[$_] = unpack "N", $buf; } ($min,$minid) = ($nframeid[$_],$_) if $nframeid[$_] < $min && defined $nframeid[$_]; } read $dec[$minid], $buf, $fsize; undef $nframeid[$minid]; ($buf, $min); } new_vdecoder for 1..$vencoders; my $part = 0; sub do_encode { my ($pstart, $pframes) = @_; $pframes = sprintf "%06d", $pframes-1; $part = sprintf "%03d", $part+1; open TEMPLATE, ">$tmpdir/param" or die; print TEMPLATE <$tmpdir/frame%06d.yuv", $pframe; print FRAME $buf; close FRAME; $frame++; $pframe++; print "s" if $frame != $framex; } last if $frame >= $nframe; } do_encode $pstart, $pframe; Video-Capture-V4l-0.902/examples/record0000755000000000000000000000623610211641046016360 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; sub print_capability { my $c=shift; print "Device: "; print "name ",$c->name; print ", type"; for (qw(capture tuner teletext overlay chromakey clipping frameram scales monochrome subcapture)) { print " $_" if eval "\$c->$_"; } print ", channels ",$c->channels; print ", audios ",$c->audios; print ", sizes ",$c->minwidth,"x",$c->minheight,"-",$c->maxwidth,"x",$c->maxheight; print "\n"; } sub print_channel { my $c=shift; print "Channel ",$c->channel,": "; print "name ",$c->name; print ", tuners ",$c->tuners; print ", flags"; for (qw(tuner audio)) { print " $_" if eval "\$c->$_"; } print ", type"; for (qw(tv camera)) { print " $_" if eval "\$c->$_"; } # PAL, NTSC, SECAM, PAL-NC, PAL-M, PAL-N, NTSC-Japan print ", norm ",$c->norm; print "\n"; } sub print_tuner { my $c=shift; print "Tuner ",$c->tuner,": "; print "name ",$c->name; print ", range ",$c->rangelow,"-",$c->rangehigh; print ", flags"; for (qw(pal ntsc secam low norm stereo_on rds_on mbs_on)) { print " $_" if eval "\$c->$_"; } print ", mode ",$c->mode; print ", signal ",$c->signal; print "\n"; } sub print_audio { my $c=shift; print "Audio Channel ",$c->audio,": "; print "volume ",$c->volume; print ", bass ",$c->bass; print ", treble ",$c->treble; print ", flags"; for (qw(mute mutable volume bass treble)) { print " $_" if eval "\$c->$_"; } print ", name ",$c->name; print ", mode ",$c->mode; print ", balance ",$c->balance; print ", step ",$c->step; print "\n"; } sub print_picture { my $c=shift; print "Picture Settings: "; print "brightness ",$c->brightness; print ", hue ",$c->hue; print ", colour ",$c->colour; print ", contrast ",$c->contrast; print ", whiteness ",$c->whiteness; print ", depth ",$c->depth; print ", palette ",$c->palette; print "\n"; } $grab = new Video::Capture::V4l or die "Unable to open Videodevice: $!"; print_capability $grab->capability; for (0..$grab->capability->channels-1) { print_channel $grab->channel($_); } for($_=0; my $tuner = $grab->tuner($_); $_++) { last if $tuner->tuner != $_; print_tuner $tuner; } for($_=0; my $audio = $grab->audio($_); $_++) { last if $audio->audio != $_; print_audio $audio; } print_picture $grab->picture; my $channel = $grab->channel (0); my $tuner = $grab->tuner (0); $tuner->mode(MODE_PAL); $channel->norm(MODE_PAL); $tuner->mode(8); $tuner->set; $channel->set; $RTL2 = 154250; $RTL2 = 196250; my $format = PALETTE_YUYV; print $grab->freq ($RTL2),"\n"; $|=1; my($w,$h)=(576,432); my @dests = ( "stream1", "stream2", "stream3", ); my $frame=0; my $fr=$grab->capture($frame, $w, $h, $format); my $index=0; for(;;) { my $nfr = $grab->capture(1-$frame, $w, $h, $format); $grab->sync($frame) or print "unable to sync"; # save $fr now, as it contains the raw BGR data use File::Sync qw/fsync/; $index++; print "."; open FRAME, (sprintf ">%s/frame%08d", $dests[$index % @dests], $index) or die; print FRAME $fr; close FRAME; $frame = 1-$frame; $fr = $nfr; } Video-Capture-V4l-0.902/examples/xsview0000755000000000000000000000115610211641046016423 0ustar rootroot#!/usr/bin/perl use blib; use Video::Capture::V4l; use Video::RTjpeg; $outprefix = "/tmp/vstream"; require $outprefix; $|=1; open DATA, "<$outprefix.v0" or die; read DATA, $buf, 4; my ($tlen) = unpack "N*", $buf; read DATA, $tables, $tlen; Video::RTjpeg::init_decompress($tables, $w, $h); while (read DATA, $buf, 8) { my ($time, $size) = unpack "N*", $buf; read DATA, $buf, $size; $buf = Video::RTjpeg::decompress $buf; $buf = Video::RTjpeg::yuvrgb $buf; print ".$size"; #print ".",length($buf); open DISPLAY, "| display -size ${w}x$h rgb:-" or die; print DISPLAY $buf; close DISPLAY; } Video-Capture-V4l-0.902/examples/capture0000755000000000000000000001413010211641046016535 0ustar rootroot#!/usr/bin/perl # # capture a steady stream of video frames, compress it and split it into # multiple files, for long recording sessions # # configure it below # use Socket; use Fcntl; use Video::Capture::V4l; use Video::RTjpeg; use Time::HiRes 'time'; use File::Sync 'sync'; use IPC::SysV; use POSIX qw(nice WNOHANG); use IO::Select; BEGIN { require "linux-dsp-ioctl.ph" } $|=1; my $outprefix = "/tmp/vstream"; my $initial_fadein = 40; # initial settle time my $consec = 25; # push this many frames to each encoder my $syncfreq = 0.2; # pause this time between syncs my $vencoders = 8; # number of encoder processes my(@venc,@enc); #my ($w, $h, $vformat) = (704, 528, PALETTE_YUV420P); my ($cw, $ch, $vformat) = (576, 432, PALETTE_YUV420P); my ($cl, $cr, $ct, $cb) = (16,16, 16,16); #my ($cw, $ch, $vformat) = (320, 240, PALETTE_YUV420P); #my ($cl, $cr, $ct, $cb) = (0,0, 0,0); my $fps = 25; my $spf = 1/$fps; my ($x, $y, $w, $h) = ($cl, $ct, $cw-$cr-$cl, $ch-$cb-$ct); my ($rate, $channels, $aformat) = (44100, 2, &AFMT_S16_LE); my ($Q, $M) = (255, 0); my $fsize = $cw*$ch*2; my $buffers = int(32*1024*1024/$fsize); my $bufsize = $fsize * $buffers; my $shm = shmget IPC_PRIVATE, $bufsize, IPC_CREAT|0600; $shm or die "unable to allocate $bufsize shm segment"; END { shmctl $shm, IPC_RMID, 0 } $SIG{INT} = sub { exit }; my @buffers = (0..($buffers-1)); my $select = IO::Select->new(); my %cb; # audio setup sysopen DSP, "/dev/dsp", O_RDONLY or sysopen DSP, "/dev/dsp", O_RDONLY or die "unable to open /dev/dsp for reading: $!"; ioctl DSP, SNDCTL_DSP_SETFRAGMENT, pack "i", 0x7fff000e or die "SNDCTL_DSP_SETFRAGMENT: $!"; ioctl DSP, SNDCTL_DSP_SETFMT, pack "i", $aformat or die "SNDCTL_DSP_SETFMT: $!"; ioctl DSP, SNDCTL_DSP_CHANNELS, pack "i", $channels or die "SNDCTL_DSP_CHANNELS: $!"; ioctl DSP, SNDCTL_DSP_SPEED, pack "i", $rate or die "SNDCTL_DSP_SPEED: $!"; open AUDIO, ">$outprefix.a" or die; # video setup $grab = new Video::Capture::V4l or die "Unable to open Videodevice: $!"; my $channel = $grab->channel (0); my $tuner = $grab->tuner (0); $tuner->mode(MODE_PAL); $channel->norm(MODE_PAL); $tuner->mode(8); $tuner->set; $channel->set; #$CHANNEL69 = 855250; #print $grab->freq ($CHANNEL69),"\n"; sub new_vencoder { my $number = @enc; my $encp = do { local *ENCODER_WRITER }; my $encc = do { local *ENCODER_READER }; socketpair $encc, $encp, AF_UNIX, SOCK_STREAM, PF_UNSPEC; $select->add($encp); $cb[fileno $encp] = sub { my $buf; 4 == sysread $encp, $buf, 4 or die "unable to read bufferid"; $buf = unpack "N", $buf; push @buffers, $buf; }; if (0 == fork) { open DATA, ">$outprefix.v$number" or die "$!"; my $tables = Video::RTjpeg::init_compress($cw,$ch,$Q); Video::RTjpeg::init_mcompress(); syswrite DATA, pack "N", length($tables); syswrite DATA, $tables; my $buf; my $count = $number * 313; for(;;) { 8 == read $encc, $buf, 8 or die "incomplete frame time read: $!"; my ($buffer, $time) = unpack "NN", $buf; last if $buffer >= $buffers; shmread $shm, $buf, $buffer*$fsize, $fsize; syswrite $encc, (pack "N", $buffer); my $fr = Video::RTjpeg::mcompress($buf,$M,$M>>1, $x, $y, $w, $h); #my $fr = Video::RTjpeg::compress($buf); syswrite DATA, pack "NN", $time, length $fr; syswrite DATA, $fr; #Video::RTjpeg::fdatasync fileno DATA if ($count++ & 63) == 0; print "+"; } print "X"; exit; } push @enc, $encp; } new_vencoder for 1..$vencoders; @venc = map (($_)x$consec, @enc); my $frame = 0; my $frames = 0; my $dropped = 0; sub put_vframe { my $buffer = pop @buffers; my $enc = pop @venc; unshift @venc, $enc; if (defined $buffer) { print "-"; shmwrite $shm, ${$_[1]}, $buffer*$fsize, $fsize; syswrite $enc, (pack "NN", $buffer, $_[0]); } else { print "o"; $dropped++; } } my $syncpid = fork; if ($syncpid==0) { for(;;) { select undef, undef, undef, $syncfreq; print "S"; sync; } Video::RTjpeg::_exit; }; system "rtprio -p $$"; my $fr = \$grab->capture ($frame, $cw, $ch, $vformat); for(1..$initial_fadein) { my $nfr = \$grab->capture (1-$frame, $cw, $ch, $vformat); $grab->sync($frame) or die "unable to sync"; $frame = 1-$frame; $fr = $nfr; } my $start = time; my $nframe; $fr = \$grab->capture ($frame, $cw, $ch, $vformat); my $audpid = fork; if ($audpid==0) { my $count = 0; my $in = ""; vec($in, fileno DSP, 1) = 1; fcntl DSP, F_SETFL, O_NONBLOCK; ioctl DSP, SNDCTL_DSP_SETTRIGGER, pack "i", 0; ioctl DSP, SNDCTL_DSP_SETTRIGGER, pack "i", PCM_ENABLE_INPUT; for(;;) { my $buf; select my $xin = $in, undef, undef, $spf*2; print "."; if (0 < sysread DSP, $buf, 128*1024) { #print length $buf; syswrite AUDIO, $buf; } } Video::RTjpeg::_exit; }; my $do_capture = 1; $select->add(*STDIN); $cb[fileno STDIN] = sub { $do_capture = 0; }; while($do_capture) { printf "\n%02d:%02d +%2d %2ds %dd > ", int($nframe*$spf/60), int($nframe*$spf)%60, scalar@buffers, $frames-$nframe, $dropped if $frames % $fps == 0; my $nfr = \$grab->capture (1-$frame, $cw, $ch, $vformat); $grab->sync($frame) or die "unable to sync"; my $now = time; $nframe = int (($now-$start) / $spf + 0.5); $start = $now - $nframe * $spf; put_vframe($nframe, $fr); for ($select->can_read(0)) { $cb[fileno $_]->(); } $frame = 1-$frame; $frames++; $fr = $nfr; } open CTRL, ">$outprefix" or die; print CTRL <remove(*STDIN); close DSP; close AUDIO; kill 'TERM', $syncpid; kill 'TERM', $audpid; for (@enc) { syswrite $_, (pack "NN", -1, -1); $select->remove($_); } for(;;) { for ($select->can_read(0)) { $cb[fileno $_]->(); } } Video-Capture-V4l-0.902/examples/indexer0000755000000000000000000000276110211641046016537 0ustar rootroot#!/usr/bin/perl use Video::Capture::V4l; BEGIN { eval "use Time::HiRes 'time'" } $grab = new Video::Capture::V4l; my $channel = $grab->channel (0); my $tuner = $grab->tuner (0); $tuner->mode(MODE_PAL); $tuner->set; $channel->norm(MODE_PAL); $channel->set; my $fps = 25; # glorious PAL $grab->picture->brightness(32768); $grab->picture->contrast(40000); $grab->picture->hue(32768); $grab->picture->colour(32768); $grab->picture->set; #$RTL2 = 591250; #$RTL2 = 855250; $RTL2 = 154250; print $grab->freq ($RTL2),"\n"; $|=1; my($w,$h)=(128,128); my $count = 0; open DB,">db" or die; select DB; $|=1; select STDOUT; print "press enter to start> "; ; my $frame=0; my $fr=$grab->capture ($frame,$w,$h); print DB pack("N*",$w>>3,$h>>3); for(;;) { my $nfr = $grab->capture (1-$frame,$w,$h); $grab->sync($frame) or die "unable to sync"; my $stamp = time; if ($start && $start!=$stamp) { $stamp = int(($stamp-$start)*$fps+0.5); print(($stamp-$count)," frames lost\n") if $stamp > $count; $count=$stamp; } else { $start=$stamp; $stamp=$count; } # width MUST be divisible by 4 Video::Capture::V4l::reduce2($fr,$w>>0); Video::Capture::V4l::reduce2($fr,$w>>1); Video::Capture::V4l::reduce2($fr,$w>>2); Video::Capture::V4l::normalize($fr); #${$img->get_dataref}=$fr; $img->upd_data(); #wpnm $img,sprintf('frame/%03d',$count),'PPM',1; print " $count\r"; $count++; print DB pack("i",$stamp),$fr; $frame = 1-$frame; $fr = $nfr; } Video-Capture-V4l-0.902/examples/vbi-info0000755000000000000000000000515210211641046016607 0ustar rootroot#!/usr/bin/perl # dumps "interesting" data about tv channels use Video::Capture::V4l; use Video::Capture::VBI qw/:DEFAULT %VPS_CNI %VT_NI/; $vbi = new Video::Capture::V4l::VBI or die; # the next line is optional (it enables buffering) $vbi->backlog(25); # max. 1 second backlog (~900kB) $inp_fd = fileno STDIN; $vbi_fd = $vbi->fileno; print "VBI capturing started.\n\n"; print < q quit c clear EOF sub init { %fea = (); print "\n"; } sub fea { $fea{$_[0]} = $_[1]; } my($last_cni, $last_ni); for(;;) { my $r=""; vec($r,$inp_fd,1)=1; #vec($r,$vbi_fd,1)=1; select $r,undef,undef,0.2; while ($vbi->queued) { $fields++; my $vbi_alloc; for (decode_field $vbi->field, VBI_VT|VBI_VPS|VBI_OTHER|VBI_EMPTY) { if ($_->[0] == VBI_VPS) { init if $last_cni != $_->[3]; $last_cni = $_->[3]; if (ord($_->[1]) > 127 or length $name_ >= 12) { $name = $name_; $name_ = ""; } $name_ .= $_->[1] & "\x7f"; fea('VPS',sprintf "%04x=%s|$name",$_->[3],$VPS_CNI{$_->[3] & 0x0fff}); $vps++; $vbi_alloc .= "V"; } elsif ($_->[0] == VBI_VT) { if ($_->[2] == 0) { if ($_->[4] == 0x1df) { fea('EPG'); } else { fea('VT'); } } elsif ($_->[2] == 30) { if (($_->[3]>>1) == 0) { init if $last_ni != $_->[6]; $last_ni = $_->[6]; fea("NI30/1",sprintf "%04x=%s", $_->[6], $VT_NI{$_->[6]}[0]); } elsif (($_->[3]>>1) == 8) { fea('PDC'); } else { fea("30","$_->[3]"); } } elsif ($_->[2] == 31) { if ($_->[4] == 0x500) { fea("$_->[1]/IC"); } else { fea(sprintf "$_->[1]/31[%x]",$_->[4]); } } $vt++; $vbi_alloc .= "T"; } elsif ($_->[0] == VBI_OTHER) { $vbi_alloc .= $_->[1] == 1 ? "c" : "O"; } elsif ($_->[0] == VBI_EMPTY) { $vbi_alloc .= "."; } else { $others++; } } fea("alloc","$vbi_alloc"); } if (vec($r,$inp_fd,1)) { $_ = ; if (/^q/) { last; } elsif (/^c/) { init; } } printf "%5d|F %5d|VPS %6d|VT %5d|O", $fields, $vps,$vt,$others; while (my($k, $v) = each(%fea)) { print " $k"; print "[$v]" if $v; } $|=1; print " < \r"; $|=0; } Video-Capture-V4l-0.902/XawTV.pm0000644000000000000000000000552110211646347014712 0ustar rootrootpackage Video::XawTV; =head1 NAME Video::XawTV - read, create and edit .xawtvrc's. =head1 SYNOPSIS use Video::XawTV; $rc = new Video::XawTV; # - or - $rc = new Video::XawTV "$HOME{ENV}/.xawtv"; $rc->load("otherrcfile"); $rc->save; $rc->save("filename"); $source = $rc->opt('source'); $rc->opt('source') = "Television"; @channels = $rc->channels; $rc->channels(@channels); print $channels[0]{name}; # Arte print $channels[0]{channel}; # E4 =head1 DESCRIPTION Pardon? Ha! Haa! Hahahahahaha!!! =cut $VESRSION = 0.1; use Carp; sub new { my $self = bless {}, shift; $self->load(shift) if @_; $self; } my %std_global = ( norm => 1, capture => 1, source => 1, color => 1, bright => 1, hue => 1, contrast => 1, fullscreen => 1, wm-off-by => 1, freqtab => 1, pixsize => 1, 'jpeg-quality'=> 1, mixer => 1, lauch => 1, ); my %std_channel = ( channel => 1, fine => 1, norm => 1, key => 1, capture => 1, source => 1, color => 1, bright => 1, hue => 1, contrast => 1, ); sub load { my $self = shift; my $fn = shift; local $_; open FN, "<$fn" or croak "unable to open '$fn': $!"; $self->{fn} = $fn; $self->{channels} = []; my $channel = $self->{global} = {}; my $std = \%std_global; while () { if (/^#Video::XawTV=#\s*(\S+)\s*=\s*(.*)\s*$/) { $channel->{lc $1} = $2; } elsif (/^\s*#(.*)$/) { # comments are being reordered, but.. my! $channel->{"#$1"} = 1; } elsif (/^\s*(\S+)\s*=\s*(.*)\s*$/) { $channel->{lc $1} = $2; $std->{lc $1}++; } elsif (/\s*\[(.*)\]\s*$/) { push @{$self->{channels}}, $channel = { name => $1 }; $std = \%std_channel; } elsif (/\S/) { chomp; croak "unparsable statement in '$fn': '$_'"; } } close FN; } sub save_hash { my ($fh, $hash, $std) = @_; while (my ($k,$v) = each %$hash) { next if $k eq 'name'; if ($k =~ /^#/) { print $fh $k, "\n"; } else { print $fh "#Video::XawTV=#" unless $std->{lc $k}; print $fh "$k = $v\n"; } } print $fh "\n"; } sub save { my $self = shift; my $fn = shift || $self->{fn}; open FN,">$fn~" or croak "unable to open '$fn~' for writing: $!"; save_hash(*FN, $self->{global}, \%std_global); for (@{$self->{channels}}) { print FN "[", $_->{name}, "]\n"; save_hash(*FN, $_, \%std_channel); } close FN; rename "$fn~", $fn or croak "unable to replace '$fn': $!"; } sub opt { my $self = shift; my $opt = shift; $self->{global}{$opt} = shift if @_; $self->{global}{$opt}; } sub channels { my $self = shift; if (@_) { $self->{channels} = ref $_[0] eq "ARRAY" ? $_[0] : [@_]; } wantarray ? @{$self->{channels}} : $self->{channels}; } 1; Video-Capture-V4l-0.902/COPYING0000644000000000000000000004312710211640742014373 0ustar rootroot GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. Video-Capture-V4l-0.902/MANIFEST0000644000000000000000000000240010211640742014456 0ustar rootrootREADME Changes MANIFEST Makefile.PL test.pl gppport.h typemap COPYING TODO Frequencies.pm XawTV.pm V4l/Makefile.PL V4l/V4l.pm V4l/V4l.xs V4l/genacc VBI/Makefile.PL VBI/VBI.pm VBI/VBI.xs RTjpeg/Makefile.PL RTjpeg/RTjpeg.pm RTjpeg/RTjpeg.xs RTjpeg/codec/LICENSE.jpeg RTjpeg/codec/README RTjpeg/codec/RTjpeg.h RTjpeg/codec/compose.sh RTjpeg/codec/modules/RTb2s.c RTjpeg/codec/modules/RTb2s.ct RTjpeg/codec/modules/RTb2s_raw.c RTjpeg/codec/modules/RTb2s_raw.ct RTjpeg/codec/modules/RTcolor_grey.c RTjpeg/codec/modules/RTcolor_int.c RTjpeg/codec/modules/RTdct_aan.c RTjpeg/codec/modules/RTdct_aan.ct RTjpeg/codec/modules/RTdct_std.c RTjpeg/codec/modules/RTidct_aan.c RTjpeg/codec/modules/RTidct_std.c RTjpeg/codec/modules/RTinc.ct RTjpeg/codec/modules/RTmain.c RTjpeg/codec/modules/RTmain.ct RTjpeg/codec/modules/RTquant.c RTjpeg/codec/modules/RTquant_mmx.c RTjpeg/codec/modules/RTs2b.c RTjpeg/codec/modules/RTs2b_raw.c examples/grab examples/indexer examples/finder examples/vbi examples/vbi-info examples/getepg examples/dumpepg examples/autotune examples/epgview examples/capture examples/linux-dsp-ioctl.ph examples/mp2enc examples/mpgenc examples/record examples/settv examples/xsview examples/nbcmp3 META.yml Module meta-data (added by MakeMaker)