ffi-hdhomerun 0.1.e8573162d6c7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.hgignore ADDED
@@ -0,0 +1,10 @@
1
+ syntax: glob
2
+ *.gem
3
+ .bundle
4
+ Gemfire.lock
5
+ pkg/*
6
+
7
+ *.png
8
+ .*.sw[a-z]
9
+ .AppleDouble
10
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ffi-hdhomerun.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ffi-hdhomerun"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ffi-hdhomerun"
7
+ s.version = "%s.%s" % [ HDHomeRun::VERSION,
8
+ `hg id -i`.chomp.sub("+", "m") ]
9
+ s.authors = ["David M. Lary"]
10
+ s.email = ["dmlary@gmail.com"]
11
+ s.homepage = "http://github.com/dmlary/ffi-hdhomerun"
12
+ s.summary = %q{Ruby FFI bindings for libhdhomerun}
13
+ s.description = %q{Ruby FFI bindings for libhdhomerun}
14
+
15
+ s.rubyforge_project = "ffi-hdhomerun"
16
+
17
+ s.files = `hg locate`.split("\n")
18
+ s.test_files = `hg locate -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `hg locate -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ s.add_dependency "ffi"
22
+ end
@@ -0,0 +1,131 @@
1
+ require 'ffi/hdhomerun'
2
+
3
+ module HDHomeRun
4
+ VERSION = "0.1"
5
+
6
+ class Tuner
7
+ include FFI::HDHomeRun
8
+
9
+ attr_reader :hd, :id, :tuner
10
+
11
+ # Initialize new hdhomerun tuner
12
+ #
13
+ # Arguments:
14
+ # [:id] HDHomeRun id (default: "FFFFFFFF")
15
+ # [:tuner] Tuner number (default: "/tuner0")
16
+ #
17
+ def initialize(p={})
18
+ p = {:id => p} unless p.is_a? Hash
19
+ p[:id] ||= "FFFFFFFF"
20
+ p[:tuner] ||= "/tuner0"
21
+
22
+ @hd = create_from_str(p[:id].to_s, nil)
23
+ raise ArgumentError, "Invalid device id: #{id}" if @hd.null?
24
+ @id = get_device_id_requested(@hd)
25
+
26
+ @tuner = p[:tuner]
27
+ @tuner = "/tuner%d" % @tuner unless @tuner.is_a? String
28
+ if set_tuner_from_str(@hd, @tuner) <= 0
29
+ raise RuntimeError, "invalid tuner: %s" % @tuner
30
+ end
31
+
32
+ raise ArgumentError, "Invalid device id: %08X" % id \
33
+ unless validate_device_id(@id)
34
+ raise RuntimeError, "Unable to connect to device" \
35
+ unless get_model_str(@hd)
36
+ end
37
+
38
+ def get(key)
39
+ value = FFI::MemoryPointer.new(:pointer, 1)
40
+ error = FFI::MemoryPointer.new(:pointer, 1)
41
+
42
+ if get_var(@hd, key, value, error) < 0
43
+ raise RuntimeError,
44
+ "communication error sending request to hdhomerun device"
45
+ end
46
+ value = value.read_pointer
47
+ error = error.read_pointer
48
+
49
+ raise RuntimeError, error.read_string unless error.null?
50
+ value.read_string
51
+ end
52
+
53
+ def set(key, value)
54
+ error = FFI::MemoryPointer.new(:pointer, 1)
55
+
56
+ if set_var(@hd, key, value.to_s, nil, error) < 0
57
+ raise RuntimeError,
58
+ "communication error sending request to hdhomerun device"
59
+ end
60
+ error = error.read_pointer
61
+
62
+ raise RuntimeError, error.read_string unless error.null?
63
+ true
64
+ end
65
+
66
+ def get_tuner(key)
67
+ get("%s/%s" % [@tuner, key.to_s])
68
+ end
69
+
70
+ def set_tuner(key, value)
71
+ set("%s/%s" % [@tuner, key.to_s], value)
72
+ end
73
+
74
+ # Dynamically define the following getter and setter methods
75
+ %w{channel channelmap filter program target}.each do |name|
76
+ define_method name do
77
+ get_tuner(name)
78
+ end
79
+
80
+ define_method "#{name}=" do |value|
81
+ set_tuner(name, value)
82
+ end
83
+ end
84
+
85
+ # Dynamically define these as simple getter methods
86
+ %w{status streaminfo}.each do |name|
87
+ define_method name do
88
+ get_tuner(name)
89
+ end
90
+ end
91
+
92
+ def stats
93
+ ptr = FFI::MemoryPointer.new Stats
94
+ out = Stats.new ptr;
95
+ get_video_stats(@hd, out)
96
+ out
97
+ end
98
+
99
+ def capture(p={}, &block)
100
+ raise ArgumentError, "no block" unless block_given?
101
+ raise RuntimeError, "unable to start stream" \
102
+ if stream_start(@hd) <= 0
103
+
104
+ max_delay = (p[:delay] || 0.064).to_f
105
+ last_yield = 0
106
+
107
+ begin
108
+ len_ptr = FFI::MemoryPointer.new :ulong
109
+
110
+ while true do
111
+ start = Time.now.to_f
112
+ data = stream_recv(@hd, VIDEO_DATA_BUFFER_SIZE_1S, len_ptr)
113
+
114
+ if !data.null? or start - last_yield > 1.0
115
+ last_yield = start
116
+
117
+ len = len_ptr.read_ulong
118
+ buf = data.read_string(len) if len > 0
119
+ buf ||= ""
120
+ yield(buf) or break
121
+ end
122
+
123
+ delay = max_delay - (Time.now.to_f - start)
124
+ sleep delay if delay > 0
125
+ end
126
+ ensure
127
+ stream_stop(@hd)
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,59 @@
1
+ require 'ffi'
2
+
3
+ module FFI
4
+ module HDHomeRun
5
+ extend FFI::Library
6
+ ffi_lib "libhdhomerun.so.1"
7
+
8
+ VIDEO_DATA_BUFFER_SIZE_1S = (20000000 / 8)
9
+
10
+ attach_function :create_from_str,
11
+ :hdhomerun_device_create_from_str,
12
+ [:string, :pointer], :pointer
13
+ attach_function :get_device_id_requested,
14
+ :hdhomerun_device_get_device_id_requested,
15
+ [:pointer], :uint
16
+ attach_function :validate_device_id,
17
+ :hdhomerun_discover_validate_device_id,
18
+ [:uint], :int
19
+ attach_function :get_model_str,
20
+ :hdhomerun_device_get_model_str,
21
+ [:pointer], :string
22
+ attach_function :get_var,
23
+ :hdhomerun_device_get_var,
24
+ [:pointer, :string, :pointer, :pointer], :int
25
+ attach_function :set_var,
26
+ :hdhomerun_device_set_var,
27
+ [:pointer, :string, :string, :pointer, :pointer], :int
28
+ attach_function :set_tuner_from_str,
29
+ :hdhomerun_device_set_tuner_from_str,
30
+ [:pointer, :string], :int
31
+ attach_function :stream_start,
32
+ :hdhomerun_device_stream_start,
33
+ [:pointer], :int
34
+ attach_function :stream_stop,
35
+ :hdhomerun_device_stream_stop,
36
+ [:pointer], :void
37
+ attach_function :stream_recv,
38
+ :hdhomerun_device_stream_recv,
39
+ [:pointer, :ulong, :pointer], :pointer
40
+ attach_function :get_video_stats,
41
+ :hdhomerun_device_get_video_stats,
42
+ [:pointer, :pointer], :void
43
+
44
+ class Stats < FFI::Struct
45
+ layout :packets, :uint,
46
+ :network_errors, :uint,
47
+ :transport_errors, :uint,
48
+ :sequence_errors, :uint,
49
+ :overflow_errors, :uint
50
+
51
+ %w{packets network_errors transport_errors
52
+ sequence_errors overflow_errors}.each do |name|
53
+ define_method name do
54
+ send(:[], name.to_sym)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ffi-hdhomerun
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.e8573162d6c7
5
+ prerelease: 4
6
+ platform: ruby
7
+ authors:
8
+ - David M. Lary
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-07 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ffi
16
+ requirement: &8668500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *8668500
25
+ description: Ruby FFI bindings for libhdhomerun
26
+ email:
27
+ - dmlary@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .hgignore
33
+ - Gemfile
34
+ - Rakefile
35
+ - ffi-hdhomerun.gemspec
36
+ - lib/ffi-hdhomerun.rb
37
+ - lib/ffi/hdhomerun.rb
38
+ homepage: http://github.com/dmlary/ffi-hdhomerun
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>'
54
+ - !ruby/object:Gem::Version
55
+ version: 1.3.1
56
+ requirements: []
57
+ rubyforge_project: ffi-hdhomerun
58
+ rubygems_version: 1.8.10
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Ruby FFI bindings for libhdhomerun
62
+ test_files: []