BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / add-ons / media / media-add-ons / video_mixer / VideoMixerNode.cpp
blobe85e125340ee7149e70ffeefab2b4550a2267af4
1 /*
2 * Copyright (C) 2009-2010 David McPaul
4 * All rights reserved. Distributed under the terms of the MIT License.
5 * VideoMixerNode.cpp
7 * The VideoMixerNode class takes in multiple video streams and supplies
8 * a single stream as the output.
9 * each stream is converted to the same colourspace and should match
10 * either the primary input OR the requested colourspace from the output
11 * destination.
13 * The first input is considered the primary input
14 * subsequent input framesize should match the primary input framesize
15 * The output framerate will be the same as the primary input
19 #include <stdio.h>
20 #include <string.h>
22 #include "VideoMixerNode.h"
24 using std::vector;
26 VideoMixerNode::~VideoMixerNode(void)
28 fprintf(stderr,"VideoMixerNode::~VideoMixerNode\n");
29 // Stop the BMediaEventLooper thread
30 Quit();
33 VideoMixerNode::VideoMixerNode(
34 const flavor_info *info,
35 BMessage *config,
36 BMediaAddOn *addOn)
37 : BMediaNode("VideoMixerNode"),
38 BBufferConsumer(B_MEDIA_RAW_VIDEO), // Raw video buffers in
39 BBufferProducer(B_MEDIA_RAW_VIDEO), // Raw video buffers out
40 BMediaEventLooper()
42 fprintf(stderr,"VideoMixerNode::VideoMixerNode\n");
43 // keep our creator around for AddOn calls later
44 fAddOn = addOn;
45 // NULL out our latency estimates
46 fDownstreamLatency = 0;
47 fInternalLatency = 0;
49 // Start with 1 input and 1 output
50 ClearInput(&fInitialInput);
52 strncpy(fOutput.name,"VideoMixer Output", B_MEDIA_NAME_LENGTH-1);
53 fOutput.name[B_MEDIA_NAME_LENGTH-1] = '\0';
55 // initialize the output
56 fOutput.node = media_node::null; // until registration
57 fOutput.destination = media_destination::null;
58 fOutput.source.port = ControlPort();
59 fOutput.source.id = 0;
61 GetOutputFormat(&fOutput.format);
63 fInitCheckStatus = B_OK;
66 void VideoMixerNode::NodeRegistered(void)
68 fprintf(stderr,"VideoMixerNode::NodeRegistered\n");
70 // for every node created so far set to this Node;
71 for (uint32 i=0;i<fConnectedInputs.size();i++) {
72 fConnectedInputs[i]->node = Node();
73 fConnectedInputs[i]->destination.id = i;
74 fConnectedInputs[i]->destination.port = ControlPort();
77 fInitialInput.node = Node();
78 fInitialInput.destination.id = fConnectedInputs.size();
79 fInitialInput.destination.port = ControlPort();
81 GetOutputFormat(&fOutput.format);
82 fOutput.node = Node();
84 // start the BMediaEventLooper thread
85 SetPriority(B_REAL_TIME_PRIORITY);
86 Run();
89 media_input *
90 VideoMixerNode::CreateInput(uint32 inputID) {
91 media_input *input = new media_input();
93 ClearInput(input);
95 // don't overwrite available space, and be sure to terminate
96 sprintf(input->name, "VideoMixer Input %ld", inputID);
98 return input;
101 void
102 VideoMixerNode::ClearInput(media_input *input) {
104 // initialize the input
105 sprintf(input->name, "VideoMixer Input");
106 input->node = Node();
107 input->source = media_source::null;
108 input->destination = media_destination::null;
110 GetInputFormat(&input->format);
113 media_input *
114 VideoMixerNode::GetInput(const media_source &source) {
116 vector<media_input *>::iterator each;
118 for (each=fConnectedInputs.begin(); each<fConnectedInputs.end(); each++) {
119 if ((*each)->source == source) {
120 return *each;
124 return NULL;
127 media_input *
128 VideoMixerNode::GetInput(const media_destination &destination) {
130 vector<media_input *>::iterator each;
132 for (each=fConnectedInputs.begin(); each<fConnectedInputs.end(); each++) {
133 if ((*each)->destination == destination) {
134 return *each;
138 return NULL;
141 media_input *
142 VideoMixerNode::GetInput(const int32 id) {
144 vector<media_input *>::iterator each;
146 for (each=fConnectedInputs.begin(); each<fConnectedInputs.end(); each++) {
147 if ((*each)->destination.id == id) {
148 return *each;
152 return NULL;
155 status_t VideoMixerNode::InitCheck(void) const
157 fprintf(stderr,"VideoMixerNode::InitCheck\n");
158 return fInitCheckStatus;
161 status_t VideoMixerNode::GetConfigurationFor(
162 BMessage *into_message)
164 fprintf(stderr,"VideoMixerNode::GetConfigurationFor\n");
165 return B_OK;
168 // -------------------------------------------------------- //
169 // implementation of BMediaNode
170 // -------------------------------------------------------- //
172 BMediaAddOn *VideoMixerNode::AddOn(
173 int32 *internal_id) const
175 fprintf(stderr,"VideoMixerNode::AddOn\n");
176 // BeBook says this only gets called if we were in an add-on.
177 if (fAddOn != NULL) {
178 // If we get a null pointer then we just won't write.
179 if (internal_id != NULL) {
180 internal_id = 0;
183 return fAddOn;
186 void VideoMixerNode::Start(bigtime_t performance_time)
188 fprintf(stderr,"VideoMixerNode::Start(pt=%lld)\n", performance_time);
189 BMediaEventLooper::Start(performance_time);
192 void VideoMixerNode::Stop(
193 bigtime_t performance_time,
194 bool immediate)
196 if (immediate) {
197 fprintf(stderr,"VideoMixerNode::Stop(pt=%lld,<immediate>)\n", performance_time);
198 } else {
199 fprintf(stderr,"VideoMixerNode::Stop(pt=%lld,<scheduled>)\n", performance_time);
201 BMediaEventLooper::Stop(performance_time, immediate);
204 void VideoMixerNode::Seek(
205 bigtime_t media_time,
206 bigtime_t performance_time)
208 fprintf(stderr,"VideoMixerNode::Seek(mt=%lld,pt=%lld)\n", media_time,performance_time);
209 BMediaEventLooper::Seek(media_time, performance_time);
212 void VideoMixerNode::SetRunMode(run_mode mode)
214 fprintf(stderr,"VideoMixerNode::SetRunMode(%i)\n", mode);
215 BMediaEventLooper::SetRunMode(mode);
218 void VideoMixerNode::TimeWarp(
219 bigtime_t at_real_time,
220 bigtime_t to_performance_time)
222 fprintf(stderr,"VideoMixerNode::TimeWarp(rt=%lld,pt=%lld)\n", at_real_time, to_performance_time);
223 BMediaEventLooper::TimeWarp(at_real_time, to_performance_time);
226 void VideoMixerNode::Preroll(void)
228 fprintf(stderr,"VideoMixerNode::Preroll\n");
229 // XXX:Performance opportunity
230 BMediaNode::Preroll();
233 void VideoMixerNode::SetTimeSource(BTimeSource *time_source)
235 fprintf(stderr,"VideoMixerNode::SetTimeSource\n");
236 BMediaNode::SetTimeSource(time_source);
239 status_t VideoMixerNode::HandleMessage(
240 int32 message,
241 const void *data,
242 size_t size)
244 fprintf(stderr,"VideoMixerNode::HandleMessage\n");
245 status_t status = B_OK;
246 switch (message) {
247 // no special messages for now
248 default:
249 status = BBufferConsumer::HandleMessage(message, data, size);
250 if (status == B_OK) {
251 break;
253 status = BBufferProducer::HandleMessage(message, data, size);
254 if (status == B_OK) {
255 break;
257 status = BMediaNode::HandleMessage(message, data, size);
258 if (status == B_OK) {
259 break;
261 BMediaNode::HandleBadMessage(message, data, size);
262 status = B_ERROR;
263 break;
265 return status;
268 status_t VideoMixerNode::RequestCompleted(const media_request_info &info)
270 fprintf(stderr,"VideoMixerNode::RequestCompleted\n");
271 return BMediaNode::RequestCompleted(info);
274 status_t VideoMixerNode::DeleteHook(BMediaNode *node)
276 fprintf(stderr,"VideoMixerNode::DeleteHook\n");
277 return BMediaEventLooper::DeleteHook(node);
280 status_t VideoMixerNode::GetNodeAttributes(
281 media_node_attribute *outAttributes,
282 size_t inMaxCount)
284 fprintf(stderr,"VideoMixerNode::GetNodeAttributes\n");
285 return BMediaNode::GetNodeAttributes(outAttributes, inMaxCount);
288 status_t VideoMixerNode::AddTimer(
289 bigtime_t at_performance_time,
290 int32 cookie)
292 fprintf(stderr,"VideoMixerNode::AddTimer\n");
293 return BMediaEventLooper::AddTimer(at_performance_time, cookie);
296 // -------------------------------------------------------- //
297 // VideoMixerNode specific functions
298 // -------------------------------------------------------- //
300 // public:
302 void VideoMixerNode::GetFlavor(flavor_info *outInfo, int32 id)
304 fprintf(stderr,"VideoMixerNode::GetFlavor\n");
306 if (outInfo != NULL) {
307 outInfo->internal_id = id;
308 strcpy(outInfo->name, "Haiku VideoMixer");
309 strcpy(outInfo->info, "A VideoMixerNode node mixes multiple video"
310 " streams into a single stream.");
311 outInfo->kinds = B_BUFFER_CONSUMER | B_BUFFER_PRODUCER;
312 outInfo->flavor_flags = B_FLAVOR_IS_LOCAL;
313 outInfo->possible_count = INT_MAX; // no limit
314 outInfo->in_format_count = 1;
315 media_format *inFormats = new media_format[outInfo->in_format_count];
316 GetInputFormat(&inFormats[0]);
317 outInfo->in_formats = inFormats;
318 outInfo->out_format_count = 1; // single output
319 media_format *outFormats = new media_format[outInfo->out_format_count];
320 GetOutputFormat(&outFormats[0]);
321 outInfo->out_formats = outFormats;
325 void VideoMixerNode::GetInputFormat(media_format *outFormat)
327 fprintf(stderr,"VideoMixerNode::GetInputFormat\n");
329 if (outFormat != NULL) {
330 outFormat->type = B_MEDIA_RAW_VIDEO;
331 outFormat->require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
332 outFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
333 outFormat->u.raw_video = media_raw_video_format::wildcard;
337 void VideoMixerNode::GetOutputFormat(media_format *outFormat)
339 fprintf(stderr,"VideoMixerNode::GetOutputFormat\n");
340 if (outFormat != NULL) {
341 outFormat->type = B_MEDIA_RAW_VIDEO;
342 outFormat->require_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
343 outFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
344 outFormat->u.raw_video = media_raw_video_format::wildcard;
348 // protected:
350 status_t VideoMixerNode::AddRequirements(media_format *format)
352 fprintf(stderr,"VideoMixerNode::AddRequirements\n");
353 return B_OK;