1/* 2 * FireWire DV media addon for Haiku 3 * 4 * Copyright (c) 2008, JiSheng Zhang (jszhang3@mail.ustc.edu.cn) 5 * Distributed under the terms of the MIT License. 6 * 7 * Based on DVB media addon 8 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de> 9 */ 10 11#include "FireWireDVAddOn.h" 12#include "FireWireCard.h" 13#include "FireWireDVNode.h" 14 15#include <stdio.h> 16#include <string.h> 17#include <time.h> 18 19#include <Alert.h> 20#include <Directory.h> 21#include <Entry.h> 22#include <Path.h> 23 24#include "debug.h" 25 26struct device_info 27{ 28 FireWireCard* card; 29 char name[16]; 30 media_format in_formats[1]; 31 media_format out_formats[1]; 32 flavor_info flavor; 33}; 34 35extern "C" BMediaAddOn* 36make_media_addon(image_id id) 37{ 38 CALLED(); 39 return new FireWireDVAddOn(id); 40} 41 42 43FireWireDVAddOn::FireWireDVAddOn(image_id id) 44 : BMediaAddOn(id) 45{ 46 CALLED(); 47 ScanFolder("/dev/bus/fw"); 48} 49 50 51FireWireDVAddOn::~FireWireDVAddOn() 52{ 53 CALLED(); 54 FreeDeviceList(); 55} 56 57 58status_t 59FireWireDVAddOn::InitCheck(const char** out_failure_text) 60{ 61 CALLED(); 62 if (!fDeviceList.CountItems()) { 63 *out_failure_text = "No supported device found"; 64 return B_ERROR; 65 } 66 return B_OK; 67} 68 69 70int32 71FireWireDVAddOn::CountFlavors() 72{ 73 CALLED(); 74 return fDeviceList.CountItems(); 75} 76 77 78status_t 79FireWireDVAddOn::GetFlavorAt(int32 n, const flavor_info** out_info) 80{ 81 CALLED(); 82 device_info* dev = fDeviceList.ItemAt(n); 83 if (!dev) 84 return B_ERROR; 85 *out_info = &dev->flavor; 86 return B_OK; 87} 88 89 90BMediaNode * 91FireWireDVAddOn::InstantiateNodeFor(const flavor_info* info, BMessage* config, 92 status_t* out_error) 93{ 94 CALLED(); 95 device_info* dev = fDeviceList.ItemAt(info->internal_id); 96 if (!dev || dev->flavor.internal_id != info->internal_id) { 97 *out_error = B_ERROR; 98 return NULL; 99 } 100 *out_error = B_OK; 101 102 return new FireWireDVNode(this, dev->name, dev->flavor.internal_id, 103 dev->card); 104} 105 106 107bool 108FireWireDVAddOn::WantsAutoStart() 109{ 110 CALLED(); 111 return false; 112} 113 114 115status_t 116FireWireDVAddOn::AutoStart(int index, BMediaNode** outNode, 117 int32* outInternalID, bool* outHasMore) 118{ 119 CALLED(); 120 return B_ERROR; 121} 122 123 124void 125FireWireDVAddOn::ScanFolder(const char* path) 126{ 127 CALLED(); 128 BDirectory dir(path); 129 if (dir.InitCheck() != B_OK) 130 return; 131 132 BEntry ent; 133 134 while (dir.GetNextEntry(&ent) == B_OK) { 135 BPath path(&ent); 136 if (!ent.IsDirectory() && !ent.IsSymLink()) { 137 FireWireCard *card = new FireWireCard(path.Path()); 138 if (card->InitCheck() == B_OK) 139 AddDevice(card, path.Path()); 140 else 141 delete card; 142 } 143 } 144} 145 146 147void 148FireWireDVAddOn::AddDevice(FireWireCard* card, const char* path) 149{ 150 const char* fwnumber; 151 152 // get card name, info and type 153 154 // get interface number 155 const char *p = strrchr(path, '/'); 156 fwnumber = p ? p + 1 : ""; 157 158 // create device_info 159 device_info *dev = new device_info; 160 fDeviceList.AddItem(dev); 161 162 dev->card = card; 163 164 sprintf(dev->name, "FireWire-%s", fwnumber); 165 166 // setup supported formats (the lazy way) 167 memset(dev->in_formats, 0, sizeof(dev->in_formats)); 168 memset(dev->out_formats, 0, sizeof(dev->out_formats)); 169 dev->in_formats[0].type = B_MEDIA_ENCODED_VIDEO; 170 dev->out_formats[0].type = B_MEDIA_ENCODED_VIDEO; 171 172 // setup flavor info 173 dev->flavor.name = dev->name; 174 dev->flavor.info = (char *)"The FireWireDVNode outputs to fw_raw drivers."; 175 dev->flavor.kinds = B_BUFFER_CONSUMER | B_BUFFER_PRODUCER 176 | B_CONTROLLABLE | B_PHYSICAL_OUTPUT | B_PHYSICAL_INPUT; 177 dev->flavor.flavor_flags = B_FLAVOR_IS_GLOBAL; 178 dev->flavor.internal_id = fDeviceList.CountItems() - 1; 179 dev->flavor.possible_count = 1; 180 dev->flavor.in_format_count = 1; 181 dev->flavor.in_format_flags = 0; 182 dev->flavor.in_formats = dev->in_formats; 183 dev->flavor.out_format_count = 1; 184 dev->flavor.out_format_flags = 0; 185 dev->flavor.out_formats = dev->out_formats; 186} 187 188 189void 190FireWireDVAddOn::FreeDeviceList() 191{ 192 device_info* dev; 193 while ((dev = fDeviceList.RemoveItemAt(0L))) { 194 delete dev->card; 195 delete dev; 196 } 197} 198 199