xref: /haiku/src/kits/media/MediaRecorderNode.cpp (revision 894526b51a3d931c423878fc0eb8da610fa1fb2a)
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