xref: /haiku/src/kits/media/MediaDefs.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 /***********************************************************************
2  * AUTHOR: Marcus Overhagen
3  *   FILE: MediaDefs.cpp
4  *  DESCR:
5  ***********************************************************************/
6 #include <MediaDefs.h>
7 #include <MediaNode.h>
8 #include <Roster.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdint.h>
12 #include "MediaMisc.h"
13 #include "debug.h"
14 
15 #define META_DATA_MAX_SIZE			(16 << 20)
16 #define META_DATA_AREA_MIN_SIZE		32000
17 
18 /*************************************************************
19  * media_destination
20  *************************************************************/
21 
22 // final
23 media_destination::media_destination(port_id port,
24 									 int32 id)
25 	: port(port),
26 	id(id)
27 {
28 }
29 
30 // final
31 media_destination::media_destination(const media_destination &clone)
32 	: port(clone.port),
33 	id(clone.id)
34 {
35 }
36 
37 // final
38 media_destination &
39 media_destination::operator=(const media_destination &clone)
40 {
41 	port = clone.port;
42 	id = clone.id;
43 	return *this;
44 }
45 
46 // final & verfied
47 media_destination::media_destination()
48 	: port(-1),
49 	id(-1)
50 {
51 }
52 
53 // final
54 media_destination::~media_destination()
55 {
56 }
57 
58 // final & verfied
59 media_destination media_destination::null(-1,-1);
60 
61 /*************************************************************
62  * media_source
63  *************************************************************/
64 
65 // final
66 media_source::media_source(port_id port,
67 						   int32 id)
68 	: port(port),
69 	id(id)
70 {
71 }
72 
73 // final
74 media_source::media_source(const media_source &clone)
75 	: port(clone.port),
76 	id(clone.id)
77 {
78 }
79 
80 // final
81 media_source &
82 media_source::operator=(const media_source &clone)
83 {
84 	port = clone.port;
85 	id = clone.id;
86 	return *this;
87 }
88 
89 // final & verfied
90 media_source::media_source()
91 	: port(-1),
92 	id(-1)
93 {
94 }
95 
96 // final
97 media_source::~media_source()
98 {
99 }
100 
101 // final & verfied
102 media_source media_source::null(-1,-1);
103 
104 /*************************************************************
105  *
106  *************************************************************/
107 
108 // final
109 bool operator==(const media_destination & a, const media_destination & b)
110 {
111 	return (a.port == b.port) && (a.id == b.id);
112 }
113 
114 // final
115 bool operator!=(const media_destination & a, const media_destination & b)
116 {
117 	return (a.port != b.port) || (a.id != b.id);
118 }
119 
120 bool operator<(const media_destination & a, const media_destination & b)
121 {
122 	UNIMPLEMENTED();
123 	return false;
124 }
125 
126 // final
127 bool operator==(const media_source & a, const media_source & b)
128 {
129 	return (a.port == b.port) && (a.id == b.id);
130 }
131 
132 // final
133 bool operator!=(const media_source & a, const media_source & b)
134 {
135 	return (a.port != b.port) || (a.id != b.id);
136 }
137 
138 bool operator<(const media_source & a, const media_source & b)
139 {
140 	UNIMPLEMENTED();
141 	return false;
142 }
143 
144 // final
145 bool operator==(const media_node & a, const media_node & b)
146 {
147 	return (a.node == b.node) && (a.port == b.port) && (a.kind == b.kind);
148 }
149 
150 // final
151 bool operator!=(const media_node & a, const media_node & b)
152 {
153 	return (a.node != b.node) || (a.port != b.port) || (a.kind != b.kind);
154 }
155 
156 bool operator<(const media_node & a, const media_node & b)
157 {
158 	UNIMPLEMENTED();
159 	return false;
160 }
161 
162 
163 /*************************************************************
164  *
165  *************************************************************/
166 
167 media_multi_audio_format media_raw_audio_format::wildcard;
168 
169 media_multi_audio_format media_multi_audio_format::wildcard;
170 
171 media_encoded_audio_format media_encoded_audio_format::wildcard = {{0}};
172 
173 media_video_display_info media_video_display_info::wildcard = {(color_space)0};
174 
175 media_raw_video_format media_raw_video_format::wildcard = {0};
176 
177 media_encoded_video_format media_encoded_video_format::wildcard = {{0}};
178 
179 media_multistream_format media_multistream_format::wildcard = {0};
180 
181 /*************************************************************
182  * helper functions for media_format::Matches()
183  *************************************************************/
184 
185 static bool raw_audio_format_matches(const media_raw_audio_format &a, const media_raw_audio_format &b);
186 static bool multi_audio_info_matches(const media_multi_audio_info &a, const media_multi_audio_info &b);
187 static bool multi_audio_format_matches(const media_multi_audio_format &a, const media_multi_audio_format &b);
188 static bool raw_video_format_matches(const media_raw_video_format &a, const media_raw_video_format &b);
189 static bool multistream_format_matches(const media_multistream_format &a, const media_multistream_format &b);
190 static bool encoded_audio_format_matches(const media_encoded_audio_format &a, const media_encoded_audio_format &b);
191 static bool encoded_video_format_matches(const media_encoded_video_format &a, const media_encoded_video_format &b);
192 
193 static bool
194 raw_audio_format_matches(const media_raw_audio_format &a, const media_raw_audio_format &b)
195 {
196 	if (a.frame_rate != 0 && b.frame_rate != 0 && a.frame_rate != b.frame_rate)
197 		return false;
198 	if (a.channel_count != 0 && b.channel_count != 0 && a.channel_count != b.channel_count)
199 		return false;
200 	if (a.format != 0 && b.format != 0 && a.format != b.format)
201 		return false;
202 	if (a.byte_order != 0 && b.byte_order != 0 && a.byte_order != b.byte_order)
203 		return false;
204 	if (a.buffer_size != 0 && b.buffer_size != 0 && a.buffer_size != b.buffer_size)
205 		return false;
206 	if (a.frame_rate != 0 && b.frame_rate != 0 && a.frame_rate != b.frame_rate)
207 		return false;
208 	return true;
209 }
210 
211 static bool
212 multi_audio_info_matches(const media_multi_audio_info &a, const media_multi_audio_info &b)
213 {
214 	if (a.channel_mask != 0 && b.channel_mask != 0 && a.channel_mask != b.channel_mask)
215 		return false;
216 	if (a.valid_bits != 0 && b.valid_bits != 0 && a.valid_bits != b.valid_bits)
217 		return false;
218 	if (a.matrix_mask != 0 && b.matrix_mask != 0 && a.matrix_mask != b.matrix_mask)
219 		return false;
220 	return true;
221 }
222 
223 static bool
224 multi_audio_format_matches(const media_multi_audio_format &a, const media_multi_audio_format &b)
225 {
226 	return raw_audio_format_matches(a, b) && multi_audio_info_matches(a, b);
227 }
228 
229 static bool
230 raw_video_format_matches(const media_raw_video_format &a, const media_raw_video_format &b)
231 {
232 	if (a.field_rate != 0 && b.field_rate != 0 && a.field_rate != b.field_rate)
233 		return false;
234 	if (a.interlace != 0 && b.interlace != 0 && a.interlace != b.interlace)
235 		return false;
236 	if (a.first_active != 0 && b.first_active != 0 && a.first_active != b.first_active)
237 		return false;
238 	if (a.last_active != 0 && b.last_active != 0 && a.last_active != b.last_active)
239 		return false;
240 	if (a.orientation != 0 && b.orientation != 0 && a.orientation != b.orientation)
241 		return false;
242 	if (a.pixel_width_aspect != 0 && b.pixel_width_aspect != 0 && a.pixel_width_aspect != b.pixel_width_aspect)
243 		return false;
244 	if (a.pixel_height_aspect != 0 && b.pixel_height_aspect != 0 && a.pixel_height_aspect != b.pixel_height_aspect)
245 		return false;
246 	if (a.display.format != 0 && b.display.format != 0 && a.display.format != b.display.format)
247 		return false;
248 	if (a.display.line_width != 0 && b.display.line_width != 0 && a.display.line_width != b.display.line_width)
249 		return false;
250 	if (a.display.line_count != 0 && b.display.line_count != 0 && a.display.line_count != b.display.line_count)
251 		return false;
252 	if (a.display.bytes_per_row != 0 && b.display.bytes_per_row != 0 && a.display.bytes_per_row != b.display.bytes_per_row)
253 		return false;
254 	if (a.display.pixel_offset != 0 && b.display.pixel_offset != 0 && a.display.pixel_offset != b.display.pixel_offset)
255 		return false;
256 	if (a.display.line_offset != 0 && b.display.line_offset != 0 && a.display.line_offset != b.display.line_offset)
257 		return false;
258 	if (a.display.flags != 0 && b.display.flags != 0 && a.display.flags != b.display.flags)
259 		return false;
260 	return true;
261 }
262 
263 static bool
264 multistream_format_matches(const media_multistream_format &a, const media_multistream_format &b)
265 {
266 	if (a.avg_bit_rate != 0 && b.avg_bit_rate != 0 && a.avg_bit_rate != b.avg_bit_rate)
267 		return false;
268 	if (a.max_bit_rate != 0 && b.max_bit_rate != 0 && a.max_bit_rate != b.max_bit_rate)
269 		return false;
270 	if (a.avg_chunk_size != 0 && b.avg_chunk_size != 0 && a.avg_chunk_size != b.avg_chunk_size)
271 		return false;
272 	if (a.max_chunk_size != 0 && b.max_chunk_size != 0 && a.max_chunk_size != b.max_chunk_size)
273 		return false;
274 	if (a.flags != 0 && b.flags != 0 && a.flags != b.flags)
275 		return false;
276 	if (a.format != 0 && b.format != 0 && a.format != b.format)
277 		return false;
278 
279 	if (a.format == 0 && b.format == 0)
280 		return true; // XXX how do we compare two formats with no type?
281 
282 	switch ((a.format != 0) ? a.format : b.format) {
283 		default:
284 			return true; // XXX really?
285 
286 		case media_multistream_format::B_VID:
287 			if (a.u.vid.frame_rate != 0 && b.u.vid.frame_rate != 0 && a.u.vid.frame_rate != b.u.vid.frame_rate)
288 				return false;
289 			if (a.u.vid.width != 0 && b.u.vid.width != 0 && a.u.vid.width != b.u.vid.width)
290 				return false;
291 			if (a.u.vid.height != 0 && b.u.vid.height != 0 && a.u.vid.height != b.u.vid.height)
292 				return false;
293 			if (a.u.vid.space != 0 && b.u.vid.space != 0 && a.u.vid.space != b.u.vid.space)
294 				return false;
295 			if (a.u.vid.sampling_rate != 0 && b.u.vid.sampling_rate != 0 && a.u.vid.sampling_rate != b.u.vid.sampling_rate)
296 				return false;
297 			if (a.u.vid.sample_format != 0 && b.u.vid.sample_format != 0 && a.u.vid.sample_format != b.u.vid.sample_format)
298 				return false;
299 			if (a.u.vid.byte_order != 0 && b.u.vid.byte_order != 0 && a.u.vid.byte_order != b.u.vid.byte_order)
300 				return false;
301 			if (a.u.vid.channel_count != 0 && b.u.vid.channel_count != 0 && a.u.vid.channel_count != b.u.vid.channel_count)
302 				return false;
303 			return true;
304 
305 		case media_multistream_format::B_AVI:
306 			if (a.u.avi.us_per_frame != 0 && b.u.avi.us_per_frame != 0 && a.u.avi.us_per_frame != b.u.avi.us_per_frame)
307 				return false;
308 			if (a.u.avi.width != 0 && b.u.avi.width != 0 && a.u.avi.width != b.u.avi.width)
309 				return false;
310 			if (a.u.avi.height != 0 && b.u.avi.height != 0 && a.u.avi.height != b.u.avi.height)
311 				return false;
312 			if (a.u.avi.type_count != 0 && b.u.avi.type_count != 0 && a.u.avi.type_count != b.u.avi.type_count)
313 				return false;
314 			if (a.u.avi.types[0] != 0 && b.u.avi.types[0] != 0 && a.u.avi.types[0] != b.u.avi.types[0])
315 				return false;
316 			if (a.u.avi.types[1] != 0 && b.u.avi.types[1] != 0 && a.u.avi.types[1] != b.u.avi.types[1])
317 				return false;
318 			if (a.u.avi.types[2] != 0 && b.u.avi.types[2] != 0 && a.u.avi.types[2] != b.u.avi.types[2])
319 				return false;
320 			if (a.u.avi.types[3] != 0 && b.u.avi.types[3] != 0 && a.u.avi.types[3] != b.u.avi.types[3])
321 				return false;
322 			if (a.u.avi.types[4] != 0 && b.u.avi.types[4] != 0 && a.u.avi.types[4] != b.u.avi.types[4])
323 				return false;
324 			return true;
325 	}
326 }
327 
328 static bool
329 encoded_audio_format_matches(const media_encoded_audio_format &a, const media_encoded_audio_format &b)
330 {
331 	if (!raw_audio_format_matches(a.output, b.output))
332 		return false;
333 	if (a.encoding != 0 && b.encoding != 0 && a.encoding != b.encoding)
334 		return false;
335 	if (a.bit_rate != 0 && b.bit_rate != 0 && a.bit_rate != b.bit_rate)
336 		return false;
337 	if (a.frame_size != 0 && b.frame_size != 0 && a.frame_size != b.frame_size)
338 		return false;
339 	if (!multi_audio_info_matches(a.multi_info, b.multi_info))
340 		return false;
341 
342 	if (a.encoding == 0 && b.encoding == 0)
343 		return true; // can't compare
344 
345 	switch((a.encoding != 0) ? a.encoding : b.encoding) {
346 		case media_encoded_audio_format::B_ANY:
347 		default:
348 			return true;
349 	}
350 }
351 
352 static bool
353 encoded_video_format_matches(const media_encoded_video_format &a, const media_encoded_video_format &b)
354 {
355 	if (!raw_video_format_matches(a.output, b.output))
356 		return false;
357 	if (a.encoding != 0 && b.encoding != 0 && a.encoding != b.encoding)
358 		return false;
359 
360 	if (a.avg_bit_rate != 0 && b.avg_bit_rate != 0 && a.avg_bit_rate != b.avg_bit_rate)
361 		return false;
362 	if (a.max_bit_rate != 0 && b.max_bit_rate != 0 && a.max_bit_rate != b.max_bit_rate)
363 		return false;
364 	if (a.frame_size != 0 && b.frame_size != 0 && a.frame_size != b.frame_size)
365 		return false;
366 	if (a.forward_history != 0 && b.forward_history != 0 && a.forward_history != b.forward_history)
367 		return false;
368 	if (a.backward_history != 0 && b.backward_history != 0 && a.backward_history != b.backward_history)
369 		return false;
370 
371 	if (a.encoding == 0 && b.encoding == 0)
372 		return true; // can't compare
373 
374 	switch((a.encoding != 0) ? a.encoding : b.encoding) {
375 		case media_encoded_video_format::B_ANY:
376 		default:
377 			return true;
378 	}
379 }
380 
381 /*************************************************************
382  * helper functions for media_format::SpecializeTo()
383  *************************************************************/
384 
385 static void raw_audio_format_specialize(media_raw_audio_format *format, const media_raw_audio_format *other);
386 static void multi_audio_info_specialize(media_multi_audio_info *format, const media_multi_audio_info *other);
387 static void multi_audio_format_specialize(media_multi_audio_format *format, const media_multi_audio_format *other);
388 static void raw_video_format_specialize(media_raw_video_format *format, const media_raw_video_format *other);
389 static void multistream_format_specialize(media_multistream_format *format, const media_multistream_format *other);
390 static void encoded_audio_format_specialize(media_encoded_audio_format *format, const media_encoded_audio_format *other);
391 static void encoded_video_format_specialize(media_encoded_video_format *format, const media_encoded_video_format *other);
392 
393 
394 static void
395 raw_audio_format_specialize(media_raw_audio_format *format, const media_raw_audio_format *other)
396 {
397 	if (format->frame_rate == 0)
398 		format->frame_rate = other->frame_rate;
399 	if (format->channel_count == 0)
400 		format->channel_count = other->channel_count;
401 	if (format->format == 0)
402 		format->format = other->format;
403 	if (format->byte_order == 0)
404 		format->byte_order = other->byte_order;
405 	if (format->buffer_size == 0)
406 		format->buffer_size = other->buffer_size;
407 	if (format->frame_rate == 0)
408 		format->frame_rate = other->frame_rate;
409 }
410 
411 static void
412 multi_audio_info_specialize(media_multi_audio_info *format, const media_multi_audio_info *other)
413 {
414 	if (format->channel_mask == 0)
415 		format->channel_mask = other->channel_mask;
416 	if (format->valid_bits == 0)
417 		format->valid_bits = other->valid_bits;
418 	if (format->matrix_mask == 0)
419 		format->matrix_mask = other->matrix_mask;
420 }
421 
422 static void
423 multi_audio_format_specialize(media_multi_audio_format *format, const media_multi_audio_format *other)
424 {
425 	raw_audio_format_specialize(format, other);
426 	multi_audio_info_specialize(format, other);
427 }
428 
429 static void
430 raw_video_format_specialize(media_raw_video_format *format, const media_raw_video_format *other)
431 {
432 	if (format->field_rate == 0)
433 		format->field_rate = other->field_rate;
434 	if (format->interlace == 0)
435 		format->interlace = other->interlace;
436 	if (format->first_active == 0)
437 		format->first_active = other->first_active;
438 	if (format->last_active == 0)
439 		format->last_active = other->last_active;
440 	if (format->orientation == 0)
441 		format->orientation = other->orientation;
442 	if (format->pixel_width_aspect == 0)
443 		format->pixel_width_aspect = other->pixel_width_aspect;
444 	if (format->pixel_height_aspect == 0)
445 		format->pixel_height_aspect = other->pixel_height_aspect;
446 	if (format->display.format == 0)
447 		format->display.format = other->display.format;
448 	if (format->display.line_width == 0)
449 		format->display.line_width = other->display.line_width;
450 	if (format->display.line_count == 0)
451 		format->display.line_count = other->display.line_count;
452 	if (format->display.bytes_per_row == 0)
453 		format->display.bytes_per_row = other->display.bytes_per_row;
454 	if (format->display.pixel_offset == 0)
455 		format->display.pixel_offset = other->display.pixel_offset;
456 	if (format->display.line_offset == 0)
457 		format->display.line_offset = other->display.line_offset;
458 	if (format->display.flags == 0)
459 		format->display.flags = other->display.flags;
460 }
461 
462 static void
463 multistream_format_specialize(media_multistream_format *format, const media_multistream_format *other)
464 {
465 	if (format->avg_bit_rate == 0)
466 		format->avg_bit_rate = other->avg_bit_rate;
467 	if (format->max_bit_rate == 0)
468 		format->max_bit_rate = other->max_bit_rate;
469 	if (format->avg_chunk_size == 0)
470 		format->avg_chunk_size = other->avg_chunk_size;
471 	if (format->max_chunk_size == 0)
472 		format->max_chunk_size = other->max_chunk_size;
473 	if (format->flags == 0)
474 		format->flags = other->flags;
475 	if (format->format == 0)
476 		format->format = other->format;
477 
478 	switch (format->format) {
479 		case media_multistream_format::B_VID:
480 			if (format->u.vid.frame_rate == 0)
481 				format->u.vid.frame_rate = other->u.vid.frame_rate;
482 			if (format->u.vid.width == 0)
483 				format->u.vid.width = other->u.vid.width;
484 			if (format->u.vid.height == 0)
485 				format->u.vid.height = other->u.vid.height;
486 			if (format->u.vid.space == 0)
487 				format->u.vid.space = other->u.vid.space;
488 			if (format->u.vid.sampling_rate == 0)
489 				format->u.vid.sampling_rate = other->u.vid.sampling_rate;
490 			if (format->u.vid.sample_format == 0)
491 				format->u.vid.sample_format = other->u.vid.sample_format;
492 			if (format->u.vid.byte_order == 0)
493 				format->u.vid.byte_order = other->u.vid.byte_order;
494 			if (format->u.vid.channel_count == 0)
495 				format->u.vid.channel_count = other->u.vid.channel_count;
496 			break;
497 
498 		case media_multistream_format::B_AVI:
499 			if (format->u.avi.us_per_frame == 0)
500 				format->u.avi.us_per_frame = other->u.avi.us_per_frame;
501 			if (format->u.avi.width == 0)
502 				format->u.avi.width = other->u.avi.width;
503 			if (format->u.avi.height == 0)
504 				format->u.avi.height = other->u.avi.height;
505 			if (format->u.avi.type_count == 0)
506 				format->u.avi.type_count = other->u.avi.type_count;
507 			if (format->u.avi.types[0] == 0)
508 				format->u.avi.types[0] = other->u.avi.types[0];
509 			if (format->u.avi.types[1] == 0)
510 				format->u.avi.types[1] = other->u.avi.types[1];
511 			if (format->u.avi.types[2] == 0)
512 				format->u.avi.types[2] = other->u.avi.types[2];
513 			if (format->u.avi.types[3] == 0)
514 				format->u.avi.types[3] = other->u.avi.types[3];
515 			if (format->u.avi.types[4] == 0)
516 				format->u.avi.types[4] = other->u.avi.types[4];
517 			break;
518 
519 		default:
520 			ERROR("media_format::SpecializeTo can't specialize media_multistream_format of format %d\n", format->format);
521 	}
522 }
523 
524 static void
525 encoded_audio_format_specialize(media_encoded_audio_format *format, const media_encoded_audio_format *other)
526 {
527 	raw_audio_format_specialize(&format->output, &other->output);
528 	if (format->encoding == 0)
529 		format->encoding = other->encoding;
530 	if (format->bit_rate == 0)
531 		format->bit_rate = other->bit_rate;
532 	if (format->frame_size == 0)
533 		format->frame_size = other->frame_size;
534 	multi_audio_info_specialize(&format->multi_info, &other->multi_info);
535 }
536 
537 static void
538 encoded_video_format_specialize(media_encoded_video_format *format, const media_encoded_video_format *other)
539 {
540 	raw_video_format_specialize(&format->output, &other->output);
541 	if (format->avg_bit_rate == 0)
542 		format->avg_bit_rate = other->avg_bit_rate;
543 	if (format->max_bit_rate == 0)
544 		format->max_bit_rate = other->max_bit_rate;
545 	if (format->encoding == 0)
546 		format->encoding = other->encoding;
547 	if (format->frame_size == 0)
548 		format->frame_size = other->frame_size;
549 	if (format->forward_history == 0)
550 		format->forward_history = other->forward_history;
551 	if (format->backward_history == 0)
552 		format->backward_history = other->backward_history;
553 }
554 
555 
556 /*************************************************************
557  * media_format
558  *************************************************************/
559 
560 bool
561 media_format::Matches(const media_format *other) const
562 {
563 	CALLED();
564 	if (type == 0 && other->type == 0)
565 		return true; // XXX how do we compare two formats with no type?
566 
567 	if (type != 0 && other->type != 0 && type != other->type)
568 		return false;
569 
570 	switch ((type != 0) ? type : other->type) {
571 		case B_MEDIA_RAW_AUDIO:
572 			return multi_audio_format_matches(u.raw_audio, other->u.raw_audio);
573 
574 		case B_MEDIA_RAW_VIDEO:
575 			return raw_video_format_matches(u.raw_video, other->u.raw_video);
576 
577 		case B_MEDIA_MULTISTREAM:
578 			return multistream_format_matches(u.multistream, other->u.multistream);
579 
580 		case B_MEDIA_ENCODED_AUDIO:
581 			return encoded_audio_format_matches(u.encoded_audio, other->u.encoded_audio);
582 
583 		case B_MEDIA_ENCODED_VIDEO:
584 			return encoded_video_format_matches(u.encoded_video, other->u.encoded_video);
585 
586 		default:
587 			return true; // XXX really?
588 	}
589 }
590 
591 void
592 media_format::SpecializeTo(const media_format *otherFormat)
593 {
594 	CALLED();
595 	if (type == 0 && otherFormat->type == 0) {
596 		ERROR("media_format::SpecializeTo can't specialize wildcard to other wildcard format\n");
597 		return;
598 	}
599 
600 	if (type == 0)
601 		type = otherFormat->type;
602 
603 	switch (type) {
604 		case B_MEDIA_RAW_AUDIO:
605 			multi_audio_format_specialize(&u.raw_audio, &otherFormat->u.raw_audio);
606 			return;
607 
608 		case B_MEDIA_RAW_VIDEO:
609 			raw_video_format_specialize(&u.raw_video, &otherFormat->u.raw_video);
610 			return;
611 
612 		case B_MEDIA_MULTISTREAM:
613 			multistream_format_specialize(&u.multistream, &otherFormat->u.multistream);
614 			return;
615 
616 		case B_MEDIA_ENCODED_AUDIO:
617 			encoded_audio_format_specialize(&u.encoded_audio, &otherFormat->u.encoded_audio);
618 			return;
619 
620 		case B_MEDIA_ENCODED_VIDEO:
621 			encoded_video_format_specialize(&u.encoded_video, &otherFormat->u.encoded_video);
622 			return;
623 
624 		default:
625 			ERROR("media_format::SpecializeTo can't specialize format type %d\n", type);
626 	}
627 }
628 
629 
630 status_t
631 media_format::SetMetaData(const void *data,
632 						  size_t size)
633 {
634 	if (!data || size < 0 || size > META_DATA_MAX_SIZE)
635 		return B_BAD_VALUE;
636 
637 	void *new_addr;
638 	area_id new_area;
639 	if (size < META_DATA_AREA_MIN_SIZE) {
640 		new_area = B_BAD_VALUE;
641 		new_addr = malloc(size);
642 		if (!new_addr)
643 			return B_NO_MEMORY;
644 	} else {
645 		new_area = create_area("meta_data_area", &new_addr, B_ANY_ADDRESS, ROUND_UP_TO_PAGE(size),
646 	                           B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
647 		if (new_area < 0)
648 			return (status_t)new_area;
649 	}
650 
651 	if (meta_data_area > 0)
652 		delete_area(meta_data_area);
653 	else
654 		free(meta_data);
655 
656 	meta_data = new_addr;
657 	meta_data_size = size;
658 	meta_data_area = new_area;
659 
660 	memcpy(meta_data, data, size);
661 
662 	if (meta_data_area > 0)
663 		set_area_protection(meta_data_area, B_READ_AREA);
664 
665 	return B_OK;
666 }
667 
668 
669 const void *
670 media_format::MetaData() const
671 {
672 	return meta_data;
673 }
674 
675 
676 int32
677 media_format::MetaDataSize() const
678 {
679 	return meta_data_size;
680 }
681 
682 
683 media_format::media_format()
684 {
685 	memset(this, 0x00, sizeof(*this));
686 	meta_data_area = B_BAD_VALUE;
687 }
688 
689 
690 media_format::media_format(const media_format &other)
691 {
692 	memset(this, 0x00, sizeof(*this));
693 	meta_data_area = B_BAD_VALUE;
694 	*this = other;
695 }
696 
697 
698 media_format::~media_format()
699 {
700 	if (meta_data_area > 0)
701 		delete_area(meta_data_area);
702 	else
703 		free(meta_data);
704 }
705 
706 
707 // final
708 media_format &
709 media_format::operator=(const media_format &clone)
710 {
711 	// get rid of this format's meta data
712 	this->~media_format(); // danger: using only ~media_format() would call the constructor
713 
714 	// make a binary copy
715 	memcpy(this, &clone, sizeof(*this));
716 	// some binary copies are invalid:
717 	meta_data = NULL;
718 	meta_data_area = B_BAD_VALUE;
719 
720 	// clone or copy the meta data
721 	if (clone.meta_data) {
722 		if (clone.meta_data_area) {
723 			meta_data_area = clone_area("meta_data_clone_area", &meta_data,
724 										B_ANY_ADDRESS, B_READ_AREA, clone.meta_data_area);
725 			if (meta_data_area < 0) {
726 				// whoops, we just lost our meta data
727 				meta_data = NULL;
728 				meta_data_size = NULL;
729 			}
730 		} else {
731 			meta_data = malloc(meta_data_size);
732 			if (meta_data) {
733 				memcpy(meta_data, clone.meta_data, meta_data_size);
734 			} else {
735 				// whoops, we just lost our meta data
736 				meta_data_size = NULL;
737 			}
738 		}
739 	}
740 	return *this;
741 }
742 
743 /*************************************************************
744  *
745  *************************************************************/
746 
747 
748 bool operator==(const media_raw_audio_format & a, const media_raw_audio_format & b)
749 {
750 	return (   a.frame_rate == b.frame_rate
751 			&& a.channel_count == b.channel_count
752 			&& a.format == b.format
753 			&& a.byte_order == b.byte_order
754 			&& a.buffer_size == b.buffer_size);
755 }
756 
757 bool operator==(const media_multi_audio_info & a, const media_multi_audio_info & b)
758 {
759 	return (   a.channel_mask == b.channel_mask
760 			&& a.valid_bits == b.valid_bits
761 			&& a.matrix_mask == b.matrix_mask);
762 }
763 
764 bool operator==(const media_multi_audio_format & a, const media_multi_audio_format & b)
765 {
766 	return (   (media_raw_audio_format)a == (media_raw_audio_format)b
767 			&& (media_multi_audio_info)a == (media_multi_audio_info)b);
768 }
769 
770 bool operator==(const media_encoded_audio_format & a, const media_encoded_audio_format & b)
771 {
772 	return (   a.output == b.output
773 			&& a.encoding == b.encoding
774 			&& a.bit_rate == b.bit_rate
775 			&& a.frame_size == b.frame_size
776 			&& a.multi_info == b.multi_info);
777 }
778 
779 bool operator==(const media_video_display_info & a, const media_video_display_info & b)
780 {
781 	return (   a.format == b.format
782 			&& a.line_width == b.line_width
783 			&& a.line_count == b.line_count
784 			&& a.bytes_per_row == b.bytes_per_row
785 			&& a.pixel_offset == b.pixel_offset
786 			&& a.line_offset == b.line_offset
787 			&& a.flags == b.flags);
788 }
789 
790 bool operator==(const media_raw_video_format & a, const media_raw_video_format & b)
791 {
792 	return (   a.field_rate == b.field_rate
793 			&& a.interlace == b.interlace
794 			&& a.first_active == b.first_active
795 			&& a.last_active == b.last_active
796 			&& a.orientation == b.orientation
797 			&& a.pixel_width_aspect == b.pixel_width_aspect
798 			&& a.pixel_height_aspect == b.pixel_height_aspect
799 			&& a.display == b.display);
800 }
801 
802 bool operator==(const media_encoded_video_format & a, const media_encoded_video_format & b)
803 {
804 	return (   a.output == b.output
805 			&& a.avg_bit_rate == b.avg_bit_rate
806 			&& a.max_bit_rate == b.max_bit_rate
807 			&& a.encoding == b.encoding
808 			&& a.frame_size == b.frame_size
809 			&& a.forward_history == b.forward_history
810 			&& a.backward_history == b.backward_history);
811 }
812 
813 bool operator==(const media_multistream_format::vid_info & a, const media_multistream_format::vid_info & b)
814 {
815 	return (   a.frame_rate == b.frame_rate
816 			&& a.width == b.width
817 			&& a.height == b.height
818 			&& a.space == b.space
819 			&& a.sampling_rate == b.sampling_rate
820 			&& a.sample_format == b.sample_format
821 			&& a.byte_order == b.byte_order
822 			&& a.channel_count == b.channel_count);
823 }
824 
825 bool operator==(const media_multistream_format::avi_info & a, const media_multistream_format::avi_info & b)
826 {
827 	return (   a.us_per_frame == b.us_per_frame
828 			&& a.width == b.width
829 			&& a.height == b.height
830 			&& a.type_count == b.type_count
831 			&& a.types[0] == b.types[0]
832 			&& a.types[1] == b.types[1]
833 			&& a.types[2] == b.types[2]
834 			&& a.types[3] == b.types[3]
835 			&& a.types[4] == b.types[4]);
836 }
837 
838 bool operator==(const media_multistream_format & a, const media_multistream_format & b)
839 {
840 	if (a.avg_bit_rate != b.avg_bit_rate
841 		|| a.max_bit_rate != b.max_bit_rate
842 		|| a.avg_chunk_size != b.avg_chunk_size
843 		|| a.max_chunk_size != b.max_chunk_size
844 		|| a.format != b.format
845 		|| a.flags != b.flags)
846 		return false;
847 
848 	switch (a.format) {
849 		case media_multistream_format::B_VID:
850 			return a.u.vid == b.u.vid;
851 
852 		case media_multistream_format::B_AVI:
853 			return a.u.avi == b.u.avi;
854 
855 		default:
856 			return true; // XXX really?
857 	}
858 }
859 
860 bool operator==(const media_format & a, const media_format & b)
861 {
862 	if (a.type != b.type
863 		|| a.user_data_type != b.user_data_type
864 		// XXX compare user_data[48] ?
865 		|| a.require_flags != b.require_flags
866 		|| a.deny_flags != b.deny_flags)
867 		return false;
868 
869 	switch (a.type) {
870 		case B_MEDIA_RAW_AUDIO:
871 			return a.u.raw_audio == b.u.raw_audio;
872 
873 		case B_MEDIA_RAW_VIDEO:
874 			return a.u.raw_video == b.u.raw_video;
875 
876 		case B_MEDIA_MULTISTREAM:
877 			return a.u.multistream == b.u.multistream;
878 
879 		case B_MEDIA_ENCODED_AUDIO:
880 			return a.u.encoded_audio == b.u.encoded_audio;
881 
882 		case B_MEDIA_ENCODED_VIDEO:
883 			return a.u.encoded_video == b.u.encoded_video;
884 
885 		default:
886 			return true; // XXX really?
887 	}
888 }
889 
890 /*************************************************************
891  *
892  *************************************************************/
893 
894 /* return true if a and b are compatible (accounting for wildcards) */
895 bool format_is_compatible(const media_format & a, const media_format & b)	/* a is the format you want to feed to something accepting b */
896 {
897 	return a.Matches(&b);
898 }
899 
900 bool string_for_format(const media_format & f, char * buf, size_t size)
901 {
902 	char encoding[10]; /* maybe Be wanted to use some 4CCs ? */
903 	const char *video_orientation = "0"; /* I'd use "NC", R5 uses 0. */
904 
905 	if (buf == NULL)
906 		return false;
907 	switch (f.type) {
908 	case B_MEDIA_RAW_AUDIO:
909 		snprintf(buf, size,
910 				"raw_audio;%g;%ld;0x%lx;%ld;0x%lx;0x%08lx;%d;0x%04x",
911 				f.u.raw_audio.frame_rate,
912 				f.u.raw_audio.channel_count,
913 				f.u.raw_audio.format,
914 				f.u.raw_audio.byte_order,
915 				f.u.raw_audio.buffer_size,
916 				f.u.raw_audio.channel_mask,
917 				f.u.raw_audio.valid_bits,
918 				f.u.raw_audio.matrix_mask);
919 		return true;
920 	case B_MEDIA_RAW_VIDEO:
921 		if (f.u.raw_video.orientation == B_VIDEO_TOP_LEFT_RIGHT)
922 			video_orientation = "TopLR";
923 		else if (f.u.raw_video.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
924 			video_orientation = "BotLR";
925 		//snprintf(buf, size, "raw_video;%g;%ld;%ld;%ld;%s;%d;%d;%d;%d;%d;%d;%d;%d",
926 		snprintf(buf, size, "raw_video;%g;0x%x;%ld;%ld;%ld;%ld;%s;%d;%d",
927 				f.u.raw_video.field_rate,
928 				f.u.raw_video.display.format,
929 				f.u.raw_video.interlace,
930 				f.u.raw_video.display.line_width,
931 				f.u.raw_video.display.line_count,
932 				f.u.raw_video.first_active,
933 				video_orientation,
934 				f.u.raw_video.pixel_width_aspect,
935 				f.u.raw_video.pixel_height_aspect);
936 		return true;
937 	case B_MEDIA_ENCODED_AUDIO:
938 		snprintf(encoding, 10, "%d", f.u.encoded_audio.encoding);
939 		snprintf(buf, size,
940 				"caudio;%s;%g;%ld;(%g;%ld;0x%lx;%ld;0x%lx;0x%08lx;%d;0x%04x)",
941 				encoding, // f.u.encoded_audio.encoding,
942 				f.u.encoded_audio.bit_rate,
943 				f.u.encoded_audio.frame_size,
944 				// (
945 				f.u.encoded_audio.output.frame_rate,
946 				f.u.encoded_audio.output.channel_count,
947 				f.u.encoded_audio.output.format,
948 				f.u.encoded_audio.output.byte_order,
949 				f.u.encoded_audio.output.buffer_size,
950 				f.u.encoded_audio.multi_info.channel_mask,
951 				f.u.encoded_audio.multi_info.valid_bits,
952 				f.u.encoded_audio.multi_info.matrix_mask);
953 				// )
954 		return true;
955 	case B_MEDIA_ENCODED_VIDEO:
956 		snprintf(encoding, 10, "%d", f.u.encoded_video.encoding);
957 		if (f.u.encoded_video.output.orientation == B_VIDEO_TOP_LEFT_RIGHT)
958 			video_orientation = "TopLR";
959 		else if (f.u.encoded_video.output.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
960 			video_orientation = "BotLR";
961 		snprintf(buf, size,
962 				"cvideo;%s;%g;%g;%ld;(%g;0x%x;%ld;%ld;%ld;%ld;%s;%d;%d)",
963 				encoding,
964 				f.u.encoded_video.avg_bit_rate,
965 				f.u.encoded_video.max_bit_rate,
966 				f.u.encoded_video.frame_size,
967 				// (
968 				f.u.encoded_video.output.field_rate,
969 				f.u.encoded_video.output.display.format,
970 				f.u.encoded_video.output.interlace,
971 				f.u.encoded_video.output.display.line_width,
972 				f.u.encoded_video.output.display.line_count,
973 				f.u.encoded_video.output.first_active,
974 				video_orientation,
975 				f.u.encoded_video.output.pixel_width_aspect,
976 				f.u.encoded_video.output.pixel_height_aspect);
977 				// )
978 		return true;
979 	default:
980 		snprintf(buf, size, "%d-", f.type);
981 		unsigned char *p = (unsigned char *)&(f.u);
982 		size -= strlen(buf);
983 		buf += strlen(buf);
984 		for (int i = 0; (size > 2) && (i < 96); i++) {
985 			snprintf(buf, 3, "%2.2x", *(p + i));
986 			buf+=2;
987 			size-=2;
988 		}
989 		return true; // ?
990 	}
991 	return false;
992 }
993 
994 /*************************************************************
995  *
996  *************************************************************/
997 
998 bool operator==(const media_file_format_id & a, const media_file_format_id & b)
999 {
1000 	UNIMPLEMENTED();
1001 	return false;
1002 }
1003 
1004 bool operator<(const media_file_format_id & a, const media_file_format_id & b)
1005 {
1006 	UNIMPLEMENTED();
1007 	return false;
1008 }
1009 
1010 /*************************************************************
1011  *
1012  *************************************************************/
1013 
1014 //
1015 // Use this function iterate through available file format writers
1016 //
1017 status_t get_next_file_format(int32 *cookie, media_file_format *mfi)
1018 {
1019 	UNIMPLEMENTED();
1020 	return B_ERROR;
1021 }
1022 
1023 
1024 /*************************************************************
1025  *
1026  *************************************************************/
1027 
1028 // final & verified
1029 const char * B_MEDIA_SERVER_SIGNATURE = "application/x-vnd.Be.media-server";
1030 const char * B_MEDIA_ADDON_SERVER_SIGNATURE = "application/x-vnd.Be.addon-host";
1031 
1032 const type_code B_CODEC_TYPE_INFO = 0x040807b2;
1033 
1034 /*************************************************************
1035  *
1036  *************************************************************/
1037 
1038 struct dormant_node_info
1039 {
1040 };
1041 
1042 struct buffer_clone_info
1043 {
1044 };
1045 
1046 /*************************************************************
1047  *
1048  *************************************************************/
1049 
1050 
1051 // shutdown_media_server() and launch_media_server()
1052 // are provided by libbe.so in BeOS R5
1053 
1054 status_t
1055 shutdown_media_server(bigtime_t timeout,
1056 	bool (*progress)(int stage, const char * message, void * cookie),
1057 	void * cookie)
1058 {
1059 	BMessage msg(B_QUIT_REQUESTED);
1060 	BMessage reply;
1061 	status_t err;
1062 
1063 	if ((err = msg.AddBool("be:_user_request", true)) != B_OK)
1064 		return err;
1065 
1066 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1067 		BMessenger messenger(B_MEDIA_SERVER_SIGNATURE);
1068 		progress(10, "Telling media_server to quit.", cookie);
1069 
1070 		if ((err = messenger.SendMessage(&msg, &reply, 2000000, 2000000)) != B_OK)
1071 			return err;
1072 
1073 		int32 rv;
1074 		if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1075 			return rv;
1076 	}
1077 
1078 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1079 		BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE);
1080 		progress(20, "Telling media_addon_server to quit.", cookie);
1081 
1082 		if ((err = messenger.SendMessage(&msg, &reply, 2000000, 2000000)) != B_OK)
1083 			return err;
1084 
1085 		int32 rv;
1086 		if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1087 			return rv;
1088 	}
1089 
1090 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1091 		progress(40, "Waiting for media_server to quit.", cookie);
1092 		snooze(200000);
1093 	}
1094 
1095 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1096 		progress(50, "Waiting for media_addon_server to quit.", cookie);
1097 		snooze(200000);
1098 	}
1099 
1100 	progress(70, "Cleaning Up.", cookie);
1101 	snooze(1000000);
1102 
1103 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1104 		kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE));
1105 	}
1106 
1107 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1108 		kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE));
1109 	}
1110 
1111 	progress(100, "Done Shutting Down.", cookie);
1112 	snooze(1000000);
1113 
1114 	return B_OK;
1115 }
1116 
1117 
1118 status_t
1119 launch_media_server(uint32 flags)
1120 {
1121 	status_t err;
1122 
1123 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE))
1124 		return B_ALREADY_RUNNING;
1125 
1126 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1127 		kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE));
1128 		snooze(1000000);
1129 	}
1130 
1131 	err = be_roster->Launch(B_MEDIA_SERVER_SIGNATURE);
1132 	if (err != B_OK)
1133 		return err;
1134 
1135 	err = B_MEDIA_SYSTEM_FAILURE;
1136 	for (int i = 0; i < 15; i++) {
1137 		snooze(2000000);
1138 
1139 		BMessage msg(1); // this is a hack
1140 		BMessage reply;
1141 		BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE);
1142 
1143 		if (messenger.IsValid()) {
1144 			messenger.SendMessage(&msg, &reply, 2000000, 2000000);
1145 			err = B_OK;
1146 			break;
1147 		}
1148 	}
1149 
1150 	return err;
1151 }
1152 
1153 
1154 /*************************************************************
1155  *
1156  *************************************************************/
1157 
1158 
1159 //	Given an image_id, prepare that image_id for realtime media
1160 //	If the kind of media indicated by "flags" is not enabled for real-time,
1161 //	B_MEDIA_REALTIME_DISABLED is returned.
1162 //	If there are not enough system resources to enable real-time performance,
1163 //	B_MEDIA_REALTIME_UNAVAILABLE is returned.
1164 status_t media_realtime_init_image(image_id image, uint32 flags)
1165 {
1166 	UNIMPLEMENTED();
1167 	return B_OK;
1168 }
1169 
1170 //	Given a thread ID, and an optional indication of what the thread is
1171 //	doing in "flags", prepare the thread for real-time media performance.
1172 //	Currently, this means locking the thread stack, up to size_used bytes,
1173 //	or all of it if 0 is passed. Typically, you will not be using all
1174 //	256 kB of the stack, so you should pass some smaller value you determine
1175 //	from profiling the thread; typically in the 32-64kB range.
1176 //	Return values are the same as for media_prepare_realtime_image().
1177 status_t media_realtime_init_thread(thread_id thread, size_t stack_used, uint32 flags)
1178 {
1179 	UNIMPLEMENTED();
1180 	return B_OK;
1181 }
1182 
1183 /*************************************************************
1184  * media_encode_info
1185  *************************************************************/
1186 
1187 
1188 media_encode_info::media_encode_info()
1189 {
1190 	flags = 0;
1191 	used_data_size = 0;
1192 	start_time = 0;
1193 	time_to_encode = INT64_MAX;
1194 	file_format_data = NULL;
1195 	file_format_data_size = 0;
1196 	codec_data = NULL;
1197 	codec_data_size = 0;
1198 }
1199 
1200 
1201 media_decode_info::media_decode_info()
1202 {
1203 	time_to_decode = INT64_MAX;
1204 	file_format_data = NULL;
1205 	file_format_data_size = 0;
1206 	codec_data = NULL;
1207 	codec_data_size = 0;
1208 }
1209 
1210 
1211