xref: /haiku/src/add-ons/media/media-add-ons/dvb/DVBMediaAddon.cpp (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
1 /*
2  * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify,
8  * merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include "DVBMediaAddon.h"
26 #include "DVBCard.h"
27 #include "DVBMediaNode.h"
28 #include "config.h"
29 
30 #include <string.h>
31 #include <stdio.h>
32 #include <time.h>
33 #include <Alert.h>
34 #include <Directory.h>
35 #include <Entry.h>
36 #include <Path.h>
37 
38 struct device_info
39 {
40 	DVBCard *		card;
41 	char			name[200];
42 	char			info[200];
43 	media_format 	formats[5];
44 	flavor_info 	flavor;
45 };
46 
47 
48 extern "C" BMediaAddOn *
49 make_media_addon(image_id id)
50 {
51 	return new DVBMediaAddon(id);
52 }
53 
54 
55 DVBMediaAddon::DVBMediaAddon(image_id id)
56  :	BMediaAddOn(id)
57 {
58 	ScanFolder("/dev/dvb");
59 }
60 
61 
62 DVBMediaAddon::~DVBMediaAddon()
63 {
64 	FreeDeviceList();
65 }
66 
67 
68 status_t
69 DVBMediaAddon::InitCheck(const char ** out_failure_text)
70 {
71 	if (!fDeviceList.CountItems()) {
72 		*out_failure_text = "No supported device found";
73 		return B_ERROR;
74 	}
75 	return B_OK;
76 }
77 
78 
79 int32
80 DVBMediaAddon::CountFlavors()
81 {
82 	return fDeviceList.CountItems();
83 }
84 
85 
86 status_t
87 DVBMediaAddon::GetFlavorAt(int32 n, const flavor_info ** out_info)
88 {
89 	device_info *dev = (device_info *)fDeviceList.ItemAt(n);
90 	if (!dev)
91 		return B_ERROR;
92 	*out_info = &dev->flavor;
93 	return B_OK;
94 }
95 
96 
97 BMediaNode *
98 DVBMediaAddon::InstantiateNodeFor(const flavor_info * info, BMessage * config,	status_t * out_error)
99 {
100 	printf("DVB: DVBMediaAddon::InstantiateNodeFor\n");
101 
102 	device_info *dev = (device_info *)fDeviceList.ItemAt(info->internal_id);
103 	if (!dev || dev->flavor.internal_id != info->internal_id) {
104 		*out_error = B_ERROR;
105 		return NULL;
106 	}
107 	*out_error = B_OK;
108 
109 	return new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card);
110 }
111 
112 
113 bool
114 DVBMediaAddon::WantsAutoStart()
115 {
116 #if BUILD_FOR_HAIKU
117 	printf("DVB: DVBMediaAddon::WantsAutoStart - NO\n");
118 	return false;
119 #else
120 	printf("DVB: DVBMediaAddon::WantsAutoStart - YES\n");
121 	return true;
122 #endif
123 }
124 
125 
126 status_t
127 DVBMediaAddon::AutoStart(int index, BMediaNode **outNode, int32 *outInternalID, bool *outHasMore)
128 {
129 	printf("DVB: DVBMediaAddon::AutoStart, index %d\n", index);
130 
131 #if BUILD_FOR_HAIKU
132 	return B_ERROR;
133 #else
134 
135 	device_info *dev = (device_info *)fDeviceList.ItemAt(index);
136 	if (!dev) {
137 		printf("DVB: DVBMediaAddon::AutoStart, bad index\n");
138 		return B_BAD_INDEX;
139 	}
140 
141 	*outHasMore = fDeviceList.ItemAt(index + 1) ? true : false;
142 	*outInternalID = dev->flavor.internal_id;
143 	*outNode = new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card);
144 
145 	printf("DVB: DVBMediaAddon::AutoStart, success\n");
146 
147 	return B_OK;
148 #endif
149 }
150 
151 
152 void
153 DVBMediaAddon::ScanFolder(const char *path)
154 {
155 	BDirectory dir(path);
156 	if (dir.InitCheck() != B_OK)
157 		return;
158 
159 	BEntry ent;
160 
161 	while (dir.GetNextEntry(&ent) == B_OK) {
162 		BPath path(&ent);
163 		if (ent.IsDirectory()) {
164 			ScanFolder(path.Path());
165 		} else {
166 			DVBCard *card = new DVBCard(path.Path());
167 			if (card->InitCheck() == B_OK)
168 				AddDevice(card, path.Path());
169 			else
170 				delete card;
171 		}
172 	}
173 }
174 
175 
176 void
177 DVBMediaAddon::AddDevice(DVBCard *card, const char *path)
178 {
179 	dvb_type_t type;
180 	char name[250];
181 	char info[1000];
182 	const char *dvbtype;
183 	const char *dvbnumber;
184 
185 	// get card name, info and type
186 	if (B_OK != card->GetCardType(&type)) {
187 		printf("DVBMediaAddon::AddDevice: getting DVB card type failed\n");
188 		return;
189 	}
190 	if (B_OK != card->GetCardInfo(name, sizeof(name), info, sizeof(info))) {
191 		printf("DVBMediaAddon::AddDevice: getting DVB card info failed\n");
192 		return;
193 	}
194 
195 	// get type
196 	switch (type) {
197 		case DVB_TYPE_DVB_C: dvbtype = "C"; break;
198 		case DVB_TYPE_DVB_H: dvbtype = "H"; break;
199 		case DVB_TYPE_DVB_S: dvbtype = "S"; break;
200 		case DVB_TYPE_DVB_T: dvbtype = "T"; break;
201 		default:
202 			printf("DVBMediaAddon::AddDevice: unsupported DVB type %d\n", type);
203 			return;
204 	}
205 
206 	// get interface number
207 	const char *p = strrchr(path, '/');
208 	dvbnumber = p ? p + 1 : "";
209 
210 	// create device_info
211 	device_info *dev = new device_info;
212 	fDeviceList.AddItem(dev);
213 
214 	dev->card = card;
215 
216 	// setup name and info, it's important that name starts with "DVB"
217 //	snprintf(dev->name, sizeof(dev->name), "DVB-%s %s (%s)", dvbtype, dvbnumber, name);
218 //	strlcpy(dev->info, info, sizeof(dev->info));
219 	sprintf(dev->name, "DVB-%s %s %s", dvbtype, name, dvbnumber);
220 	strcpy(dev->info, info);
221 
222 	// setup supported formats (the lazy way)
223 	memset(dev->formats, 0, sizeof(dev->formats));
224 	dev->formats[0].type = B_MEDIA_RAW_VIDEO;
225 	dev->formats[1].type = B_MEDIA_RAW_AUDIO;
226 	dev->formats[2].type = B_MEDIA_ENCODED_VIDEO;
227 	dev->formats[3].type = B_MEDIA_ENCODED_AUDIO;
228 	dev->formats[4].type = B_MEDIA_MULTISTREAM;
229 
230 	// setup flavor info
231 	dev->flavor.name = dev->name;
232 	dev->flavor.info = dev->info;
233 	dev->flavor.kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT;
234 	dev->flavor.flavor_flags = B_FLAVOR_IS_GLOBAL;
235 	dev->flavor.internal_id = fDeviceList.CountItems() - 1;
236 	dev->flavor.possible_count = 1;
237 	dev->flavor.in_format_count = 0;
238 	dev->flavor.in_format_flags = 0;
239 	dev->flavor.in_formats = 0;
240 	dev->flavor.out_format_count = 5;
241 	dev->flavor.out_format_flags = 0;
242 	dev->flavor.out_formats = dev->formats;
243 }
244 
245 
246 void
247 DVBMediaAddon::FreeDeviceList()
248 {
249 	device_info *dev;
250 	while ((dev = (device_info *)fDeviceList.RemoveItem((int32)0))) {
251 		delete dev->card;
252 		delete dev;
253 	}
254 }
255