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