xref: /haiku/src/kits/media/MediaDefs.cpp (revision 4f2fd49bdc6078128b1391191e4edac647044c3d)
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 <inttypes.h>
10 #include <stdio.h>
11 #include <string.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 "
521 				"media_multistream_format of format %ld\n", format->format);
522 	}
523 }
524 
525 static void
526 encoded_audio_format_specialize(media_encoded_audio_format *format,
527 	const media_encoded_audio_format *other)
528 {
529 	raw_audio_format_specialize(&format->output, &other->output);
530 	if (format->encoding == 0)
531 		format->encoding = other->encoding;
532 	if (format->bit_rate == 0)
533 		format->bit_rate = other->bit_rate;
534 	if (format->frame_size == 0)
535 		format->frame_size = other->frame_size;
536 	multi_audio_info_specialize(&format->multi_info, &other->multi_info);
537 }
538 
539 static void
540 encoded_video_format_specialize(media_encoded_video_format *format,
541 	const media_encoded_video_format *other)
542 {
543 	raw_video_format_specialize(&format->output, &other->output);
544 	if (format->avg_bit_rate == 0)
545 		format->avg_bit_rate = other->avg_bit_rate;
546 	if (format->max_bit_rate == 0)
547 		format->max_bit_rate = other->max_bit_rate;
548 	if (format->encoding == 0)
549 		format->encoding = other->encoding;
550 	if (format->frame_size == 0)
551 		format->frame_size = other->frame_size;
552 	if (format->forward_history == 0)
553 		format->forward_history = other->forward_history;
554 	if (format->backward_history == 0)
555 		format->backward_history = other->backward_history;
556 }
557 
558 
559 /*************************************************************
560  * media_format
561  *************************************************************/
562 
563 bool
564 media_format::Matches(const media_format *other) const
565 {
566 	CALLED();
567 	if (type == 0 && other->type == 0)
568 		return true; // XXX how do we compare two formats with no type?
569 
570 	if (type != 0 && other->type != 0 && type != other->type)
571 		return false;
572 
573 	switch ((type != 0) ? type : other->type) {
574 		case B_MEDIA_RAW_AUDIO:
575 			return multi_audio_format_matches(u.raw_audio, other->u.raw_audio);
576 
577 		case B_MEDIA_RAW_VIDEO:
578 			return raw_video_format_matches(u.raw_video, other->u.raw_video);
579 
580 		case B_MEDIA_MULTISTREAM:
581 			return multistream_format_matches(u.multistream, other->u.multistream);
582 
583 		case B_MEDIA_ENCODED_AUDIO:
584 			return encoded_audio_format_matches(u.encoded_audio, other->u.encoded_audio);
585 
586 		case B_MEDIA_ENCODED_VIDEO:
587 			return encoded_video_format_matches(u.encoded_video, other->u.encoded_video);
588 
589 		default:
590 			return true; // XXX really?
591 	}
592 }
593 
594 void
595 media_format::SpecializeTo(const media_format *otherFormat)
596 {
597 	CALLED();
598 	if (type == 0 && otherFormat->type == 0) {
599 		ERROR("media_format::SpecializeTo can't specialize wildcard to other wildcard format\n");
600 		return;
601 	}
602 
603 	if (type == 0)
604 		type = otherFormat->type;
605 
606 	switch (type) {
607 		case B_MEDIA_RAW_AUDIO:
608 			multi_audio_format_specialize(&u.raw_audio, &otherFormat->u.raw_audio);
609 			return;
610 
611 		case B_MEDIA_RAW_VIDEO:
612 			raw_video_format_specialize(&u.raw_video, &otherFormat->u.raw_video);
613 			return;
614 
615 		case B_MEDIA_MULTISTREAM:
616 			multistream_format_specialize(&u.multistream, &otherFormat->u.multistream);
617 			return;
618 
619 		case B_MEDIA_ENCODED_AUDIO:
620 			encoded_audio_format_specialize(&u.encoded_audio, &otherFormat->u.encoded_audio);
621 			return;
622 
623 		case B_MEDIA_ENCODED_VIDEO:
624 			encoded_video_format_specialize(&u.encoded_video, &otherFormat->u.encoded_video);
625 			return;
626 
627 		default:
628 			ERROR("media_format::SpecializeTo can't specialize format type %d\n", type);
629 	}
630 }
631 
632 
633 status_t
634 media_format::SetMetaData(const void *data,
635 						  size_t size)
636 {
637 	if (!data || size < 0 || size > META_DATA_MAX_SIZE)
638 		return B_BAD_VALUE;
639 
640 	void *new_addr;
641 	area_id new_area;
642 	if (size < META_DATA_AREA_MIN_SIZE) {
643 		new_area = B_BAD_VALUE;
644 		new_addr = malloc(size);
645 		if (!new_addr)
646 			return B_NO_MEMORY;
647 	} else {
648 		new_area = create_area("meta_data_area", &new_addr, B_ANY_ADDRESS, ROUND_UP_TO_PAGE(size),
649 	                           B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
650 		if (new_area < 0)
651 			return (status_t)new_area;
652 	}
653 
654 	if (meta_data_area > 0)
655 		delete_area(meta_data_area);
656 	else
657 		free(meta_data);
658 
659 	meta_data = new_addr;
660 	meta_data_size = size;
661 	meta_data_area = new_area;
662 
663 	memcpy(meta_data, data, size);
664 
665 	if (meta_data_area > 0)
666 		set_area_protection(meta_data_area, B_READ_AREA);
667 
668 	return B_OK;
669 }
670 
671 
672 const void *
673 media_format::MetaData() const
674 {
675 	return meta_data;
676 }
677 
678 
679 int32
680 media_format::MetaDataSize() const
681 {
682 	return meta_data_size;
683 }
684 
685 
686 media_format::media_format()
687 {
688 	memset(this, 0x00, sizeof(*this));
689 	meta_data_area = B_BAD_VALUE;
690 }
691 
692 
693 media_format::media_format(const media_format &other)
694 {
695 	memset(this, 0x00, sizeof(*this));
696 	meta_data_area = B_BAD_VALUE;
697 	*this = other;
698 }
699 
700 
701 media_format::~media_format()
702 {
703 	if (meta_data_area > 0)
704 		delete_area(meta_data_area);
705 	else
706 		free(meta_data);
707 }
708 
709 
710 // final
711 media_format &
712 media_format::operator=(const media_format &clone)
713 {
714 	// get rid of this format's meta data
715 	this->~media_format(); // danger: using only ~media_format() would call the constructor
716 
717 	// make a binary copy
718 	memcpy(this, &clone, sizeof(*this));
719 	// some binary copies are invalid:
720 	meta_data = NULL;
721 	meta_data_area = B_BAD_VALUE;
722 
723 	// clone or copy the meta data
724 	if (clone.meta_data) {
725 		if (clone.meta_data_area) {
726 			meta_data_area = clone_area("meta_data_clone_area", &meta_data,
727 										B_ANY_ADDRESS, B_READ_AREA, clone.meta_data_area);
728 			if (meta_data_area < 0) {
729 				// whoops, we just lost our meta data
730 				meta_data = NULL;
731 				meta_data_size = 0;
732 			}
733 		} else {
734 			meta_data = malloc(meta_data_size);
735 			if (meta_data) {
736 				memcpy(meta_data, clone.meta_data, meta_data_size);
737 			} else {
738 				// whoops, we just lost our meta data
739 				meta_data_size = 0;
740 			}
741 		}
742 	}
743 	return *this;
744 }
745 
746 /*************************************************************
747  *
748  *************************************************************/
749 
750 
751 bool operator==(const media_raw_audio_format & a, const media_raw_audio_format & b)
752 {
753 	return (   a.frame_rate == b.frame_rate
754 			&& a.channel_count == b.channel_count
755 			&& a.format == b.format
756 			&& a.byte_order == b.byte_order
757 			&& a.buffer_size == b.buffer_size);
758 }
759 
760 bool operator==(const media_multi_audio_info & a, const media_multi_audio_info & b)
761 {
762 	return (   a.channel_mask == b.channel_mask
763 			&& a.valid_bits == b.valid_bits
764 			&& a.matrix_mask == b.matrix_mask);
765 }
766 
767 bool operator==(const media_multi_audio_format & a, const media_multi_audio_format & b)
768 {
769 	return (   (media_raw_audio_format)a == (media_raw_audio_format)b
770 			&& (media_multi_audio_info)a == (media_multi_audio_info)b);
771 }
772 
773 bool operator==(const media_encoded_audio_format & a, const media_encoded_audio_format & b)
774 {
775 	return (   a.output == b.output
776 			&& a.encoding == b.encoding
777 			&& a.bit_rate == b.bit_rate
778 			&& a.frame_size == b.frame_size
779 			&& a.multi_info == b.multi_info);
780 }
781 
782 bool operator==(const media_video_display_info & a, const media_video_display_info & b)
783 {
784 	return (   a.format == b.format
785 			&& a.line_width == b.line_width
786 			&& a.line_count == b.line_count
787 			&& a.bytes_per_row == b.bytes_per_row
788 			&& a.pixel_offset == b.pixel_offset
789 			&& a.line_offset == b.line_offset
790 			&& a.flags == b.flags);
791 }
792 
793 bool operator==(const media_raw_video_format & a, const media_raw_video_format & b)
794 {
795 	return (   a.field_rate == b.field_rate
796 			&& a.interlace == b.interlace
797 			&& a.first_active == b.first_active
798 			&& a.last_active == b.last_active
799 			&& a.orientation == b.orientation
800 			&& a.pixel_width_aspect == b.pixel_width_aspect
801 			&& a.pixel_height_aspect == b.pixel_height_aspect
802 			&& a.display == b.display);
803 }
804 
805 bool operator==(const media_encoded_video_format & a, const media_encoded_video_format & b)
806 {
807 	return (   a.output == b.output
808 			&& a.avg_bit_rate == b.avg_bit_rate
809 			&& a.max_bit_rate == b.max_bit_rate
810 			&& a.encoding == b.encoding
811 			&& a.frame_size == b.frame_size
812 			&& a.forward_history == b.forward_history
813 			&& a.backward_history == b.backward_history);
814 }
815 
816 bool operator==(const media_multistream_format::vid_info & a, const media_multistream_format::vid_info & b)
817 {
818 	return (   a.frame_rate == b.frame_rate
819 			&& a.width == b.width
820 			&& a.height == b.height
821 			&& a.space == b.space
822 			&& a.sampling_rate == b.sampling_rate
823 			&& a.sample_format == b.sample_format
824 			&& a.byte_order == b.byte_order
825 			&& a.channel_count == b.channel_count);
826 }
827 
828 bool operator==(const media_multistream_format::avi_info & a, const media_multistream_format::avi_info & b)
829 {
830 	return (   a.us_per_frame == b.us_per_frame
831 			&& a.width == b.width
832 			&& a.height == b.height
833 			&& a.type_count == b.type_count
834 			&& a.types[0] == b.types[0]
835 			&& a.types[1] == b.types[1]
836 			&& a.types[2] == b.types[2]
837 			&& a.types[3] == b.types[3]
838 			&& a.types[4] == b.types[4]);
839 }
840 
841 bool operator==(const media_multistream_format & a, const media_multistream_format & b)
842 {
843 	if (a.avg_bit_rate != b.avg_bit_rate
844 		|| a.max_bit_rate != b.max_bit_rate
845 		|| a.avg_chunk_size != b.avg_chunk_size
846 		|| a.max_chunk_size != b.max_chunk_size
847 		|| a.format != b.format
848 		|| a.flags != b.flags)
849 		return false;
850 
851 	switch (a.format) {
852 		case media_multistream_format::B_VID:
853 			return a.u.vid == b.u.vid;
854 
855 		case media_multistream_format::B_AVI:
856 			return a.u.avi == b.u.avi;
857 
858 		default:
859 			return true; // XXX really?
860 	}
861 }
862 
863 bool operator==(const media_format & a, const media_format & b)
864 {
865 	if (a.type != b.type
866 		|| a.user_data_type != b.user_data_type
867 		// XXX compare user_data[48] ?
868 		|| a.require_flags != b.require_flags
869 		|| a.deny_flags != b.deny_flags)
870 		return false;
871 
872 	switch (a.type) {
873 		case B_MEDIA_RAW_AUDIO:
874 			return a.u.raw_audio == b.u.raw_audio;
875 
876 		case B_MEDIA_RAW_VIDEO:
877 			return a.u.raw_video == b.u.raw_video;
878 
879 		case B_MEDIA_MULTISTREAM:
880 			return a.u.multistream == b.u.multistream;
881 
882 		case B_MEDIA_ENCODED_AUDIO:
883 			return a.u.encoded_audio == b.u.encoded_audio;
884 
885 		case B_MEDIA_ENCODED_VIDEO:
886 			return a.u.encoded_video == b.u.encoded_video;
887 
888 		default:
889 			return true; // XXX really?
890 	}
891 }
892 
893 /*************************************************************
894  *
895  *************************************************************/
896 
897 /* return true if a and b are compatible (accounting for wildcards) */
898 bool format_is_compatible(const media_format & a, const media_format & b)	/* a is the format you want to feed to something accepting b */
899 {
900 	return a.Matches(&b);
901 }
902 
903 bool string_for_format(const media_format & f, char * buf, size_t size)
904 {
905 	char encoding[10]; /* maybe Be wanted to use some 4CCs ? */
906 	const char *video_orientation = "0"; /* I'd use "NC", R5 uses 0. */
907 
908 	if (buf == NULL)
909 		return false;
910 	switch (f.type) {
911 	case B_MEDIA_RAW_AUDIO:
912 		snprintf(buf, size,
913 				"raw_audio;%g;%ld;0x%lx;%ld;0x%lx;0x%08lx;%d;0x%04x",
914 				f.u.raw_audio.frame_rate,
915 				f.u.raw_audio.channel_count,
916 				f.u.raw_audio.format,
917 				f.u.raw_audio.byte_order,
918 				f.u.raw_audio.buffer_size,
919 				f.u.raw_audio.channel_mask,
920 				f.u.raw_audio.valid_bits,
921 				f.u.raw_audio.matrix_mask);
922 		return true;
923 	case B_MEDIA_RAW_VIDEO:
924 		if (f.u.raw_video.orientation == B_VIDEO_TOP_LEFT_RIGHT)
925 			video_orientation = "TopLR";
926 		else if (f.u.raw_video.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
927 			video_orientation = "BotLR";
928 		//snprintf(buf, size, "raw_video;%g;%ld;%ld;%ld;%s;%d;%d;%d;%d;%d;%d;%d;%d",
929 		snprintf(buf, size, "raw_video;%g;0x%x;%ld;%ld;%ld;%ld;%s;%d;%d",
930 				f.u.raw_video.field_rate,
931 				f.u.raw_video.display.format,
932 				f.u.raw_video.interlace,
933 				f.u.raw_video.display.line_width,
934 				f.u.raw_video.display.line_count,
935 				f.u.raw_video.first_active,
936 				video_orientation,
937 				f.u.raw_video.pixel_width_aspect,
938 				f.u.raw_video.pixel_height_aspect);
939 		return true;
940 	case B_MEDIA_ENCODED_AUDIO:
941 		snprintf(encoding, 10, "%d", f.u.encoded_audio.encoding);
942 		snprintf(buf, size,
943 				"caudio;%s;%g;%ld;(%g;%ld;0x%lx;%ld;0x%lx;0x%08lx;%d;0x%04x)",
944 				encoding, // f.u.encoded_audio.encoding,
945 				f.u.encoded_audio.bit_rate,
946 				f.u.encoded_audio.frame_size,
947 				// (
948 				f.u.encoded_audio.output.frame_rate,
949 				f.u.encoded_audio.output.channel_count,
950 				f.u.encoded_audio.output.format,
951 				f.u.encoded_audio.output.byte_order,
952 				f.u.encoded_audio.output.buffer_size,
953 				f.u.encoded_audio.multi_info.channel_mask,
954 				f.u.encoded_audio.multi_info.valid_bits,
955 				f.u.encoded_audio.multi_info.matrix_mask);
956 				// )
957 		return true;
958 	case B_MEDIA_ENCODED_VIDEO:
959 		snprintf(encoding, 10, "%d", f.u.encoded_video.encoding);
960 		if (f.u.encoded_video.output.orientation == B_VIDEO_TOP_LEFT_RIGHT)
961 			video_orientation = "TopLR";
962 		else if (f.u.encoded_video.output.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
963 			video_orientation = "BotLR";
964 		snprintf(buf, size,
965 				"cvideo;%s;%g;%g;%ld;(%g;0x%x;%ld;%ld;%ld;%ld;%s;%d;%d)",
966 				encoding,
967 				f.u.encoded_video.avg_bit_rate,
968 				f.u.encoded_video.max_bit_rate,
969 				f.u.encoded_video.frame_size,
970 				// (
971 				f.u.encoded_video.output.field_rate,
972 				f.u.encoded_video.output.display.format,
973 				f.u.encoded_video.output.interlace,
974 				f.u.encoded_video.output.display.line_width,
975 				f.u.encoded_video.output.display.line_count,
976 				f.u.encoded_video.output.first_active,
977 				video_orientation,
978 				f.u.encoded_video.output.pixel_width_aspect,
979 				f.u.encoded_video.output.pixel_height_aspect);
980 				// )
981 		return true;
982 	default:
983 		snprintf(buf, size, "%d-", f.type);
984 		unsigned char *p = (unsigned char *)&(f.u);
985 		size -= strlen(buf);
986 		buf += strlen(buf);
987 		for (int i = 0; (size > 2) && (i < 96); i++) {
988 			snprintf(buf, 3, "%2.2x", *(p + i));
989 			buf+=2;
990 			size-=2;
991 		}
992 		return true; // ?
993 	}
994 	return false;
995 }
996 
997 /*************************************************************
998  *
999  *************************************************************/
1000 
1001 bool operator==(const media_file_format_id & a, const media_file_format_id & b)
1002 {
1003 	UNIMPLEMENTED();
1004 	return false;
1005 }
1006 
1007 bool operator<(const media_file_format_id & a, const media_file_format_id & b)
1008 {
1009 	UNIMPLEMENTED();
1010 	return false;
1011 }
1012 
1013 /*************************************************************
1014  *
1015  *************************************************************/
1016 
1017 //
1018 // Use this function iterate through available file format writers
1019 //
1020 status_t get_next_file_format(int32 *cookie, media_file_format *mfi)
1021 {
1022 	UNIMPLEMENTED();
1023 	return B_ERROR;
1024 }
1025 
1026 
1027 /*************************************************************
1028  *
1029  *************************************************************/
1030 
1031 // final & verified
1032 const char * B_MEDIA_SERVER_SIGNATURE = "application/x-vnd.Be.media-server";
1033 const char * B_MEDIA_ADDON_SERVER_SIGNATURE = "application/x-vnd.Be.addon-host";
1034 
1035 const type_code B_CODEC_TYPE_INFO = 0x040807b2;
1036 
1037 /*************************************************************
1038  *
1039  *************************************************************/
1040 
1041 struct dormant_node_info
1042 {
1043 };
1044 
1045 struct buffer_clone_info
1046 {
1047 };
1048 
1049 /*************************************************************
1050  *
1051  *************************************************************/
1052 
1053 
1054 // shutdown_media_server() and launch_media_server()
1055 // are provided by libbe.so in BeOS R5
1056 
1057 status_t
1058 shutdown_media_server(bigtime_t timeout,
1059 	bool (*progress)(int stage, const char * message, void * cookie),
1060 	void * cookie)
1061 {
1062 	BMessage msg(B_QUIT_REQUESTED);
1063 	BMessage reply;
1064 	status_t err;
1065 
1066 	if ((err = msg.AddBool("be:_user_request", true)) != B_OK)
1067 		return err;
1068 
1069 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1070 		BMessenger messenger(B_MEDIA_SERVER_SIGNATURE);
1071 		progress(10, "Telling media_server to quit.", cookie);
1072 
1073 		if ((err = messenger.SendMessage(&msg, &reply, 2000000, 2000000)) != B_OK)
1074 			return err;
1075 
1076 		int32 rv;
1077 		if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1078 			return rv;
1079 	}
1080 
1081 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1082 		BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE);
1083 		progress(20, "Telling media_addon_server to quit.", cookie);
1084 
1085 		if ((err = messenger.SendMessage(&msg, &reply, 2000000, 2000000)) != B_OK)
1086 			return err;
1087 
1088 		int32 rv;
1089 		if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1090 			return rv;
1091 	}
1092 
1093 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1094 		progress(40, "Waiting for media_server to quit.", cookie);
1095 		snooze(200000);
1096 	}
1097 
1098 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1099 		progress(50, "Waiting for media_addon_server to quit.", cookie);
1100 		snooze(200000);
1101 	}
1102 
1103 	progress(70, "Cleaning Up.", cookie);
1104 	snooze(1000000);
1105 
1106 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1107 		kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE));
1108 	}
1109 
1110 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1111 		kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE));
1112 	}
1113 
1114 	progress(100, "Done Shutting Down.", cookie);
1115 	snooze(1000000);
1116 
1117 	return B_OK;
1118 }
1119 
1120 
1121 status_t
1122 launch_media_server(uint32 flags)
1123 {
1124 	status_t err;
1125 
1126 	if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE))
1127 		return B_ALREADY_RUNNING;
1128 
1129 	if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1130 		kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE));
1131 		snooze(1000000);
1132 	}
1133 
1134 	err = be_roster->Launch(B_MEDIA_SERVER_SIGNATURE);
1135 	if (err != B_OK)
1136 		return err;
1137 
1138 	err = B_MEDIA_SYSTEM_FAILURE;
1139 	for (int i = 0; i < 15; i++) {
1140 		snooze(2000000);
1141 
1142 		BMessage msg(1); // this is a hack
1143 		BMessage reply;
1144 		BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE);
1145 
1146 		if (messenger.IsValid()) {
1147 			messenger.SendMessage(&msg, &reply, 2000000, 2000000);
1148 			err = B_OK;
1149 			break;
1150 		}
1151 	}
1152 
1153 	return err;
1154 }
1155 
1156 
1157 /*************************************************************
1158  *
1159  *************************************************************/
1160 
1161 
1162 //	Given an image_id, prepare that image_id for realtime media
1163 //	If the kind of media indicated by "flags" is not enabled for real-time,
1164 //	B_MEDIA_REALTIME_DISABLED is returned.
1165 //	If there are not enough system resources to enable real-time performance,
1166 //	B_MEDIA_REALTIME_UNAVAILABLE is returned.
1167 status_t media_realtime_init_image(image_id image, uint32 flags)
1168 {
1169 	UNIMPLEMENTED();
1170 	return B_OK;
1171 }
1172 
1173 //	Given a thread ID, and an optional indication of what the thread is
1174 //	doing in "flags", prepare the thread for real-time media performance.
1175 //	Currently, this means locking the thread stack, up to size_used bytes,
1176 //	or all of it if 0 is passed. Typically, you will not be using all
1177 //	256 kB of the stack, so you should pass some smaller value you determine
1178 //	from profiling the thread; typically in the 32-64kB range.
1179 //	Return values are the same as for media_prepare_realtime_image().
1180 status_t media_realtime_init_thread(thread_id thread, size_t stack_used, uint32 flags)
1181 {
1182 	UNIMPLEMENTED();
1183 	return B_OK;
1184 }
1185 
1186 /*************************************************************
1187  * media_encode_info
1188  *************************************************************/
1189 
1190 
1191 media_encode_info::media_encode_info()
1192 {
1193 	flags = 0;
1194 	used_data_size = 0;
1195 	start_time = 0;
1196 	time_to_encode = INT64_MAX;
1197 	file_format_data = NULL;
1198 	file_format_data_size = 0;
1199 	codec_data = NULL;
1200 	codec_data_size = 0;
1201 }
1202 
1203 
1204 media_decode_info::media_decode_info()
1205 {
1206 	time_to_decode = INT64_MAX;
1207 	file_format_data = NULL;
1208 	file_format_data_size = 0;
1209 	codec_data = NULL;
1210 	codec_data_size = 0;
1211 }
1212 
1213 
1214