2 * Copyright 2004-2009, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
11 #include "FormatManager.h"
23 #define TIMEOUT 5000000LL
24 // 5 seconds timeout for sending the reply
25 // TODO: do we really want to pause the server looper for this?
26 // would be better to offload this action to a second thread
31 family_to_string(media_format_family family
)
34 case B_ANY_FORMAT_FAMILY
:
36 case B_BEOS_FORMAT_FAMILY
:
38 case B_QUICKTIME_FORMAT_FAMILY
:
40 case B_AVI_FORMAT_FAMILY
:
42 case B_ASF_FORMAT_FAMILY
:
44 case B_MPEG_FORMAT_FAMILY
:
46 case B_WAV_FORMAT_FAMILY
:
48 case B_AIFF_FORMAT_FAMILY
:
50 case B_AVR_FORMAT_FAMILY
:
52 case B_MISC_FORMAT_FAMILY
:
61 string_for_description(const media_format_description
& desc
, char* string
,
64 switch (desc
.family
) {
65 case B_ANY_FORMAT_FAMILY
:
66 snprintf(string
, length
, "any format");
68 case B_BEOS_FORMAT_FAMILY
:
69 snprintf(string
, length
, "BeOS format, format id 0x%lx",
72 case B_QUICKTIME_FORMAT_FAMILY
:
73 snprintf(string
, length
, "Quicktime format, vendor id 0x%lx, "
74 "codec id 0x%lx", desc
.u
.quicktime
.vendor
,
75 desc
.u
.quicktime
.codec
);
77 case B_AVI_FORMAT_FAMILY
:
78 snprintf(string
, length
, "AVI format, codec id 0x%lx",
81 case B_ASF_FORMAT_FAMILY
:
82 snprintf(string
, length
, "ASF format, GUID %02x %02x %02x %02x "
83 "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
84 desc
.u
.asf
.guid
.data
[0], desc
.u
.asf
.guid
.data
[1],
85 desc
.u
.asf
.guid
.data
[2], desc
.u
.asf
.guid
.data
[3],
86 desc
.u
.asf
.guid
.data
[4], desc
.u
.asf
.guid
.data
[5],
87 desc
.u
.asf
.guid
.data
[6], desc
.u
.asf
.guid
.data
[7],
88 desc
.u
.asf
.guid
.data
[8], desc
.u
.asf
.guid
.data
[9],
89 desc
.u
.asf
.guid
.data
[10], desc
.u
.asf
.guid
.data
[11],
90 desc
.u
.asf
.guid
.data
[12], desc
.u
.asf
.guid
.data
[13],
91 desc
.u
.asf
.guid
.data
[14], desc
.u
.asf
.guid
.data
[15]);
93 case B_MPEG_FORMAT_FAMILY
:
94 snprintf(string
, length
, "MPEG format, id 0x%lx", desc
.u
.mpeg
.id
);
96 case B_WAV_FORMAT_FAMILY
:
97 snprintf(string
, length
, "WAV format, codec id 0x%lx",
100 case B_AIFF_FORMAT_FAMILY
:
101 snprintf(string
, length
, "AIFF format, codec id 0x%lx",
104 case B_AVR_FORMAT_FAMILY
:
105 snprintf(string
, length
, "AVR format, id 0x%lx", desc
.u
.avr
.id
);
107 case B_MISC_FORMAT_FAMILY
:
108 snprintf(string
, length
, "misc format, file-format id 0x%lx, "
109 "codec id 0x%lx", desc
.u
.misc
.file_format
, desc
.u
.misc
.codec
);
112 snprintf(string
, length
, "unknown format");
123 FormatManager::FormatManager()
125 fLock("format manager"),
132 pthread_once_t
FormatManager::sInitOnce
= PTHREAD_ONCE_INIT
;
133 FormatManager
* FormatManager::sInstance
= NULL
;
137 FormatManager::CreateInstance()
139 sInstance
= new FormatManager();
143 /* static */ FormatManager
*
144 FormatManager::GetInstance()
146 pthread_once(&sInitOnce
, &CreateInstance
);
154 FormatManager::~FormatManager()
159 /*! This method is called when BMediaFormats asks for any updates
160 made to our format list.
161 If there were any changes since the last time, the whole
162 list will be sent back.
165 FormatManager::GetFormats(bigtime_t lastUpdate
, BMessage
& reply
)
167 BAutolock
locker(fLock
);
169 if (lastUpdate
>= fLastUpdate
) {
170 // There weren't any changes since last time.
171 reply
.AddBool("need_update", false);
176 // Add all meta formats to the list
177 reply
.AddBool("need_update", true);
178 reply
.AddInt64("timestamp", system_time());
180 int32 count
= fList
.CountItems();
181 for (int32 i
= 0; i
< count
; i
++) {
182 meta_format
* format
= fList
.ItemAt(i
);
183 reply
.AddData("formats", MEDIA_META_FORMAT_TYPE
, format
,
184 sizeof(meta_format
));
190 FormatManager::MakeFormatFor(const media_format_description
* descriptions
,
191 int32 descriptionCount
, media_format
& format
, uint32 flags
, void* _reserved
)
193 BAutolock
locker(fLock
);
195 int codec
= fNextCodecID
;
196 switch (format
.type
) {
197 case B_MEDIA_RAW_AUDIO
:
198 case B_MEDIA_RAW_VIDEO
:
201 case B_MEDIA_ENCODED_AUDIO
:
202 if (format
.u
.encoded_audio
.encoding
== 0) {
203 format
.u
.encoded_audio
.encoding
204 = (media_encoded_audio_format::audio_encoding
)
208 // TODO: Check the encoding and the format passed in for
209 // compatibility and return B_MISMATCHED_VALUES if incompatible
210 // or perhaps something else based on flags?
213 case B_MEDIA_ENCODED_VIDEO
:
214 if (format
.u
.encoded_video
.encoding
== 0) {
215 format
.u
.encoded_video
.encoding
216 = (media_encoded_video_format::video_encoding
)
220 // TODO: Check the encoding and the format passed in for
221 // compatibility and return B_MISMATCHED_VALUES if incompatible
222 // or perhaps something else based on flags?
225 case B_MEDIA_MULTISTREAM
:
226 if (format
.u
.multistream
.format
== 0) {
227 format
.u
.multistream
.format
= fNextCodecID
++;
230 // TODO: Check the encoding and the format passed in for
231 // compatibility and return B_MISMATCHED_VALUES if incompatible
232 // or perhaps something else based on flags?
239 fLastUpdate
= system_time();
241 status_t result
= B_OK
;
242 // TODO: Support "flags" (B_SET_DEFAULT, B_EXCLUSIVE, B_NO_MERGE)!
243 for (int32 i
= 0; i
< descriptionCount
; i
++) {
244 meta_format
* metaFormat
= new(std::nothrow
) meta_format(
245 descriptions
[i
], format
, codec
);
246 if (metaFormat
== NULL
247 || !fList
.BinaryInsert(metaFormat
, meta_format::Compare
)) {
249 result
= B_NO_MEMORY
;
259 FormatManager::RemoveFormat(const media_format
& format
)
261 BAutolock
locker(fLock
);
263 int32 foundIndex
= -1;
264 for (int32 i
= fList
.CountItems() - 1; i
>= 0; i
--) {
265 meta_format
* metaFormat
= fList
.ItemAt(i
);
266 if (metaFormat
->format
== format
) {
267 if (foundIndex
!= -1) {
268 printf("FormatManager::RemoveFormat() - format already "
269 "present at previous index: %" B_PRId32
"\n", foundIndex
);
276 delete fList
.RemoveItemAt(foundIndex
);
278 printf("FormatManager::RemoveFormat() - format not found!\n");
280 fLastUpdate
= system_time();