xref: /haiku/src/add-ons/media/media-add-ons/dvb/DVBMediaAddon.cpp (revision 96dbc7d53352b7360ca11ddf939ceaf7f54a61e9)
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 *
make_media_addon(image_id id)49 make_media_addon(image_id id)
50 {
51 	return new DVBMediaAddon(id);
52 }
53 
54 
DVBMediaAddon(image_id id)55 DVBMediaAddon::DVBMediaAddon(image_id id)
56 	: BMediaAddOn(id)
57 {
58 	ScanFolder("/dev/dvb");
59 }
60 
61 
~DVBMediaAddon()62 DVBMediaAddon::~DVBMediaAddon()
63 {
64 	FreeDeviceList();
65 }
66 
67 
68 status_t
InitCheck(const char ** out_failure_text)69 DVBMediaAddon::InitCheck(const char ** out_failure_text)
70 {
71 	debugger("");
72 	if (!fDeviceList.CountItems()) {
73 		*out_failure_text = "No supported device found";
74 		return B_ERROR;
75 	}
76 
77 	return B_OK;
78 }
79 
80 
81 int32
CountFlavors()82 DVBMediaAddon::CountFlavors()
83 {
84 	return fDeviceList.CountItems();
85 }
86 
87 
88 status_t
GetFlavorAt(int32 n,const flavor_info ** out_info)89 DVBMediaAddon::GetFlavorAt(int32 n, const flavor_info ** out_info)
90 {
91 	device_info *dev = (device_info *)fDeviceList.ItemAt(n);
92 	if (!dev)
93 		return B_ERROR;
94 	*out_info = &dev->flavor;
95 	return B_OK;
96 }
97 
98 
99 BMediaNode *
InstantiateNodeFor(const flavor_info * info,BMessage * config,status_t * out_error)100 DVBMediaAddon::InstantiateNodeFor(const flavor_info * info, BMessage * config,	status_t * out_error)
101 {
102 	printf("DVB: DVBMediaAddon::InstantiateNodeFor\n");
103 
104 	device_info *dev = (device_info *)fDeviceList.ItemAt(info->internal_id);
105 	if (!dev || dev->flavor.internal_id != info->internal_id) {
106 		*out_error = B_ERROR;
107 		return NULL;
108 	}
109 	*out_error = B_OK;
110 
111 	return new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card);
112 }
113 
114 
115 bool
WantsAutoStart()116 DVBMediaAddon::WantsAutoStart()
117 {
118 #if BUILD_FOR_HAIKU
119 //	printf("DVB: DVBMediaAddon::WantsAutoStart - NO\n");
120 	return false;
121 #else
122 //	printf("DVB: DVBMediaAddon::WantsAutoStart - YES\n");
123 	return true;
124 #endif
125 }
126 
127 
128 status_t
AutoStart(int index,BMediaNode ** outNode,int32 * outInternalID,bool * outHasMore)129 DVBMediaAddon::AutoStart(int index, BMediaNode **outNode, int32 *outInternalID, bool *outHasMore)
130 {
131 	printf("DVB: DVBMediaAddon::AutoStart, index %d\n", index);
132 
133 #if BUILD_FOR_HAIKU
134 	return B_ERROR;
135 #else
136 
137 	device_info *dev = (device_info *)fDeviceList.ItemAt(index);
138 	if (!dev) {
139 		printf("DVB: DVBMediaAddon::AutoStart, bad index\n");
140 		return B_BAD_INDEX;
141 	}
142 
143 	*outHasMore = fDeviceList.ItemAt(index + 1) ? true : false;
144 	*outInternalID = dev->flavor.internal_id;
145 	*outNode = new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card);
146 
147 	printf("DVB: DVBMediaAddon::AutoStart, success\n");
148 
149 	return B_OK;
150 #endif
151 }
152 
153 
154 void
ScanFolder(const char * path)155 DVBMediaAddon::ScanFolder(const char *path)
156 {
157 	BDirectory dir(path);
158 	if (dir.InitCheck() != B_OK)
159 		return;
160 
161 	BEntry ent;
162 
163 	while (dir.GetNextEntry(&ent) == B_OK) {
164 		BPath path(&ent);
165 		if (ent.IsDirectory()) {
166 			ScanFolder(path.Path());
167 		} else {
168 			DVBCard *card = new DVBCard(path.Path());
169 			if (card->InitCheck() == B_OK)
170 				AddDevice(card, path.Path());
171 			else
172 				delete card;
173 		}
174 	}
175 }
176 
177 
178 void
AddDevice(DVBCard * card,const char * path)179 DVBMediaAddon::AddDevice(DVBCard *card, const char *path)
180 {
181 	dvb_type_t type;
182 	char name[250];
183 	char info[1000];
184 	const char *dvbtype;
185 	const char *dvbnumber;
186 
187 	// get card name, info and type
188 	if (B_OK != card->GetCardType(&type)) {
189 		printf("DVBMediaAddon::AddDevice: getting DVB card type failed\n");
190 		return;
191 	}
192 	if (B_OK != card->GetCardInfo(name, sizeof(name), info, sizeof(info))) {
193 		printf("DVBMediaAddon::AddDevice: getting DVB card info failed\n");
194 		return;
195 	}
196 
197 	// get type
198 	switch (type) {
199 		case DVB_TYPE_DVB_C: dvbtype = "C"; break;
200 		case DVB_TYPE_DVB_H: dvbtype = "H"; break;
201 		case DVB_TYPE_DVB_S: dvbtype = "S"; break;
202 		case DVB_TYPE_DVB_T: dvbtype = "T"; break;
203 		default:
204 			printf("DVBMediaAddon::AddDevice: unsupported DVB type %d\n", type);
205 			return;
206 	}
207 
208 	// get interface number
209 	const char *p = strrchr(path, '/');
210 	dvbnumber = p ? p + 1 : "";
211 
212 	// create device_info
213 	device_info *dev = new device_info;
214 	fDeviceList.AddItem(dev);
215 
216 	dev->card = card;
217 
218 	// setup name and info, it's important that name starts with "DVB"
219 //	snprintf(dev->name, sizeof(dev->name), "DVB-%s %s (%s)", dvbtype, dvbnumber, name);
220 //	strlcpy(dev->info, info, sizeof(dev->info));
221 	sprintf(dev->name, "DVB-%s %s %s", dvbtype, name, dvbnumber);
222 	strcpy(dev->info, info);
223 
224 	// setup supported formats (the lazy way)
225 	memset(dev->formats, 0, sizeof(dev->formats));
226 	dev->formats[0].type = B_MEDIA_RAW_VIDEO;
227 	dev->formats[1].type = B_MEDIA_RAW_AUDIO;
228 	dev->formats[2].type = B_MEDIA_ENCODED_VIDEO;
229 	dev->formats[3].type = B_MEDIA_ENCODED_AUDIO;
230 	dev->formats[4].type = B_MEDIA_MULTISTREAM;
231 
232 	// setup flavor info
233 	dev->flavor.name = dev->name;
234 	dev->flavor.info = dev->info;
235 	dev->flavor.kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT;
236 	dev->flavor.flavor_flags = B_FLAVOR_IS_GLOBAL;
237 	dev->flavor.internal_id = fDeviceList.CountItems() - 1;
238 	dev->flavor.possible_count = 1;
239 	dev->flavor.in_format_count = 0;
240 	dev->flavor.in_format_flags = 0;
241 	dev->flavor.in_formats = 0;
242 	dev->flavor.out_format_count = 5;
243 	dev->flavor.out_format_flags = 0;
244 	dev->flavor.out_formats = dev->formats;
245 }
246 
247 
248 void
FreeDeviceList()249 DVBMediaAddon::FreeDeviceList()
250 {
251 	device_info *dev;
252 	while ((dev = (device_info *)fDeviceList.RemoveItem((int32)0))) {
253 		delete dev->card;
254 		delete dev;
255 	}
256 }
257