1255a01c7Sbeveloper /* 2255a01c7Sbeveloper * Copyright (c) 2002, 2003 Marcus Overhagen <Marcus@Overhagen.de> 3255a01c7Sbeveloper * 4255a01c7Sbeveloper * Permission is hereby granted, free of charge, to any person obtaining 5255a01c7Sbeveloper * a copy of this software and associated documentation files or portions 6255a01c7Sbeveloper * thereof (the "Software"), to deal in the Software without restriction, 7255a01c7Sbeveloper * including without limitation the rights to use, copy, modify, merge, 8255a01c7Sbeveloper * publish, distribute, sublicense, and/or sell copies of the Software, 9255a01c7Sbeveloper * and to permit persons to whom the Software is furnished to do so, subject 10255a01c7Sbeveloper * to the following conditions: 11255a01c7Sbeveloper * 12255a01c7Sbeveloper * * Redistributions of source code must retain the above copyright notice, 13255a01c7Sbeveloper * this list of conditions and the following disclaimer. 14255a01c7Sbeveloper * 15255a01c7Sbeveloper * * Redistributions in binary form must reproduce the above copyright notice 16255a01c7Sbeveloper * in the binary, as well as this list of conditions and the following 17255a01c7Sbeveloper * disclaimer in the documentation and/or other materials provided with 18255a01c7Sbeveloper * the distribution. 19255a01c7Sbeveloper * 20255a01c7Sbeveloper * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21255a01c7Sbeveloper * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22255a01c7Sbeveloper * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23255a01c7Sbeveloper * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24255a01c7Sbeveloper * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25255a01c7Sbeveloper * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26255a01c7Sbeveloper * THE SOFTWARE. 27255a01c7Sbeveloper * 28255a01c7Sbeveloper */ 29255a01c7Sbeveloper 3052a38012Sejakowatz #include <BufferProducer.h> 3160f15390Sbeveloper #include <BufferConsumer.h> 3252a38012Sejakowatz #include <BufferGroup.h> 3352a38012Sejakowatz #include <Buffer.h> 3452a38012Sejakowatz #include "debug.h" 3540f36b03Sbeveloper #include "MediaMisc.h" 368c6a6096Sbeveloper #include "DataExchange.h" 3752a38012Sejakowatz 3852a38012Sejakowatz /************************************************************* 3952a38012Sejakowatz * protected BBufferProducer 4052a38012Sejakowatz *************************************************************/ 4152a38012Sejakowatz 4252a38012Sejakowatz BBufferProducer::~BBufferProducer() 4352a38012Sejakowatz { 4452a38012Sejakowatz CALLED(); 4552a38012Sejakowatz } 4652a38012Sejakowatz 4752a38012Sejakowatz /************************************************************* 4852a38012Sejakowatz * public BBufferProducer 4952a38012Sejakowatz *************************************************************/ 5052a38012Sejakowatz 5152a38012Sejakowatz /* static */ status_t 5252a38012Sejakowatz BBufferProducer::ClipDataToRegion(int32 format, 5352a38012Sejakowatz int32 size, 5463ffaa3eSbeveloper const void *data, 5552a38012Sejakowatz BRegion *region) 5652a38012Sejakowatz { 5752a38012Sejakowatz CALLED(); 5852a38012Sejakowatz 5952a38012Sejakowatz if (format != B_CLIP_SHORT_RUNS) 6052a38012Sejakowatz return B_MEDIA_BAD_CLIP_FORMAT; 6152a38012Sejakowatz 6263ffaa3eSbeveloper return clip_shorts_to_region((const int16 *)data, size / sizeof(int16), region); 6352a38012Sejakowatz } 6452a38012Sejakowatz 6552a38012Sejakowatz media_type 6652a38012Sejakowatz BBufferProducer::ProducerType() 6752a38012Sejakowatz { 6852a38012Sejakowatz CALLED(); 6952a38012Sejakowatz return fProducerType; 7052a38012Sejakowatz } 7152a38012Sejakowatz 7252a38012Sejakowatz /************************************************************* 7352a38012Sejakowatz * protected BBufferProducer 7452a38012Sejakowatz *************************************************************/ 7552a38012Sejakowatz 7652a38012Sejakowatz /* explicit */ 7752a38012Sejakowatz BBufferProducer::BBufferProducer(media_type producer_type) : 7852a38012Sejakowatz BMediaNode("called by BBufferProducer"), 7952a38012Sejakowatz fProducerType(producer_type), 8052a38012Sejakowatz fInitialLatency(0), 8160f15390Sbeveloper fInitialFlags(0), 8260f15390Sbeveloper fDelay(0) 8352a38012Sejakowatz { 8452a38012Sejakowatz CALLED(); 8552a38012Sejakowatz 8652a38012Sejakowatz AddNodeKind(B_BUFFER_PRODUCER); 8752a38012Sejakowatz } 8852a38012Sejakowatz 8952a38012Sejakowatz 9052a38012Sejakowatz status_t 9152a38012Sejakowatz BBufferProducer::VideoClippingChanged(const media_source &for_source, 9252a38012Sejakowatz int16 num_shorts, 9352a38012Sejakowatz int16 *clip_data, 9452a38012Sejakowatz const media_video_display_info &display, 9552a38012Sejakowatz int32 *_deprecated_) 9652a38012Sejakowatz { 9752a38012Sejakowatz CALLED(); 9852a38012Sejakowatz // may be implemented by derived classes 9952a38012Sejakowatz return B_ERROR; 10052a38012Sejakowatz } 10152a38012Sejakowatz 10252a38012Sejakowatz 10352a38012Sejakowatz status_t 10452a38012Sejakowatz BBufferProducer::GetLatency(bigtime_t *out_lantency) 10552a38012Sejakowatz { 10660f15390Sbeveloper CALLED(); 10760f15390Sbeveloper // The default implementation of GetLatency() finds the maximum 10852a38012Sejakowatz // latency of your currently-available outputs by iterating over 10952a38012Sejakowatz // them, and returns that value in outLatency 11052a38012Sejakowatz 11160f15390Sbeveloper int32 cookie; 11260f15390Sbeveloper bigtime_t latency; 11360f15390Sbeveloper media_output output; 11460f15390Sbeveloper media_node_id unused; 11560f15390Sbeveloper 11660f15390Sbeveloper *out_lantency = 0; 11760f15390Sbeveloper cookie = 0; 11860f15390Sbeveloper while (B_OK == GetNextOutput(&cookie, &output)) { 11960f15390Sbeveloper 12060f15390Sbeveloper if (output.destination == media_destination::null) 12160f15390Sbeveloper continue; 12260f15390Sbeveloper 12360f15390Sbeveloper if (output.node.node == fNodeID) { // avoid port writes (deadlock) if loopback connection 12460f15390Sbeveloper if (!fConsumerThis) 12560f15390Sbeveloper fConsumerThis = dynamic_cast<BBufferConsumer *>(this); 12660f15390Sbeveloper if (!fConsumerThis) 12760f15390Sbeveloper continue; 12860f15390Sbeveloper latency = 0; 12960f15390Sbeveloper if (B_OK == fConsumerThis->GetLatencyFor(output.destination, &latency, &unused)) { 13060f15390Sbeveloper if (latency > *out_lantency) { 13160f15390Sbeveloper *out_lantency = latency; 13260f15390Sbeveloper } 13360f15390Sbeveloper } 13460f15390Sbeveloper } else { 13560f15390Sbeveloper if (B_OK == FindLatencyFor(output.destination, &latency, &unused)) { 13660f15390Sbeveloper if (latency > *out_lantency) { 13760f15390Sbeveloper *out_lantency = latency; 13860f15390Sbeveloper } 13960f15390Sbeveloper } 14060f15390Sbeveloper } 14160f15390Sbeveloper } 14260f15390Sbeveloper printf("BBufferProducer::GetLatency: node %ld, name \"%s\" has max latency %Ld\n", fNodeID, fName, *out_lantency); 14360f15390Sbeveloper return B_OK; 14452a38012Sejakowatz } 14552a38012Sejakowatz 14652a38012Sejakowatz 14752a38012Sejakowatz status_t 14852a38012Sejakowatz BBufferProducer::SetPlayRate(int32 numer, 14952a38012Sejakowatz int32 denom) 15052a38012Sejakowatz { 15152a38012Sejakowatz CALLED(); 15252a38012Sejakowatz // may be implemented by derived classes 15352a38012Sejakowatz return B_ERROR; 15452a38012Sejakowatz } 15552a38012Sejakowatz 15652a38012Sejakowatz 15752a38012Sejakowatz status_t 15852a38012Sejakowatz BBufferProducer::HandleMessage(int32 message, 159dfb2ad61Sbeveloper const void *data, 16052a38012Sejakowatz size_t size) 16152a38012Sejakowatz { 1625ac4fbd7Sbeveloper PRINT(4, "BBufferProducer::HandleMessage %#lx, node %ld\n", message, fNodeID); 1638c6a6096Sbeveloper status_t rv; 16452a38012Sejakowatz switch (message) { 16560f15390Sbeveloper case PRODUCER_SET_RUN_MODE_DELAY: 16660f15390Sbeveloper { 16760f15390Sbeveloper const producer_set_run_mode_delay_command *command = static_cast<const producer_set_run_mode_delay_command *>(data); 16860f15390Sbeveloper // when changing this, also change NODE_SET_RUN_MODE 16960f15390Sbeveloper fDelay = command->delay; 17060f15390Sbeveloper fRunMode = command->mode; 1711df08d39Sbeveloper TRACE("PRODUCER_SET_RUN_MODE_DELAY: fDelay now %Ld\n", fDelay); 17260f15390Sbeveloper SetRunMode(fRunMode); 17360f15390Sbeveloper return B_OK; 17460f15390Sbeveloper } 17552a38012Sejakowatz 17652a38012Sejakowatz case PRODUCER_FORMAT_SUGGESTION_REQUESTED: 17752a38012Sejakowatz { 178dfb2ad61Sbeveloper const producer_format_suggestion_requested_request *request = static_cast<const producer_format_suggestion_requested_request *>(data); 179dfb2ad61Sbeveloper producer_format_suggestion_requested_reply reply; 180dfb2ad61Sbeveloper rv = FormatSuggestionRequested(request->type, request->quality, &reply.format); 181dfb2ad61Sbeveloper request->SendReply(rv, &reply, sizeof(reply)); 18252a38012Sejakowatz return B_OK; 18352a38012Sejakowatz } 18452a38012Sejakowatz 18552a38012Sejakowatz case PRODUCER_FORMAT_PROPOSAL: 18652a38012Sejakowatz { 187dfb2ad61Sbeveloper const producer_format_proposal_request *request = static_cast<const producer_format_proposal_request *>(data); 1888c6a6096Sbeveloper producer_format_proposal_reply reply; 1898c6a6096Sbeveloper reply.format = request->format; 1908c6a6096Sbeveloper rv = FormatProposal(request->output, &reply.format); 1918c6a6096Sbeveloper request->SendReply(rv, &reply, sizeof(reply)); 19252a38012Sejakowatz return B_OK; 19352a38012Sejakowatz } 19452a38012Sejakowatz 19552a38012Sejakowatz case PRODUCER_PREPARE_TO_CONNECT: 19652a38012Sejakowatz { 197dfb2ad61Sbeveloper const producer_prepare_to_connect_request *request = static_cast<const producer_prepare_to_connect_request *>(data); 1988c6a6096Sbeveloper producer_prepare_to_connect_reply reply; 1998c6a6096Sbeveloper reply.format = request->format; 2005ac4fbd7Sbeveloper reply.out_source = request->source; 2018c6a6096Sbeveloper memcpy(reply.name, request->name, B_MEDIA_NAME_LENGTH); 2028c6a6096Sbeveloper rv = PrepareToConnect(request->source, request->destination, &reply.format, &reply.out_source, reply.name); 2038c6a6096Sbeveloper request->SendReply(rv, &reply, sizeof(reply)); 20452a38012Sejakowatz return B_OK; 20552a38012Sejakowatz } 20652a38012Sejakowatz 20752a38012Sejakowatz case PRODUCER_CONNECT: 20852a38012Sejakowatz { 209dfb2ad61Sbeveloper const producer_connect_request *request = static_cast<const producer_connect_request *>(data); 2108c6a6096Sbeveloper producer_connect_reply reply; 2118c6a6096Sbeveloper memcpy(reply.name, request->name, B_MEDIA_NAME_LENGTH); 2128c6a6096Sbeveloper Connect(request->error, request->source, request->destination, request->format, reply.name); 2138c6a6096Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 21452a38012Sejakowatz return B_OK; 21552a38012Sejakowatz } 21652a38012Sejakowatz 21752a38012Sejakowatz case PRODUCER_DISCONNECT: 21852a38012Sejakowatz { 219dfb2ad61Sbeveloper const producer_disconnect_request *request = static_cast<const producer_disconnect_request *>(data); 2209e9417d2Sbeveloper producer_disconnect_reply reply; 2218c6a6096Sbeveloper Disconnect(request->source, request->destination); 2229e9417d2Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 22352a38012Sejakowatz return B_OK; 22452a38012Sejakowatz } 22552a38012Sejakowatz 22652a38012Sejakowatz case PRODUCER_GET_INITIAL_LATENCY: 22752a38012Sejakowatz { 228dfb2ad61Sbeveloper const producer_get_initial_latency_request *request = static_cast<const producer_get_initial_latency_request *>(data); 229dfb2ad61Sbeveloper producer_get_initial_latency_reply reply; 23052a38012Sejakowatz reply.initial_latency = fInitialLatency; 23152a38012Sejakowatz reply.flags = fInitialFlags; 232dfb2ad61Sbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 23352a38012Sejakowatz return B_OK; 23452a38012Sejakowatz } 23552a38012Sejakowatz 23652a38012Sejakowatz case PRODUCER_SET_PLAY_RATE: 23752a38012Sejakowatz { 238dfb2ad61Sbeveloper const producer_set_play_rate_request *request = static_cast<const producer_set_play_rate_request *>(data); 239dfb2ad61Sbeveloper producer_set_play_rate_reply reply; 240dfb2ad61Sbeveloper rv = SetPlayRate(request->numer, request->denom); 241dfb2ad61Sbeveloper request->SendReply(rv, &reply, sizeof(reply)); 24252a38012Sejakowatz return B_OK; 24352a38012Sejakowatz } 24452a38012Sejakowatz 24552a38012Sejakowatz case PRODUCER_GET_LATENCY: 24652a38012Sejakowatz { 247dfb2ad61Sbeveloper const producer_get_latency_request *request = static_cast<const producer_get_latency_request *>(data); 248dfb2ad61Sbeveloper producer_get_latency_reply reply; 249dfb2ad61Sbeveloper rv = GetLatency(&reply.latency); 250dfb2ad61Sbeveloper request->SendReply(rv, &reply, sizeof(reply)); 25152a38012Sejakowatz return B_OK; 25252a38012Sejakowatz } 25352a38012Sejakowatz 25452a38012Sejakowatz case PRODUCER_GET_NEXT_OUTPUT: 25552a38012Sejakowatz { 256dfb2ad61Sbeveloper const producer_get_next_output_request *request = static_cast<const producer_get_next_output_request *>(data); 2573620737cSbeveloper producer_get_next_output_reply reply; 2588c6a6096Sbeveloper reply.cookie = request->cookie; 2593620737cSbeveloper rv = GetNextOutput(&reply.cookie, &reply.output); 2603620737cSbeveloper request->SendReply(rv, &reply, sizeof(reply)); 26152a38012Sejakowatz return B_OK; 26252a38012Sejakowatz } 26352a38012Sejakowatz 26452a38012Sejakowatz case PRODUCER_DISPOSE_OUTPUT_COOKIE: 26552a38012Sejakowatz { 266dfb2ad61Sbeveloper const producer_dispose_output_cookie_request *request = static_cast<const producer_dispose_output_cookie_request *>(data); 2673620737cSbeveloper producer_dispose_output_cookie_reply reply; 2688c6a6096Sbeveloper DisposeOutputCookie(request->cookie); 2693620737cSbeveloper request->SendReply(B_OK, &reply, sizeof(reply)); 27052a38012Sejakowatz return B_OK; 27152a38012Sejakowatz } 27252a38012Sejakowatz 27352a38012Sejakowatz case PRODUCER_SET_BUFFER_GROUP: 27452a38012Sejakowatz { 275dfb2ad61Sbeveloper const producer_set_buffer_group_command *command = static_cast<const producer_set_buffer_group_command *>(data); 276dfb2ad61Sbeveloper node_request_completed_command replycommand; 27752a38012Sejakowatz BBufferGroup *group; 278dfb2ad61Sbeveloper group = command->buffer_count != 0 ? new BBufferGroup(command->buffer_count, command->buffers) : NULL; 279dfb2ad61Sbeveloper rv = SetBufferGroup(command->source, group); 280dfb2ad61Sbeveloper if (command->destination == media_destination::null) 28152a38012Sejakowatz return B_OK; 282dfb2ad61Sbeveloper replycommand.info.what = media_request_info::B_SET_OUTPUT_BUFFERS_FOR; 283dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 284dfb2ad61Sbeveloper replycommand.info.status = rv; 285dfb2ad61Sbeveloper replycommand.info.cookie = (int32)group; 286dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 287dfb2ad61Sbeveloper replycommand.info.source = command->source; 288dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 289dfb2ad61Sbeveloper SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, &replycommand, sizeof(replycommand)); 29052a38012Sejakowatz return B_OK; 29152a38012Sejakowatz } 29252a38012Sejakowatz 29352a38012Sejakowatz case PRODUCER_FORMAT_CHANGE_REQUESTED: 29452a38012Sejakowatz { 295dfb2ad61Sbeveloper const producer_format_change_requested_command *command = static_cast<const producer_format_change_requested_command *>(data); 296dfb2ad61Sbeveloper node_request_completed_command replycommand; 297dfb2ad61Sbeveloper replycommand.info.format = command->format; 298dfb2ad61Sbeveloper rv = FormatChangeRequested(command->source, command->destination, &replycommand.info.format, NULL); 299dfb2ad61Sbeveloper if (command->destination == media_destination::null) 30052a38012Sejakowatz return B_OK; 301dfb2ad61Sbeveloper replycommand.info.what = media_request_info::B_REQUEST_FORMAT_CHANGE; 302dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 303dfb2ad61Sbeveloper replycommand.info.status = rv; 304dfb2ad61Sbeveloper //replycommand.info.cookie 305dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 306dfb2ad61Sbeveloper replycommand.info.source = command->source; 307dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 308dfb2ad61Sbeveloper SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, &replycommand, sizeof(replycommand)); 30952a38012Sejakowatz return B_OK; 31052a38012Sejakowatz } 31152a38012Sejakowatz 31252a38012Sejakowatz case PRODUCER_VIDEO_CLIPPING_CHANGED: 31352a38012Sejakowatz { 314dfb2ad61Sbeveloper const producer_video_clipping_changed_command *command = static_cast<const producer_video_clipping_changed_command *>(data); 315dfb2ad61Sbeveloper node_request_completed_command replycommand; 316dfb2ad61Sbeveloper rv = VideoClippingChanged(command->source, command->short_count, (int16 *)command->shorts, command->display, NULL); 317dfb2ad61Sbeveloper if (command->destination == media_destination::null) 31852a38012Sejakowatz return B_OK; 319dfb2ad61Sbeveloper replycommand.info.what = media_request_info::B_SET_VIDEO_CLIPPING_FOR; 320dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 321dfb2ad61Sbeveloper replycommand.info.status = rv; 322dfb2ad61Sbeveloper //replycommand.info.cookie 323dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 324dfb2ad61Sbeveloper replycommand.info.source = command->source; 325dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 326dfb2ad61Sbeveloper replycommand.info.format.type = B_MEDIA_RAW_VIDEO; 327dfb2ad61Sbeveloper replycommand.info.format.u.raw_video.display = command->display; 328dfb2ad61Sbeveloper SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, &replycommand, sizeof(replycommand)); 32952a38012Sejakowatz return B_OK; 33052a38012Sejakowatz } 33152a38012Sejakowatz 33252a38012Sejakowatz case PRODUCER_ADDITIONAL_BUFFER_REQUESTED: 33352a38012Sejakowatz { 334dfb2ad61Sbeveloper const producer_additional_buffer_requested_command *command = static_cast<const producer_additional_buffer_requested_command *>(data); 335dfb2ad61Sbeveloper AdditionalBufferRequested(command->source, command->prev_buffer, command->prev_time, command->has_seek_tag ? &command->prev_tag : NULL); 33652a38012Sejakowatz return B_OK; 33752a38012Sejakowatz } 33852a38012Sejakowatz 33952a38012Sejakowatz case PRODUCER_LATENCY_CHANGED: 34052a38012Sejakowatz { 341dfb2ad61Sbeveloper const producer_latency_changed_command *command = static_cast<const producer_latency_changed_command *>(data); 342dfb2ad61Sbeveloper LatencyChanged(command->source, command->destination, command->latency, command->flags); 34352a38012Sejakowatz return B_OK; 34452a38012Sejakowatz } 34552a38012Sejakowatz 34652a38012Sejakowatz case PRODUCER_LATE_NOTICE_RECEIVED: 34752a38012Sejakowatz { 348dfb2ad61Sbeveloper const producer_late_notice_received_command *command = static_cast<const producer_late_notice_received_command *>(data); 349dfb2ad61Sbeveloper LateNoticeReceived(command->source, command->how_much, command->performance_time); 35052a38012Sejakowatz return B_OK; 35152a38012Sejakowatz } 35252a38012Sejakowatz 35352a38012Sejakowatz case PRODUCER_ENABLE_OUTPUT: 35452a38012Sejakowatz { 355dfb2ad61Sbeveloper const producer_enable_output_command *command = static_cast<const producer_enable_output_command *>(data); 356dfb2ad61Sbeveloper node_request_completed_command replycommand; 357dfb2ad61Sbeveloper EnableOutput(command->source, command->enabled, NULL); 358dfb2ad61Sbeveloper if (command->destination == media_destination::null) 35952a38012Sejakowatz return B_OK; 360dfb2ad61Sbeveloper replycommand.info.what = media_request_info::B_SET_OUTPUT_ENABLED; 361dfb2ad61Sbeveloper replycommand.info.change_tag = command->change_tag; 362dfb2ad61Sbeveloper replycommand.info.status = B_OK; 363dfb2ad61Sbeveloper //replycommand.info.cookie 364dfb2ad61Sbeveloper replycommand.info.user_data = command->user_data; 365dfb2ad61Sbeveloper replycommand.info.source = command->source; 366dfb2ad61Sbeveloper replycommand.info.destination = command->destination; 367dfb2ad61Sbeveloper //replycommand.info.format 368dfb2ad61Sbeveloper SendToPort(command->destination.port, NODE_REQUEST_COMPLETED, &replycommand, sizeof(replycommand)); 36952a38012Sejakowatz return B_OK; 37052a38012Sejakowatz } 37152a38012Sejakowatz 37252a38012Sejakowatz }; 37352a38012Sejakowatz return B_ERROR; 37452a38012Sejakowatz } 37552a38012Sejakowatz 37652a38012Sejakowatz 37752a38012Sejakowatz void 37852a38012Sejakowatz BBufferProducer::AdditionalBufferRequested(const media_source &source, 37952a38012Sejakowatz media_buffer_id prev_buffer, 38052a38012Sejakowatz bigtime_t prev_time, 38152a38012Sejakowatz const media_seek_tag *prev_tag) 38252a38012Sejakowatz { 38352a38012Sejakowatz CALLED(); 38452a38012Sejakowatz // may be implemented by derived classes 38552a38012Sejakowatz } 38652a38012Sejakowatz 38752a38012Sejakowatz 38852a38012Sejakowatz void 38952a38012Sejakowatz BBufferProducer::LatencyChanged(const media_source &source, 39052a38012Sejakowatz const media_destination &destination, 39152a38012Sejakowatz bigtime_t new_latency, 39252a38012Sejakowatz uint32 flags) 39352a38012Sejakowatz { 39452a38012Sejakowatz CALLED(); 39552a38012Sejakowatz // may be implemented by derived classes 39652a38012Sejakowatz } 39752a38012Sejakowatz 39852a38012Sejakowatz 39952a38012Sejakowatz status_t 40052a38012Sejakowatz BBufferProducer::SendBuffer(BBuffer *buffer, 40152a38012Sejakowatz const media_destination &destination) 40252a38012Sejakowatz { 40352a38012Sejakowatz CALLED(); 40452a38012Sejakowatz if (destination == media_destination::null) 40552a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 40652a38012Sejakowatz if (buffer == NULL) 40752a38012Sejakowatz return B_BAD_VALUE; 40852a38012Sejakowatz 409dfb2ad61Sbeveloper consumer_buffer_received_command command; 410dfb2ad61Sbeveloper command.buffer = buffer->ID(); 411dfb2ad61Sbeveloper command.header = *(buffer->Header()); 412dfb2ad61Sbeveloper command.header.buffer = command.buffer; // buffer->ID(); 413dfb2ad61Sbeveloper command.header.destination = destination.id; 4141df08d39Sbeveloper command.header.owner = 0; // XXX fill with "buffer owner info area" 41560f15390Sbeveloper command.header.start_time += fDelay; // time compensation as set by BMediaRoster::SetProducerRunModeDelay() 41652a38012Sejakowatz 417*a6d316d8Sbeveloper //printf("BBufferProducer::SendBuffer node %2ld, buffer %2ld, start_time %12Ld with lateness %6Ld\n", ID(), buffer->Header()->buffer, command.header.start_time, TimeSource()->Now() - command.header.start_time); 418*a6d316d8Sbeveloper 419dfb2ad61Sbeveloper return SendToPort(destination.port, CONSUMER_BUFFER_RECEIVED, &command, sizeof(command)); 42052a38012Sejakowatz } 42152a38012Sejakowatz 42252a38012Sejakowatz 42352a38012Sejakowatz status_t 42452a38012Sejakowatz BBufferProducer::SendDataStatus(int32 status, 42552a38012Sejakowatz const media_destination &destination, 42652a38012Sejakowatz bigtime_t at_time) 42752a38012Sejakowatz { 42852a38012Sejakowatz CALLED(); 42940f36b03Sbeveloper if (IS_INVALID_DESTINATION(destination)) 43052a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 43152a38012Sejakowatz 432dfb2ad61Sbeveloper consumer_producer_data_status_command command; 433dfb2ad61Sbeveloper command.for_whom = destination; 434dfb2ad61Sbeveloper command.status = status; 435dfb2ad61Sbeveloper command.at_performance_time = at_time; 43652a38012Sejakowatz 437dfb2ad61Sbeveloper return SendToPort(destination.port, CONSUMER_PRODUCER_DATA_STATUS, &command, sizeof(command)); 43852a38012Sejakowatz } 43952a38012Sejakowatz 44052a38012Sejakowatz 44152a38012Sejakowatz status_t 44252a38012Sejakowatz BBufferProducer::ProposeFormatChange(media_format *format, 44352a38012Sejakowatz const media_destination &for_destination) 44452a38012Sejakowatz { 44552a38012Sejakowatz CALLED(); 44640f36b03Sbeveloper if (IS_INVALID_DESTINATION(for_destination)) 44752a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 44852a38012Sejakowatz 4498c6a6096Sbeveloper consumer_accept_format_request request; 4508c6a6096Sbeveloper consumer_accept_format_reply reply; 45152a38012Sejakowatz status_t rv; 45252a38012Sejakowatz 4538c6a6096Sbeveloper request.dest = for_destination; 4548c6a6096Sbeveloper request.format = *format; 4558c6a6096Sbeveloper rv = QueryPort(for_destination.port, CONSUMER_ACCEPT_FORMAT, &request, sizeof(request), &reply, sizeof(reply)); 4568c6a6096Sbeveloper if (rv != B_OK) 45752a38012Sejakowatz return rv; 45852a38012Sejakowatz 45952a38012Sejakowatz *format = reply.format; 4608c6a6096Sbeveloper return B_OK; 46152a38012Sejakowatz } 46252a38012Sejakowatz 46352a38012Sejakowatz 46452a38012Sejakowatz status_t 46552a38012Sejakowatz BBufferProducer::ChangeFormat(const media_source &for_source, 46652a38012Sejakowatz const media_destination &for_destination, 46752a38012Sejakowatz media_format *format) 46852a38012Sejakowatz { 46952a38012Sejakowatz CALLED(); 47040f36b03Sbeveloper if (IS_INVALID_SOURCE(for_source)) 47152a38012Sejakowatz return B_MEDIA_BAD_SOURCE; 47240f36b03Sbeveloper if (IS_INVALID_DESTINATION(for_destination)) 47352a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 47452a38012Sejakowatz 475dfb2ad61Sbeveloper consumer_format_changed_request request; 476dfb2ad61Sbeveloper consumer_format_changed_reply reply; 47752a38012Sejakowatz 4788c6a6096Sbeveloper request.producer = for_source; 4798c6a6096Sbeveloper request.consumer = for_destination; 4808c6a6096Sbeveloper request.format = *format; 48152a38012Sejakowatz 482dfb2ad61Sbeveloper // we use a request/reply to make this synchronous 483dfb2ad61Sbeveloper return QueryPort(for_destination.port, CONSUMER_FORMAT_CHANGED, &request, sizeof(request), &reply, sizeof(reply)); 48452a38012Sejakowatz } 48552a38012Sejakowatz 48652a38012Sejakowatz 48752a38012Sejakowatz status_t 48852a38012Sejakowatz BBufferProducer::FindLatencyFor(const media_destination &for_destination, 48952a38012Sejakowatz bigtime_t *out_latency, 49052a38012Sejakowatz media_node_id *out_timesource) 49152a38012Sejakowatz { 49252a38012Sejakowatz CALLED(); 49340f36b03Sbeveloper if (IS_INVALID_DESTINATION(for_destination)) 49452a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 49552a38012Sejakowatz 49652a38012Sejakowatz status_t rv; 497dfb2ad61Sbeveloper consumer_get_latency_for_request request; 498dfb2ad61Sbeveloper consumer_get_latency_for_reply reply; 49952a38012Sejakowatz 5008c6a6096Sbeveloper request.for_whom = for_destination; 50152a38012Sejakowatz 502dfb2ad61Sbeveloper rv = QueryPort(for_destination.port, CONSUMER_GET_LATENCY_FOR, &request, sizeof(request), &reply, sizeof(reply)); 503dfb2ad61Sbeveloper if (rv != B_OK) 50452a38012Sejakowatz return rv; 50552a38012Sejakowatz 50652a38012Sejakowatz *out_latency = reply.latency; 50752a38012Sejakowatz *out_timesource = reply.timesource; 508dfb2ad61Sbeveloper return rv; 50952a38012Sejakowatz } 51052a38012Sejakowatz 51152a38012Sejakowatz 51252a38012Sejakowatz status_t 51352a38012Sejakowatz BBufferProducer::FindSeekTag(const media_destination &for_destination, 51452a38012Sejakowatz bigtime_t in_target_time, 51552a38012Sejakowatz media_seek_tag *out_tag, 51652a38012Sejakowatz bigtime_t *out_tagged_time, 51752a38012Sejakowatz uint32 *out_flags, 51852a38012Sejakowatz uint32 in_flags) 51952a38012Sejakowatz { 52052a38012Sejakowatz CALLED(); 52140f36b03Sbeveloper if (IS_INVALID_DESTINATION(for_destination)) 52252a38012Sejakowatz return B_MEDIA_BAD_DESTINATION; 52352a38012Sejakowatz 52452a38012Sejakowatz status_t rv; 525dfb2ad61Sbeveloper consumer_seek_tag_requested_request request; 526dfb2ad61Sbeveloper consumer_seek_tag_requested_reply reply; 52752a38012Sejakowatz 5288c6a6096Sbeveloper request.destination = for_destination; 5298c6a6096Sbeveloper request.target_time = in_target_time; 5308c6a6096Sbeveloper request.flags = in_flags; 53152a38012Sejakowatz 532dfb2ad61Sbeveloper rv = QueryPort(for_destination.port, CONSUMER_SEEK_TAG_REQUESTED, &request, sizeof(request), &reply, sizeof(reply)); 533dfb2ad61Sbeveloper if (rv != B_OK) 53452a38012Sejakowatz return rv; 53552a38012Sejakowatz 53652a38012Sejakowatz *out_tag = reply.seek_tag; 53752a38012Sejakowatz *out_tagged_time = reply.tagged_time; 53852a38012Sejakowatz *out_flags = reply.flags; 539dfb2ad61Sbeveloper return rv; 54052a38012Sejakowatz } 54152a38012Sejakowatz 54252a38012Sejakowatz 54352a38012Sejakowatz void 54452a38012Sejakowatz BBufferProducer::SetInitialLatency(bigtime_t inInitialLatency, 54552a38012Sejakowatz uint32 flags) 54652a38012Sejakowatz { 54752a38012Sejakowatz fInitialLatency = inInitialLatency; 54852a38012Sejakowatz fInitialFlags = flags; 54952a38012Sejakowatz } 55052a38012Sejakowatz 55152a38012Sejakowatz /************************************************************* 55252a38012Sejakowatz * private BBufferProducer 55352a38012Sejakowatz *************************************************************/ 55452a38012Sejakowatz 55552a38012Sejakowatz /* 55652a38012Sejakowatz private unimplemented 55752a38012Sejakowatz BBufferProducer::BBufferProducer() 55852a38012Sejakowatz BBufferProducer::BBufferProducer(const BBufferProducer &clone) 55952a38012Sejakowatz BBufferProducer & BBufferProducer::operator=(const BBufferProducer &clone) 56052a38012Sejakowatz */ 56152a38012Sejakowatz 56252a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_0(void *) { return B_ERROR; } 56352a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_1(void *) { return B_ERROR; } 56452a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_2(void *) { return B_ERROR; } 56552a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_3(void *) { return B_ERROR; } 56652a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_4(void *) { return B_ERROR; } 56752a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_5(void *) { return B_ERROR; } 56852a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_6(void *) { return B_ERROR; } 56952a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_7(void *) { return B_ERROR; } 57052a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_8(void *) { return B_ERROR; } 57152a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_9(void *) { return B_ERROR; } 57252a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_10(void *) { return B_ERROR; } 57352a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_11(void *) { return B_ERROR; } 57452a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_12(void *) { return B_ERROR; } 57552a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_13(void *) { return B_ERROR; } 57652a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_14(void *) { return B_ERROR; } 57752a38012Sejakowatz status_t BBufferProducer::_Reserved_BufferProducer_15(void *) { return B_ERROR; } 57852a38012Sejakowatz 57952a38012Sejakowatz 58052a38012Sejakowatz status_t 58163ffaa3eSbeveloper BBufferProducer::clip_shorts_to_region(const int16 *data, 58252a38012Sejakowatz int count, 58352a38012Sejakowatz BRegion *output) 58452a38012Sejakowatz { 58552a38012Sejakowatz UNIMPLEMENTED(); 58652a38012Sejakowatz 58752a38012Sejakowatz return B_ERROR; 58852a38012Sejakowatz } 58952a38012Sejakowatz 59052a38012Sejakowatz 59152a38012Sejakowatz status_t 59252a38012Sejakowatz BBufferProducer::clip_region_to_shorts(const BRegion *input, 59363ffaa3eSbeveloper int16 *data, 59452a38012Sejakowatz int max_count, 59552a38012Sejakowatz int *out_count) 59652a38012Sejakowatz { 59752a38012Sejakowatz UNIMPLEMENTED(); 59852a38012Sejakowatz 59952a38012Sejakowatz return B_ERROR; 60052a38012Sejakowatz } 60152a38012Sejakowatz 602