2 * Copyright (c) 2002, 2003, 2008 Marcus Overhagen <Marcus@Overhagen.de>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files or portions
6 * thereof (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so, subject
10 * to the following conditions:
12 * * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright notice
16 * in the binary, as well as this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided with
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31 #include <MediaAddOn.h>
36 #include "DataExchange.h"
39 #define MAX_FLAVOR_IN_FORMAT_COUNT 300
40 #define MAX_FLAVOR_OUT_FORMAT_COUNT 300
42 #define FLATTEN_MAGIC 'CODE'
43 #define FLATTEN_TYPECODE 'DFIT'
47 _newstrdup(const char *str
)
51 int len
= strlen(str
) + 1;
52 char *p
= new(std::nothrow
) char[len
];
59 // #pragma mark - dormant_node_info
62 dormant_node_info::dormant_node_info()
71 dormant_node_info::~dormant_node_info()
76 // #pragma mark - flavor_info
79 /* DO NOT IMPLEMENT */
81 flavor_info &flavor_info::operator=(const flavor_info &other)
85 // #pragma mark - dormant_flavor_info
88 dormant_flavor_info::dormant_flavor_info()
100 out_format_flags
= 0;
105 dormant_flavor_info::~dormant_flavor_info()
110 delete[] out_formats
;
114 dormant_flavor_info::dormant_flavor_info(const dormant_flavor_info
&clone
)
125 dormant_flavor_info
&
126 dormant_flavor_info::operator=(const dormant_flavor_info
&clone
)
128 // call operator=(const flavor_info &clone) to copy the flavor_info base class
129 *this = static_cast<const flavor_info
>(clone
);
130 // copy the dormant_node_info member variable
131 node_info
= clone
.node_info
;
136 dormant_flavor_info
&
137 dormant_flavor_info::operator=(const flavor_info
&clone
)
140 flavor_flags
= clone
.flavor_flags
;
141 internal_id
= clone
.internal_id
;
142 possible_count
= clone
.possible_count
;
145 info
= _newstrdup(clone
.info
);
148 name
= _newstrdup(clone
.name
);
150 delete [] in_formats
;
153 in_format_flags
= clone
.in_format_flags
;
154 if ((kinds
& B_BUFFER_CONSUMER
) != 0) {
155 if (clone
.in_format_count
>= 0
156 && clone
.in_format_count
<= MAX_FLAVOR_IN_FORMAT_COUNT
) {
157 in_formats
= new(std::nothrow
) media_format
[clone
.in_format_count
];
158 if (in_formats
!= NULL
&& clone
.in_formats
!= NULL
) {
159 in_format_count
= clone
.in_format_count
;
160 for (int i
= 0; i
< in_format_count
; i
++) {
161 const_cast<media_format
&>(in_formats
[i
])
162 = clone
.in_formats
[i
];
166 fprintf(stderr
, "error: dormant_flavor_info::operator= clone.in_"
167 "format_count is invalid\n");
169 } else if (clone
.in_format_count
) {
170 fprintf(stderr
, "warning: dormant_flavor_info::operator= not "
171 "B_BUFFER_CONSUMER and clone.in_format_count is != 0\n");
174 delete [] out_formats
;
176 out_format_count
= 0;
177 out_format_flags
= clone
.out_format_flags
;
178 if (kinds
& B_BUFFER_PRODUCER
) {
179 if (clone
.out_format_count
>= 0
180 && clone
.out_format_count
<= MAX_FLAVOR_OUT_FORMAT_COUNT
) {
181 out_formats
= new(std::nothrow
) media_format
[clone
.out_format_count
];
182 if (out_formats
!= NULL
&& clone
.out_formats
!= NULL
) {
183 out_format_count
= clone
.out_format_count
;
184 for (int i
= 0; i
< out_format_count
; i
++) {
185 const_cast<media_format
&>(out_formats
[i
])
186 = clone
.out_formats
[i
];
190 fprintf(stderr
, "error dormant_flavor_info::operator= clone.out_"
191 "format_count is invalid\n");
193 } else if (clone
.out_format_count
) {
194 fprintf(stderr
, "warning: dormant_flavor_info::operator= not "
195 "B_BUFFER_PRODUCER and clone.out_format_count is != 0\n");
198 // initialize node_info with default values
199 dormant_node_info defaultValues
;
200 node_info
= defaultValues
;
207 dormant_flavor_info::set_name(const char *newName
)
210 name
= _newstrdup(newName
);
215 dormant_flavor_info::set_info(const char *newInfo
)
218 info
= _newstrdup(newInfo
);
223 dormant_flavor_info::add_in_format(const media_format
&in_format
)
225 media_format
*p
= new(std::nothrow
) media_format
[in_format_count
+ 1];
227 for (int i
= 0; i
< in_format_count
; i
++)
228 p
[i
] = in_formats
[i
];
229 p
[in_format_count
] = in_format
;
230 delete [] in_formats
;
232 in_format_count
+= 1;
238 dormant_flavor_info::add_out_format(const media_format
&out_format
)
240 media_format
*p
= new(std::nothrow
) media_format
[out_format_count
+ 1];
242 for (int i
= 0; i
< out_format_count
; i
++)
243 p
[i
] = out_formats
[i
];
244 p
[out_format_count
] = out_format
;
245 delete [] out_formats
;
247 out_format_count
+= 1;
253 dormant_flavor_info::IsFixedSize() const
260 dormant_flavor_info::TypeCode() const
262 return FLATTEN_TYPECODE
;
267 dormant_flavor_info::FlattenedSize() const
271 size
+= sizeof(int32
);
273 size
+= sizeof(int32
);
274 // struct flavor_info
275 size
+= sizeof(int32
) + strlen(name
);
276 size
+= sizeof(int32
) + strlen(info
);
277 size
+= sizeof(kinds
);
278 size
+= sizeof(flavor_flags
);
279 size
+= sizeof(internal_id
);
280 size
+= sizeof(possible_count
);
281 size
+= sizeof(in_format_count
);
282 size
+= sizeof(in_format_flags
);
283 if (in_format_count
> 0 && in_format_count
<= MAX_FLAVOR_IN_FORMAT_COUNT
284 && in_formats
!= NULL
)
285 size
+= in_format_count
* sizeof(media_format
);
286 size
+= sizeof(out_format_count
);
287 size
+= sizeof(out_format_flags
);
288 if (out_format_count
> 0 && out_format_count
<= MAX_FLAVOR_OUT_FORMAT_COUNT
289 && out_formats
!= NULL
)
290 size
+= out_format_count
* sizeof(media_format
);
291 // struct dormant_node_info node_info
292 size
+= sizeof(node_info
);
299 dormant_flavor_info::Flatten(void *buffer
, ssize_t size
) const
301 if (size
< FlattenedSize())
304 char *buf
= (char *)buffer
;
305 int32 nameLength
= name
? (int32
)strlen(name
) : -1;
306 int32 infoLength
= info
? (int32
)strlen(info
) : -1;
307 int32 inFormatCount
= 0;
308 size_t inFormatSize
= 0;
309 int32 outFormatCount
= 0;
310 size_t outFormatSize
= 0;
312 if ((kinds
& B_BUFFER_CONSUMER
) != 0 && in_format_count
> 0
313 && in_formats
!= NULL
) {
314 if (in_format_count
<= MAX_FLAVOR_IN_FORMAT_COUNT
) {
315 inFormatCount
= in_format_count
;
316 inFormatSize
= in_format_count
* sizeof(media_format
);
318 fprintf(stderr
, "error dormant_flavor_info::Flatten: "
319 "in_format_count is too large\n");
324 if ((kinds
& B_BUFFER_PRODUCER
) != 0 && out_format_count
> 0
325 && out_formats
!= NULL
) {
326 if (out_format_count
<= MAX_FLAVOR_OUT_FORMAT_COUNT
) {
327 outFormatCount
= out_format_count
;
328 outFormatSize
= out_format_count
* sizeof(media_format
);
330 fprintf(stderr
, "error dormant_flavor_info::Flatten: "
331 "out_format_count is too large\n");
337 *(int32
*)buf
= FLATTEN_MAGIC
; buf
+= sizeof(int32
);
340 *(int32
*)buf
= FlattenedSize(); buf
+= sizeof(int32
);
342 // struct flavor_info
343 *(int32
*)buf
= nameLength
; buf
+= sizeof(int32
);
344 if (nameLength
> 0) {
345 memcpy(buf
, name
, nameLength
);
348 *(int32
*)buf
= infoLength
; buf
+= sizeof(int32
);
349 if (infoLength
> 0) {
350 memcpy(buf
, info
, infoLength
);
354 *(uint64
*)buf
= kinds
; buf
+= sizeof(uint64
);
355 *(uint32
*)buf
= flavor_flags
; buf
+= sizeof(uint32
);
356 *(int32
*)buf
= internal_id
; buf
+= sizeof(int32
);
357 *(int32
*)buf
= possible_count
; buf
+= sizeof(int32
);
358 *(int32
*)buf
= inFormatCount
; buf
+= sizeof(int32
);
359 *(uint32
*)buf
= in_format_flags
; buf
+= sizeof(uint32
);
361 // XXX FIXME! we should not!!! make flat copies of media_format
362 memcpy(buf
, in_formats
, inFormatSize
); buf
+= inFormatSize
;
364 *(int32
*)buf
= outFormatCount
; buf
+= sizeof(int32
);
365 *(uint32
*)buf
= out_format_flags
; buf
+= sizeof(uint32
);
367 // XXX FIXME! we should not!!! make flat copies of media_format
368 memcpy(buf
, out_formats
, outFormatSize
); buf
+= outFormatSize
;
370 *(dormant_node_info
*)buf
= node_info
; buf
+= sizeof(dormant_node_info
);
377 dormant_flavor_info::Unflatten(type_code c
, const void *buffer
, ssize_t size
)
379 if (c
!= FLATTEN_TYPECODE
)
384 const char *buf
= (const char *)buffer
;
389 if (*(int32
*)buf
!= FLATTEN_MAGIC
)
391 buf
+= sizeof(int32
);
394 if (*(uint32
*)buf
> (uint32
)size
)
396 buf
+= sizeof(int32
);
405 delete[] out_formats
;
407 out_format_count
= 0;
409 // struct flavor_info
410 nameLength
= *(int32
*)buf
; buf
+= sizeof(int32
);
411 if (nameLength
>= 0) { // if nameLength is -1, we leave name = 0
412 name
= new(std::nothrow
) char [nameLength
+ 1];
414 memcpy(name
, buf
, nameLength
);
415 name
[nameLength
] = 0;
416 buf
+= nameLength
; // XXX not save
420 infoLength
= *(int32
*)buf
; buf
+= sizeof(int32
);
421 if (infoLength
>= 0) { // if infoLength is -1, we leave info = 0
422 info
= new(std::nothrow
) char [infoLength
+ 1];
424 memcpy(info
, buf
, infoLength
);
425 info
[infoLength
] = 0;
426 buf
+= infoLength
; // XXX not save
432 kinds
= *(uint64
*)buf
; buf
+= sizeof(uint64
);
433 flavor_flags
= *(uint32
*)buf
; buf
+= sizeof(uint32
);
434 internal_id
= *(int32
*)buf
; buf
+= sizeof(int32
);
435 possible_count
= *(int32
*)buf
; buf
+= sizeof(int32
);
436 count
= *(int32
*)buf
; buf
+= sizeof(int32
);
437 in_format_flags
= *(uint32
*)buf
; buf
+= sizeof(uint32
);
440 if (count
<= MAX_FLAVOR_IN_FORMAT_COUNT
) {
441 in_formats
= new(std::nothrow
) media_format
[count
];
444 // TODO: we should not!!! make flat copies of media_format
445 memcpy(const_cast<media_format
*>(in_formats
), buf
,
446 count
* sizeof(media_format
));
447 in_format_count
= count
;
449 buf
+= count
* sizeof(media_format
); // TODO: not save
452 count
= *(int32
*)buf
; buf
+= sizeof(int32
);
453 out_format_flags
= *(uint32
*)buf
; buf
+= sizeof(uint32
);
456 if (count
<= MAX_FLAVOR_OUT_FORMAT_COUNT
) {
457 out_formats
= new(std::nothrow
) media_format
[count
];
460 // TODO: we should not!!! make flat copies of media_format
461 memcpy(const_cast<media_format
*>(out_formats
), buf
,
462 count
* sizeof(media_format
));
463 out_format_count
= count
;
465 buf
+= count
* sizeof(media_format
); // TODO: not save
468 node_info
= *(dormant_node_info
*)buf
; buf
+= sizeof(dormant_node_info
);
474 // #pragma mark - BMediaAddOn
477 BMediaAddOn::BMediaAddOn(image_id image
)
486 BMediaAddOn::~BMediaAddOn()
493 BMediaAddOn::InitCheck(const char **_failureText
)
496 // only to be implemented by derived classes
497 *_failureText
= "no error";
503 BMediaAddOn::CountFlavors()
506 // only to be implemented by derived classes
512 BMediaAddOn::GetFlavorAt(int32 n
, const flavor_info
**_info
)
515 // only to be implemented by derived classes
521 BMediaAddOn::InstantiateNodeFor(const flavor_info
*info
, BMessage
*config
,
525 // only to be implemented by derived classes
531 BMediaAddOn::GetConfigurationFor(BMediaNode
*node
, BMessage
*toMessage
)
534 // only to be implemented by derived classes
540 BMediaAddOn::WantsAutoStart()
543 // only to be implemented by derived classes
549 BMediaAddOn::AutoStart(int count
, BMediaNode
**_node
, int32
*_internalID
,
553 // only to be implemented by derived classes
559 BMediaAddOn::SniffRef(const entry_ref
&file
, BMimeType
*mimeType
,
560 float *_quality
, int32
*_internalID
)
563 // only to be implemented by BFileInterface derived classes
569 BMediaAddOn::SniffType(const BMimeType
&type
, float *_quality
,
573 // only to be implemented by BFileInterface derived classes
579 BMediaAddOn::GetFileFormatList(int32 flavorID
,
580 media_file_format
*writableFormats
, int32 maxWriteItems
, int32
*_writeItems
,
581 media_file_format
*readableFormats
, int32 maxReadItems
, int32
*_readItems
,
585 // only to be implemented by BFileInterface derived classes
591 BMediaAddOn::SniffTypeKind(const BMimeType
&type
, uint64 kinds
, float *_quality
,
592 int32
*_internalID
, void *_reserved
)
595 // only to be implemented by BFileInterface derived classes
601 BMediaAddOn::ImageID()
608 BMediaAddOn::AddonID()
614 // #pragma mark - protected BMediaAddOn
618 BMediaAddOn::NotifyFlavorChange()
624 add_on_server_rescan_flavors_command command
;
625 command
.add_on_id
= fAddon
;
626 return SendToAddOnServer(ADD_ON_SERVER_RESCAN_ADD_ON_FLAVORS
, &command
,
631 // #pragma mark - private BMediaAddOn
636 BMediaAddOn::BMediaAddOn()
637 BMediaAddOn::BMediaAddOn(const BMediaAddOn &clone)
638 BMediaAddOn & BMediaAddOn::operator=(const BMediaAddOn &clone)
643 // declared here to remove them from the class header file
644 status_t
_Reserved_MediaAddOn_0__11BMediaAddOnPv(void *, void *); /* now used for BMediaAddOn::GetFileFormatList */
645 status_t
_Reserved_MediaAddOn_1__11BMediaAddOnPv(void *, void *); /* now used for BMediaAddOn::SniffTypeKind */
646 status_t
_Reserved_MediaAddOn_0__11BMediaAddOnPv(void *, void *) { return B_ERROR
; }
647 status_t
_Reserved_MediaAddOn_1__11BMediaAddOnPv(void *, void *) { return B_ERROR
; }
650 status_t
BMediaAddOn::_Reserved_MediaAddOn_2(void *) { return B_ERROR
; }
651 status_t
BMediaAddOn::_Reserved_MediaAddOn_3(void *) { return B_ERROR
; }
652 status_t
BMediaAddOn::_Reserved_MediaAddOn_4(void *) { return B_ERROR
; }
653 status_t
BMediaAddOn::_Reserved_MediaAddOn_5(void *) { return B_ERROR
; }
654 status_t
BMediaAddOn::_Reserved_MediaAddOn_6(void *) { return B_ERROR
; }
655 status_t
BMediaAddOn::_Reserved_MediaAddOn_7(void *) { return B_ERROR
; }