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