1/* 2 * Copyright 2004-2008, Fran��ois Revol, <revol@free.fr>. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include <support/Autolock.h> 7#include <media/MediaFormats.h> 8 9#include <stdio.h> 10#include <string.h> 11#include <unistd.h> 12 13#include "AddOn.h" 14#include "Producer.h" 15#include "CamRoster.h" 16#include "CamDebug.h" 17#include "CamDevice.h" 18 19 20WebCamMediaAddOn::WebCamMediaAddOn(image_id imid) 21 : BMediaAddOn(imid), 22 fInitStatus(B_NO_INIT), 23 fRoster(NULL) 24{ 25 PRINT((CH "()" CT)); 26 fInternalIDCounter = 0; 27 /* Customize these parameters to match those of your node */ 28 fMediaFormat.type = B_MEDIA_RAW_VIDEO; 29 fMediaFormat.u.raw_video = media_raw_video_format::wildcard; 30 fMediaFormat.u.raw_video.interlace = 1; 31 fMediaFormat.u.raw_video.display.format = B_RGB32; 32 FillDefaultFlavorInfo(&fDefaultFlavorInfo); 33 34 fRoster = new CamRoster(this); 35 fRoster->Start(); 36// if( fRoster->CountCameras() < 1 ) 37/* fInitStatus = B_ERROR; 38 else 39*/ 40 fInitStatus = B_OK; 41} 42 43 44WebCamMediaAddOn::~WebCamMediaAddOn() 45{ 46 fRoster->Stop(); 47 delete fRoster; 48} 49 50 51status_t 52WebCamMediaAddOn::InitCheck(const char **out_failure_text) 53{ 54 if (fInitStatus < B_OK) { 55 *out_failure_text = "No cameras attached"; 56 return fInitStatus; 57 } 58 59 return B_OK; 60} 61 62 63int32 64WebCamMediaAddOn::CountFlavors() 65{ 66 PRINT((CH "()" CT)); 67 int32 count; 68 if (!fRoster) 69 return B_NO_INIT; 70 if (fInitStatus < B_OK) 71 return fInitStatus; 72 73 /* This addon only supports a single flavor, as defined in the 74 * constructor */ 75 count = fRoster->CountCameras(); 76 return count;//(count > 0)?count:1;//1; 77} 78 79 80/* 81 * The pointer to the flavor received only needs to be valid between 82 * successive calls to BMediaAddOn::GetFlavorAt(). 83 */ 84status_t 85WebCamMediaAddOn::GetFlavorAt(int32 n, const flavor_info **out_info) 86{ 87 PRINT((CH "(%d, ) roster %p is %" B_PRIx32 CT, n, fRoster, fInitStatus)); 88 int32 count; 89 CamDevice* cam; 90 if (!fRoster) 91 return B_NO_INIT; 92 if (fInitStatus < B_OK) 93 return fInitStatus; 94 95 count = fRoster->CountCameras(); 96 PRINT((CH ": %d cameras" CT, count)); 97 if (n >= count)//(n != 0) 98 return B_BAD_INDEX; 99 100 fRoster->Lock(); 101 cam = fRoster->CameraAt(n); 102 *out_info = &fDefaultFlavorInfo; 103 if (cam && cam->FlavorInfo()) 104 *out_info = cam->FlavorInfo(); 105 fRoster->Unlock(); 106 PRINT((CH ": returning flavor for %d, internal_id %d" CT, n, (*out_info)->internal_id)); 107 return B_OK; 108} 109 110 111BMediaNode * 112WebCamMediaAddOn::InstantiateNodeFor( 113 const flavor_info *info, BMessage* /*_config*/, status_t* /*_out_error*/) 114{ 115 PRINT((CH "()" CT)); 116 VideoProducer *node; 117 CamDevice *cam=NULL; 118 119 if (fInitStatus < B_OK) 120 return NULL; 121 122 fRoster->Lock(); 123 for (uint32 i = 0; i < fRoster->CountCameras(); i++) { 124 CamDevice *c; 125 c = fRoster->CameraAt(i); 126 PRINT((CH ": cam[%d]: %d, %s" CT, i, c->FlavorInfo()->internal_id, c->BrandName())); 127 if (c && (c->FlavorInfo()->internal_id == info->internal_id)) { 128 cam = c; 129 break; 130 } 131 } 132 fRoster->Unlock(); 133 if (!cam) 134 return NULL; 135 136#if 0 137 fRoster->Lock(); 138 cam = fRoster->CameraAt(n); 139 *out_info = &fDefaultFlavorInfo; 140 if (cam && cam->FlavorInfo()) 141 *out_info = cam->FlavorInfo(); 142 fRoster->Unlock(); 143#endif 144 /* At most one instance of the node should be instantiated at any given 145 * time. The locking for this restriction may be found in the VideoProducer 146 * class. */ 147 node = new VideoProducer(this, cam, cam->FlavorInfo()->name, cam->FlavorInfo()->internal_id); 148 if (node && (node->InitCheck() < B_OK)) { 149 delete node; 150 node = NULL; 151 } 152 153 return node; 154} 155 156 157status_t 158WebCamMediaAddOn::CameraAdded(CamDevice* device) 159{ 160 PRINT((CH "()" CT)); 161 NotifyFlavorChange(); 162 return B_OK; 163} 164 165 166status_t 167WebCamMediaAddOn::CameraRemoved(CamDevice* device) 168{ 169 PRINT((CH "()" CT)); 170 NotifyFlavorChange(); 171 return B_OK; 172} 173 174 175void 176WebCamMediaAddOn::FillDefaultFlavorInfo(flavor_info* info) 177{ 178 info->name = (char *)"USB Web Camera"; 179 info->info = (char *)"USB Web Camera"; 180 info->kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT; 181 info->flavor_flags = 0;//B_FLAVOR_IS_GLOBAL; 182 info->internal_id = atomic_add((int32*)&fInternalIDCounter, 1); 183 info->possible_count = 1;//0; 184 info->in_format_count = 0; 185 info->in_format_flags = 0; 186 info->in_formats = NULL; 187 info->out_format_count = 1; 188 info->out_format_flags = 0; 189 info->out_formats = &fMediaFormat; 190} 191 192 193BMediaAddOn * 194make_media_addon(image_id id) 195{ 196 return new WebCamMediaAddOn(id); 197} 198