BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / add-ons / media / media-add-ons / video_mixer / VideoMixerNodeConsumer.cpp
blob9fbedb45c6f568ba6a254407a905862d731b28eb
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
8 * takes in multiple video streams and supplies
9 * a single stream as the output.
10 * each stream is converted to the same colourspace
13 #include "VideoMixerNode.h"
15 #include <stdio.h>
18 // -------------------------------------------------------- //
19 // implemention of BBufferConsumer
20 // -------------------------------------------------------- //
22 // Check to make sure the format is okay, then remove
23 // any wildcards corresponding to our requirements.
24 status_t VideoMixerNode::AcceptFormat(
25 const media_destination &dest,
26 media_format *format)
28 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::AcceptFormat\n");
30 if (fInitialInput.destination != dest) {
31 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION");
32 return B_MEDIA_BAD_DESTINATION; // none of our inputs matched the dest
35 media_format myFormat;
37 GetInputFormat(&myFormat);
39 AddRequirements(format);
41 return B_OK;
44 status_t VideoMixerNode::GetNextInput(
45 int32 *cookie,
46 media_input *out_input)
48 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::GetNextInput (%ld)\n",*cookie);
50 // Cookie 0 is the connecting input, all others are connected inputs
51 if (uint32(*cookie) == fConnectedInputs.size()) {
52 *out_input = fInitialInput;
53 } else {
54 out_input = GetInput(*cookie);
56 if (out_input == NULL) {
57 fprintf(stderr,"<- B_ERROR (no more inputs)\n");
58 return B_ERROR;
62 // so next time they won't get the same input again
63 (*cookie)++;
65 return B_OK;
68 void VideoMixerNode::DisposeInputCookie(
69 int32 cookie)
71 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::DisposeInputCookie\n");
72 // nothing to do since our cookies are just integers
75 void VideoMixerNode::BufferReceived(BBuffer *buffer)
77 switch (buffer->Header()->type) {
78 // case B_MEDIA_PARAMETERS:
79 // {
80 // status_t status = ApplyParameterData(buffer->Data(),buffer->SizeUsed());
81 // if (status != B_OK) {
82 // fprintf(stderr,"ApplyParameterData in MediaDemultiplexerNode::BufferReceived failed\n");
83 // }
84 // buffer->Recycle();
85 // }
86 // break;
87 case B_MEDIA_RAW_VIDEO:
88 if (buffer->Flags() & BBuffer::B_SMALL_BUFFER) {
89 fprintf(stderr,"NOT IMPLEMENTED: B_SMALL_BUFFER in VideoMixerNode::BufferReceived\n");
90 // XXX: implement this part
91 buffer->Recycle();
92 } else {
93 media_timed_event event(buffer->Header()->start_time, BTimedEventQueue::B_HANDLE_BUFFER,
94 buffer, BTimedEventQueue::B_RECYCLE_BUFFER);
95 status_t status = EventQueue()->AddEvent(event);
96 if (status != B_OK) {
97 fprintf(stderr,"EventQueue()->AddEvent(event) in VideoMixerNode::BufferReceived failed\n");
98 buffer->Recycle();
101 break;
102 default:
103 fprintf(stderr,"unexpected buffer type in VideoMixerNode::BufferReceived\n");
104 buffer->Recycle();
105 break;
109 void VideoMixerNode::ProducerDataStatus(
110 const media_destination &for_whom,
111 int32 status,
112 bigtime_t at_performance_time)
114 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::ProducerDataStatus\n");
115 media_input *input = GetInput(for_whom);
117 if (input == NULL) {
118 fprintf(stderr,"invalid destination received in VideoMixerNode::ProducerDataStatus\n");
119 return;
122 media_timed_event event(at_performance_time, BTimedEventQueue::B_DATA_STATUS,
123 &input, BTimedEventQueue::B_NO_CLEANUP, status, 0, NULL);
124 EventQueue()->AddEvent(event);
127 status_t VideoMixerNode::GetLatencyFor(
128 const media_destination &for_whom,
129 bigtime_t *out_latency,
130 media_node_id *out_timesource)
132 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::GetLatencyFor\n");
133 if ((out_latency == 0) || (out_timesource == 0)) {
134 fprintf(stderr,"<- B_BAD_VALUE\n");
135 return B_BAD_VALUE;
138 media_input *input = GetInput(for_whom);
140 if (input == NULL) {
141 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
142 return B_MEDIA_BAD_DESTINATION;
145 *out_latency = EventLatency();
146 *out_timesource = TimeSource()->ID();
148 return B_OK;
151 status_t VideoMixerNode::Connected(
152 const media_source &producer, /* here's a good place to request buffer group usage */
153 const media_destination &where,
154 const media_format &with_format,
155 media_input *out_input)
157 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::Connected\n");
159 if (fInitialInput.destination != where) {
160 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
161 return B_MEDIA_BAD_DESTINATION;
164 media_input *input = CreateInput(fConnectedInputs.size());
165 fConnectedInputs.push_back(input);
167 // Specialise the output?
169 // compute the latency or just guess
170 fInternalLatency = 500; // just a guess
171 fprintf(stderr," internal latency guessed = %lld\n", fInternalLatency);
173 SetEventLatency(fInternalLatency);
175 // record the agreed upon values
176 input->destination = where;
177 input->source = producer;
178 input->format = with_format;
180 *out_input = *input;
182 // Reset the Initial Input
183 ClearInput(&fInitialInput);
184 fInitialInput.destination.id = fConnectedInputs.size();
185 fInitialInput.destination.port = ControlPort();
187 return B_OK;
190 void VideoMixerNode::Disconnected(
191 const media_source &producer,
192 const media_destination &where)
194 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::Disconnected\n");
196 media_input *input = GetInput(where);
198 if (input == NULL) {
199 fprintf(stderr,"<- B_MEDIA_BAD_DESTINATION\n");
200 return;
203 if (input->source != producer) {
204 fprintf(stderr,"<- B_MEDIA_BAD_SOURCE\n");
205 return;
208 bufferMixer.RemoveBuffer(input->destination.id);
210 // disconnected but not deleted (important)
211 input->source = media_source::null;
212 GetInputFormat(&input->format);
215 /* The notification comes from the upstream producer, so he's already cool with */
216 /* the format; you should not ask him about it in here. */
217 status_t VideoMixerNode::FormatChanged(
218 const media_source & producer,
219 const media_destination & consumer,
220 int32 change_tag,
221 const media_format & format)
223 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::FormatChanged\n");
225 media_input *input = GetInput(producer);
227 if (input == NULL) {
228 return B_MEDIA_BAD_SOURCE;
231 if (input->destination != consumer) {
232 return B_MEDIA_BAD_DESTINATION;
235 input->format = format;
236 return B_OK;
239 /* Given a performance time of some previous buffer, retrieve the remembered tag */
240 /* of the closest (previous or exact) performance time. Set *out_flags to 0; the */
241 /* idea being that flags can be added later, and the understood flags returned in */
242 /* *out_flags. */
243 status_t VideoMixerNode::SeekTagRequested(
244 const media_destination & destination,
245 bigtime_t in_target_time,
246 uint32 in_flags,
247 media_seek_tag * out_seek_tag,
248 bigtime_t * out_tagged_time,
249 uint32 * out_flags)
251 fprintf(stderr,"VideoMixerNode(BBufferConsumer)::SeekTagRequested\n");
252 // XXX: implement this
253 return BBufferConsumer::SeekTagRequested(destination,in_target_time, in_flags,
254 out_seek_tag, out_tagged_time, out_flags);