2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 * Copyright (c) 2002, 2003 Marcus Overhagen <Marcus@Overhagen.de>
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files or portions
11 * thereof (the "Software"), to deal in the Software without restriction,
12 * including without limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of the Software,
14 * and to permit persons to whom the Software is furnished to do so, subject
15 * to the following conditions:
17 * * Redistributions of source code must retain the above copyright notice,
18 * this list of conditions and the following disclaimer.
20 * * Redistributions in binary form must reproduce the above copyright notice
21 * in the binary, as well as this list of conditions and the following
22 * disclaimer in the documentation and/or other materials provided with
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
38 #include <MediaDefs.h>
41 #include "DataExchange.h"
42 #include "SharedBufferList.h"
45 using namespace BPrivate::media
;
48 // #pragma mark - buffer_clone_info
51 buffer_clone_info::buffer_clone_info()
62 buffer_clone_info::~buffer_clone_info()
68 // #pragma mark - public BBuffer
80 BBuffer::SizeAvailable()
91 return fMediaHeader
.size_used
;
96 BBuffer::SetSizeUsed(size_t size_used
)
99 fMediaHeader
.size_used
= min_c(size_used
, fSize
);
115 if (fBufferList
== NULL
)
117 fBufferList
->RecycleBuffer(this);
122 BBuffer::CloneInfo() const
125 buffer_clone_info info
;
127 info
.buffer
= fMediaHeader
.buffer
;
129 info
.offset
= fOffset
;
141 return fMediaHeader
.buffer
;
149 return fMediaHeader
.type
;
157 return &fMediaHeader
;
162 BBuffer::AudioHeader()
165 return &fMediaHeader
.u
.raw_audio
;
170 BBuffer::VideoHeader()
173 return &fMediaHeader
.u
.raw_video
;
181 return SizeAvailable();
185 // #pragma mark - private BBuffer
188 BBuffer::BBuffer(const buffer_clone_info
& info
)
199 // Ensure that the media_header is clean
200 memset(&fMediaHeader
, 0, sizeof(fMediaHeader
));
201 // special case for BSmallBuffer
202 if (info
.area
== 0 && info
.buffer
== 0)
205 // Must be -1 if registration fail
206 fMediaHeader
.buffer
= -1;
208 fBufferList
= BPrivate::SharedBufferList::Get();
209 if (fBufferList
== NULL
) {
210 ERROR("BBuffer::BBuffer: BPrivate::SharedBufferList::Get() failed\n");
214 server_register_buffer_request request
;
215 server_register_buffer_reply reply
;
217 request
.team
= BPrivate::current_team();
220 // ask media_server to register this buffer,
221 // either identified by "buffer" or by area information.
222 // media_server either has a copy of the area identified
223 // by "buffer", or creates a new area.
224 // the information and the area is cached by the media_server
225 // until the last buffer has been unregistered
226 // the area_id of the cached area is passed back to us, and we clone it.
228 if (QueryServer(SERVER_REGISTER_BUFFER
, &request
, sizeof(request
), &reply
,
229 sizeof(reply
)) != B_OK
) {
230 ERROR("BBuffer::BBuffer: failed to register buffer with "
235 ASSERT(reply
.info
.buffer
> 0);
236 ASSERT(reply
.info
.area
> 0);
237 ASSERT(reply
.info
.size
> 0);
239 fArea
= clone_area("a cloned BBuffer", &fData
, B_ANY_ADDRESS
,
240 B_READ_AREA
| B_WRITE_AREA
, reply
.info
.area
);
242 ERROR("BBuffer::BBuffer: buffer cloning failed"
243 ", unregistering buffer\n");
244 server_unregister_buffer_command cmd
;
245 cmd
.team
= BPrivate::current_team();
246 cmd
.buffer_id
= reply
.info
.buffer
;
247 SendToServer(SERVER_UNREGISTER_BUFFER
, &cmd
, sizeof(cmd
));
251 // the response from media server contains enough information
252 // to clone the memory for this buffer
253 fSize
= reply
.info
.size
;
254 fFlags
= reply
.info
.flags
;
255 fOffset
= reply
.info
.offset
;
256 fMediaHeader
.size_used
= 0;
257 fMediaHeader
.buffer
= reply
.info
.buffer
;
258 fData
= (char*)fData
+ fOffset
;
266 // unmap the BufferList
267 if (fBufferList
!= NULL
)
274 // Ask media_server to unregister the buffer when the last clone of
275 // this buffer is gone, media_server will also remove its cached area.
276 server_unregister_buffer_command cmd
;
277 cmd
.team
= BPrivate::current_team();
278 cmd
.buffer_id
= fMediaHeader
.buffer
;
279 SendToServer(SERVER_UNREGISTER_BUFFER
, &cmd
, sizeof(cmd
));
285 BBuffer::SetHeader(const media_header
* header
)
288 ASSERT(header
->buffer
== fMediaHeader
.buffer
);
289 if (header
->buffer
!= fMediaHeader
.buffer
)
291 fMediaHeader
= *header
;
295 // #pragma mark - public BSmallBuffer
298 static const buffer_clone_info sSmallBufferInfo
;
301 BSmallBuffer::BSmallBuffer()
303 BBuffer(sSmallBufferInfo
)
306 debugger("BSmallBuffer::BSmallBuffer called\n");
311 BSmallBuffer::SmallBufferSizeLimit()