1 /* 2 * Copyright 2014, Dario Casalinuovo 3 * Copyright 1999, Be Incorporated 4 * All Rights Reserved. 5 * This file may be used under the terms of the Be Sample Code License. 6 */ 7 8 9 #include "MediaRecorderNode.h" 10 11 #include <Buffer.h> 12 #include <scheduler.h> 13 #include <TimedEventQueue.h> 14 #include <TimeSource.h> 15 16 #include <MediaDebug.h> 17 #include <MediaRecorder.h> 18 19 20 BMediaRecorderNode::BMediaRecorderNode(const char* name, 21 BMediaRecorder* recorder, media_type type) 22 : 23 BMediaNode(name), 24 BMediaEventLooper(), 25 BBufferConsumer(type), 26 fRecorder(recorder) 27 { 28 CALLED(); 29 30 fInput.destination.id = 1; 31 fInput.destination.port = ControlPort(); 32 33 fName.SetTo(name); 34 35 BString str(name); 36 str << " Input"; 37 strcpy(fInput.name, str.String()); 38 } 39 40 41 BMediaRecorderNode::~BMediaRecorderNode() 42 { 43 CALLED(); 44 } 45 46 47 BMediaAddOn* 48 BMediaRecorderNode::AddOn(int32* id) const 49 { 50 CALLED(); 51 52 if (id) 53 *id = -1; 54 55 return NULL; 56 } 57 58 59 void 60 BMediaRecorderNode::NodeRegistered() 61 { 62 CALLED(); 63 Run(); 64 } 65 66 67 void 68 BMediaRecorderNode::SetRunMode(run_mode mode) 69 { 70 CALLED(); 71 72 int32 priority; 73 74 if (mode == BMediaNode::B_OFFLINE) 75 priority = B_OFFLINE_PROCESSING; 76 else { 77 switch(ConsumerType()) { 78 case B_MEDIA_RAW_AUDIO: 79 case B_MEDIA_ENCODED_AUDIO: 80 priority = B_AUDIO_RECORDING; 81 break; 82 83 case B_MEDIA_RAW_VIDEO: 84 case B_MEDIA_ENCODED_VIDEO: 85 priority = B_VIDEO_RECORDING; 86 break; 87 88 default: 89 priority = B_DEFAULT_MEDIA_PRIORITY; 90 } 91 } 92 93 SetPriority(suggest_thread_priority(priority)); 94 95 BMediaNode::SetRunMode(mode); 96 } 97 98 99 void 100 BMediaRecorderNode::SetAcceptedFormat(const media_format& format) 101 { 102 CALLED(); 103 104 fOKFormat = format; 105 } 106 107 108 status_t 109 BMediaRecorderNode::GetInput(media_input* outInput) 110 { 111 CALLED(); 112 113 fInput.node = Node(); 114 *outInput = fInput; 115 116 return B_OK; 117 } 118 119 120 void 121 BMediaRecorderNode::SetDataEnabled(bool enabled) 122 { 123 CALLED(); 124 125 int32 tag; 126 127 SetOutputEnabled(fInput.source, 128 fInput.destination, enabled, NULL, &tag); 129 } 130 131 132 void 133 BMediaRecorderNode::HandleEvent(const media_timed_event* event, 134 bigtime_t lateness, bool realTimeEvent) 135 { 136 CALLED(); 137 138 // we ignore them all! 139 } 140 141 142 void 143 BMediaRecorderNode::Start(bigtime_t performanceTime) 144 { 145 CALLED(); 146 147 if (fRecorder->fNotifyHook) 148 (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, 149 BMediaRecorder::B_WILL_START, performanceTime); 150 151 fRecorder->fRunning = true; 152 } 153 154 155 void 156 BMediaRecorderNode::Stop(bigtime_t performanceTime, bool immediate) 157 { 158 CALLED(); 159 160 if (fRecorder->fNotifyHook) 161 (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, 162 BMediaRecorder::B_WILL_STOP, performanceTime, immediate); 163 164 fRecorder->fRunning = false; 165 } 166 167 168 void 169 BMediaRecorderNode::Seek(bigtime_t mediaTime, bigtime_t performanceTime) 170 { 171 CALLED(); 172 173 if (fRecorder->fNotifyHook) 174 (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, 175 BMediaRecorder::B_WILL_SEEK, performanceTime, mediaTime); 176 } 177 178 179 void 180 BMediaRecorderNode::TimeWarp(bigtime_t realTime, bigtime_t performanceTime) 181 { 182 CALLED(); 183 184 // Since buffers will come pre-time-stamped, we only need to look 185 // at them, so we can ignore the time warp as a consumer. 186 if (fRecorder->fNotifyHook) 187 (*fRecorder->fNotifyHook)(fRecorder->fBufferCookie, 188 BMediaRecorder::B_WILL_TIMEWARP, realTime, performanceTime); 189 } 190 191 192 status_t 193 BMediaRecorderNode::HandleMessage(int32 message, 194 const void* data, size_t size) 195 { 196 CALLED(); 197 198 if (BBufferConsumer::HandleMessage(message, data, size) < 0 199 && BMediaEventLooper::HandleMessage(message, data, size) < 0 200 && BMediaNode::HandleMessage(message, data, size) < 0) { 201 HandleBadMessage(message, data, size); 202 return B_ERROR; 203 } 204 return B_OK; 205 } 206 207 208 status_t 209 BMediaRecorderNode::AcceptFormat(const media_destination& dest, 210 media_format* format) 211 { 212 CALLED(); 213 214 if (format_is_compatible(*format, fOKFormat)) 215 return B_OK; 216 217 *format = fOKFormat; 218 219 return B_MEDIA_BAD_FORMAT; 220 } 221 222 223 status_t 224 BMediaRecorderNode::GetNextInput(int32* cookie, media_input* outInput) 225 { 226 CALLED(); 227 228 if (*cookie == 0) { 229 *cookie = -1; 230 *outInput = fInput; 231 return B_OK; 232 } 233 234 return B_BAD_INDEX; 235 } 236 237 238 void 239 BMediaRecorderNode::DisposeInputCookie(int32 cookie) 240 { 241 CALLED(); 242 } 243 244 245 void 246 BMediaRecorderNode::BufferReceived(BBuffer* buffer) 247 { 248 CALLED(); 249 250 fRecorder->BufferReceived(buffer->Data(), buffer->SizeUsed(), 251 *buffer->Header()); 252 253 buffer->Recycle(); 254 } 255 256 257 void 258 BMediaRecorderNode::ProducerDataStatus( 259 const media_destination& forWhom, int32 status, 260 bigtime_t performanceTime) 261 { 262 CALLED(); 263 } 264 265 266 status_t 267 BMediaRecorderNode::GetLatencyFor(const media_destination& forWhom, 268 bigtime_t* outLatency, media_node_id* outTimesource) 269 { 270 CALLED(); 271 272 *outLatency = 0; 273 *outTimesource = TimeSource()->ID(); 274 275 return B_OK; 276 } 277 278 279 status_t 280 BMediaRecorderNode::Connected(const media_source &producer, 281 const media_destination &where, const media_format &withFormat, 282 media_input* outInput) 283 { 284 CALLED(); 285 286 fInput.source = producer; 287 fInput.format = withFormat; 288 *outInput = fInput; 289 290 fRecorder->fConnected = true; 291 fRecorder->fInput = fInput; 292 293 return B_OK; 294 } 295 296 297 void 298 BMediaRecorderNode::Disconnected(const media_source& producer, 299 const media_destination& where) 300 { 301 CALLED(); 302 303 fInput.source = media_source::null; 304 305 fRecorder->fConnected = false; 306 307 fRecorder->fInput.format = fOKFormat; 308 } 309 310 311 status_t 312 BMediaRecorderNode::FormatChanged(const media_source& producer, 313 const media_destination& consumer, int32 tag, 314 const media_format& format) 315 { 316 CALLED(); 317 318 if (!format_is_compatible(format, fOKFormat)) 319 return B_MEDIA_BAD_FORMAT; 320 321 fInput.format = format; 322 323 return B_OK; 324 } 325