xref: /haiku/src/apps/cortex/Persistence/Wrappers/MediaFormatIO.cpp (revision 922e7ba1f3228e6f28db69b0ded8f86eb32dea17)
1 // MediaFormatIO.cpp
2 // e.moon 2jul99
3 
4 #include "MediaFormatIO.h"
5 //#include "xml_export_utils.h"
6 
7 __USE_CORTEX_NAMESPACE
8 
9 // -------------------------------------------------------- //
10 // *** constants
11 // -------------------------------------------------------- //
12 
13 // these tags map directly to MediaFormatIO
14 const char* const MediaFormatIO::s_multi_audio_tag 			= "multi_audio_format";
15 const char* const MediaFormatIO::s_raw_audio_tag 				= "raw_audio_format";
16 const char* const MediaFormatIO::s_raw_video_tag 				= "raw_video_format";
17 const char* const MediaFormatIO::s_multistream_tag 			= "multistream_format";
18 const char* const MediaFormatIO::s_encoded_audio_tag 		= "encoded_audio_format";
19 const char* const MediaFormatIO::s_encoded_video_tag 		= "encoded_video_format";
20 
21 // nested tags
22 const char* const MediaFormatIO::s_video_display_info_tag		= "video_display_info";
23 const char* const MediaFormatIO::s_multistream_flags_tag			= "multistream_flags";
24 const char* const MediaFormatIO::s_multistream_vid_info_tag	= "multistream_vid_info";
25 const char* const MediaFormatIO::s_multistream_avi_info_tag	= "multistream_avi_info";
26 const char* const MediaFormatIO::s_multi_audio_info_tag			= "multi_audio_info";
27 const char* const MediaFormatIO::s_media_type_tag						= "media_type";
28 
29 // -------------------------------------------------------- //
30 // *** ctor/dtor
31 // -------------------------------------------------------- //
32 
33 MediaFormatIO::~MediaFormatIO() {}
34 
35 MediaFormatIO::MediaFormatIO() :
36 	m_complete(false) {}
37 MediaFormatIO::MediaFormatIO(const media_format& format) :
38 	m_complete(true),
39 	m_format(format) {}
40 
41 // -------------------------------------------------------- //
42 // *** accessors
43 // -------------------------------------------------------- //
44 
45 // returns B_OK if the object contains a valid format,
46 // or B_ERROR if not.
47 
48 status_t MediaFormatIO::getFormat(media_format& outFormat) const {
49 	if(!m_complete)
50 		return B_ERROR;
51 	outFormat = m_format;
52 	return B_OK;
53 }
54 
55 // -------------------------------------------------------- //
56 // *** static setup method
57 // -------------------------------------------------------- //
58 
59 // call this method to install hooks for the tags needed by
60 // MediaFormatIO
61 
62 /*static*/
63 void MediaFormatIO::AddTo(XML::DocumentType* pDocType) {
64 
65 	pDocType->addMapping(new Mapping
66 		<MediaFormatIO>(s_multi_audio_tag));
67 	pDocType->addMapping(new Mapping
68 		<MediaFormatIO>(s_raw_audio_tag));
69 	pDocType->addMapping(new Mapping
70 		<MediaFormatIO>(s_raw_video_tag));
71 	pDocType->addMapping(new Mapping
72 		<MediaFormatIO>(s_multistream_tag));
73 	pDocType->addMapping(new Mapping
74 		<MediaFormatIO>(s_encoded_audio_tag));
75 	pDocType->addMapping(new Mapping
76 		<MediaFormatIO>(s_encoded_video_tag));
77 }
78 
79 // -------------------------------------------------------- //
80 // *** IPersistent
81 // -------------------------------------------------------- //
82 
83 // -------------------------------------------------------- //
84 // attribute constants
85 // -------------------------------------------------------- //
86 
87 // *** raw_audio_format
88 const char* const gKey_frame_rate							= "frame_rate";
89 const char* const gKey_channel_count					= "channel_count";
90 const char* const gKey_format									= "format";
91 const char* const gKey_byte_order							= "byte_order";
92 const char* const gKey_buffer_size						= "buffer_size";
93 
94 // *** +multi_audio_format
95 const char* const gKey_channel_mask						= "channel_mask";
96 const char* const gKey_valid_bits							= "valid_bits";
97 const char* const gKey_matrix_mask						= "matrix_mask";
98 
99 // *** raw_video_format
100 const char* const gKey_field_rate							= "field_rate";
101 const char* const gKey_interlace							= "interlace";
102 const char* const gKey_first_active						= "first_active";
103 const char* const gKey_last_active						= "last_active";
104 const char* const gKey_orientation						= "orientation";
105 const char* const gKey_pixel_width_aspect			= "pixel_width_aspect";
106 const char* const gKey_pixel_height_aspect		= "pixel_height_aspect";
107 
108 // *** video_display_info
109 const char* const gKey_color_space						= "color_space";
110 const char* const gKey_line_width							= "line_width";
111 const char* const gKey_line_count							= "line_count";
112 const char* const gKey_bytes_per_row					= "bytes_per_row";
113 const char* const gKey_pixel_offset						= "pixel_offset";
114 const char* const gKey_line_offset						= "line_offset";
115 
116 // *** multistream_format
117 const char* const gKey_multistream_format			= "format";
118 const char* const gKey_avg_bit_rate						= "avg_bit_rate";
119 const char* const gKey_max_bit_rate						= "max_bit_rate";
120 const char* const gKey_avg_chunk_size					= "avg_chunk_size";
121 const char* const gKey_max_chunk_size					= "max_chunk_size";
122 
123 // *** multistream_flags
124 const char* const gKey_header_has_flags				= "header_has_flags";
125 const char* const gKey_clean_buffers					= "clean_buffers";
126 const char* const gKey_homogenous_buffers			= "homogenous_buffers";
127 
128 // *** multistream_vid_info
129 // frame_rate
130 const char* const gKey_width									= "width";
131 const char* const gKey_height									= "height";
132 const char* const gKey_space									= "space";
133 const char* const gKey_sampling_rate					= "sampling_rate";
134 const char* const gKey_sample_format					= "sample_format";
135 // byte_order
136 // channel_count
137 
138 // *** multistream_avi_info
139 const char* const gKey_us_per_frame						= "us_per_frame";
140 // width
141 // height
142 
143 // *** encoded_audio_format
144 const char* const gKey_encoding								= "encoding";
145 const char* const gKey_bit_rate								= "bit_rate";
146 const char* const gKey_frame_size							= "frame_size";
147 
148 // *** encoded_video_format
149 // encoding
150 // avg_bit_rate
151 // max_bit_rate
152 // frame_size
153 const char* const gKey_forward_history				= "forward_history";
154 const char* const gKey_backward_history				= "backward_history";
155 
156 // padding (number of spaces allowed for attribute name)
157 const int16 g_padAttributes		= 30;
158 
159 // -------------------------------------------------------- //
160 // export
161 // -------------------------------------------------------- //
162 
163 void write_colorspace_attr(
164 	const char* key,
165 	color_space c,
166 	ExportContext& context) {
167 
168 	switch(c) {
169 		case B_RGB32:
170 			context.writeAttr(key, "B_RGB32");
171 			break;
172 		case B_RGBA32:
173 			context.writeAttr(key, "B_RGBA32");
174 			break;
175 		case B_RGB24:
176 			context.writeAttr(key, "B_RGB24");
177 			break;
178 		case B_RGB16:
179 			context.writeAttr(key, "B_RGB16");
180 			break;
181 		case B_RGB15:
182 			context.writeAttr(key, "B_RGB15");
183 			break;
184 		case B_RGBA15:
185 			context.writeAttr(key, "B_RGBA15");
186 			break;
187 		case B_CMAP8:
188 			context.writeAttr(key, "B_CMAP8");
189 			break;
190 		case B_GRAY8:
191 			context.writeAttr(key, "B_GRAY8");
192 			break;
193 		case B_GRAY1:
194 			context.writeAttr(key, "B_GRAY1");
195 			break;
196 		case B_RGB32_BIG:
197 			context.writeAttr(key, "B_RGB32_BIG");
198 			break;
199 		case B_RGBA32_BIG:
200 			context.writeAttr(key, "B_RGBA32_BIG");
201 			break;
202 		case B_RGB24_BIG:
203 			context.writeAttr(key, "B_RGB24_BIG");
204 			break;
205 		case B_RGB16_BIG:
206 			context.writeAttr(key, "B_RGB16_BIG");
207 			break;
208 		case B_RGB15_BIG:
209 			context.writeAttr(key, "B_RGB15_BIG");
210 			break;
211 		case B_RGBA15_BIG:
212 			context.writeAttr(key, "B_RGBA15_BIG");
213 			break;
214 		case B_YCbCr422:
215 			context.writeAttr(key, "B_YCbCr422");
216 			break;
217 		case B_YCbCr411:
218 			context.writeAttr(key, "B_YCbCr411");
219 			break;
220 		case B_YCbCr444:
221 			context.writeAttr(key, "B_YCbCr444");
222 			break;
223 		case B_YCbCr420:
224 			context.writeAttr(key, "B_YCbCr420");
225 			break;
226 		case B_YUV422:
227 			context.writeAttr(key, "B_YUV422");
228 			break;
229 		case B_YUV411:
230 			context.writeAttr(key, "B_YUV411");
231 			break;
232 		case B_YUV444:
233 			context.writeAttr(key, "B_YUV444");
234 			break;
235 		case B_YUV420:
236 			context.writeAttr(key, "B_YUV420");
237 			break;
238 		case B_YUV9:
239 			context.writeAttr(key, "B_YUV9");
240 			break;
241 		case B_YUV12:
242 			context.writeAttr(key, "B_YUV12");
243 			break;
244 		case B_UVL24:
245 			context.writeAttr(key, "B_UVL24");
246 			break;
247 		case B_UVL32:
248 			context.writeAttr(key, "B_UVL32");
249 			break;
250 		case B_UVLA32:
251 			context.writeAttr(key, "B_UVLA32");
252 			break;
253 		case B_LAB24:
254 			context.writeAttr(key, "B_LAB24");
255 			break;
256 		case B_LAB32:
257 			context.writeAttr(key, "B_LAB32");
258 			break;
259 		case B_LABA32:
260 			context.writeAttr(key, "B_LABA32");
261 			break;
262 		case B_HSI24:
263 			context.writeAttr(key, "B_HSI24");
264 			break;
265 		case B_HSI32:
266 			context.writeAttr(key, "B_HSI32");
267 			break;
268 		case B_HSIA32:
269 			context.writeAttr(key, "B_HSIA32");
270 			break;
271 		case B_HSV24:
272 			context.writeAttr(key, "B_HSV24");
273 			break;
274 		case B_HSV32:
275 			context.writeAttr(key, "B_HSV32");
276 			break;
277 		case B_HSVA32:
278 			context.writeAttr(key, "B_HSVA32");
279 			break;
280 		case B_HLS24:
281 			context.writeAttr(key, "B_HLS24");
282 			break;
283 		case B_HLS32:
284 			context.writeAttr(key, "B_HLS32");
285 			break;
286 		case B_HLSA32:
287 			context.writeAttr(key, "B_HLSA32");
288 			break;
289 		case B_CMY24:
290 			context.writeAttr(key, "B_CMY24");
291 			break;
292 		case B_CMY32:
293 			context.writeAttr(key, "B_CMY32");
294 			break;
295 		case B_CMYA32:
296 			context.writeAttr(key, "B_CMYA32");
297 			break;
298 		case B_CMYK32:
299 			context.writeAttr(key, "B_CMYK32");
300 			break;
301 		default:
302 			break;
303 	}
304 }
305 
306 void import_color_space(
307 	const char* value,
308 	color_space& dest) {
309 
310 	if(!strcmp(value, "B_RGB32"))
311 		dest = B_RGB32;
312 	else if(!strcmp(value, "B_RGBA32"))
313 		dest = B_RGBA32;
314 	else if(!strcmp(value, "B_RGB24"))
315 		dest = B_RGB24;
316 	else if(!strcmp(value, "B_RGB16"))
317 		dest = B_RGB16;
318 	else if(!strcmp(value, "B_RGB15"))
319 		dest = B_RGB15;
320 	else if(!strcmp(value, "B_RGBA15"))
321 		dest = B_RGBA15;
322 	else if(!strcmp(value, "B_CMAP8"))
323 		dest = B_CMAP8;
324 	else if(!strcmp(value, "B_GRAY8"))
325 		dest = B_GRAY8;
326 	else if(!strcmp(value, "B_GRAY1"))
327 		dest = B_GRAY1;
328 	else if(!strcmp(value, "B_RGB32_BIG"))
329 		dest = B_RGB32_BIG;
330 	else if(!strcmp(value, "B_RGBA32_BIG"))
331 		dest = B_RGBA32_BIG;
332 	else if(!strcmp(value, "B_RGB24_BIG"))
333 		dest = B_RGB24_BIG;
334 	else if(!strcmp(value, "B_RGB16_BIG"))
335 		dest = B_RGB16_BIG;
336 	else if(!strcmp(value, "B_RGB15_BIG"))
337 		dest = B_RGB15_BIG;
338 	else if(!strcmp(value, "B_RGBA15_BIG"))
339 		dest = B_RGBA15_BIG;
340 	else if(!strcmp(value, "B_RGB32_LITTLE"))
341 		dest = B_RGB32_LITTLE;
342 	else if(!strcmp(value, "B_RGBA32_LITTLE"))
343 		dest = B_RGBA32_LITTLE;
344 	else if(!strcmp(value, "B_RGB24_LITTLE"))
345 		dest = B_RGB24_LITTLE;
346 	else if(!strcmp(value, "B_RGB16_LITTLE"))
347 		dest = B_RGB16_LITTLE;
348 	else if(!strcmp(value, "B_RGB15_LITTLE"))
349 		dest = B_RGB15_LITTLE;
350 	else if(!strcmp(value, "B_RGBA15_LITTLE"))
351 		dest = B_RGBA15_LITTLE;
352 	else if(!strcmp(value, "B_YCbCr422"))
353 		dest = B_YCbCr422;
354 	else if(!strcmp(value, "B_YCbCr411"))
355 		dest = B_YCbCr411;
356 	else if(!strcmp(value, "B_YCbCr444"))
357 		dest = B_YCbCr444;
358 	else if(!strcmp(value, "B_YCbCr420"))
359 		dest = B_YCbCr420;
360 	else if(!strcmp(value, "B_YUV422"))
361 		dest = B_YUV422;
362 	else if(!strcmp(value, "B_YUV411"))
363 		dest = B_YUV411;
364 	else if(!strcmp(value, "B_YUV444"))
365 		dest = B_YUV444;
366 	else if(!strcmp(value, "B_YUV420"))
367 		dest = B_YUV420;
368 	else if(!strcmp(value, "B_YUV9"))
369 		dest = B_YUV9;
370 	else if(!strcmp(value, "B_YUV12"))
371 		dest = B_YUV12;
372 	else if(!strcmp(value, "B_UVL24"))
373 		dest = B_UVL24;
374 	else if(!strcmp(value, "B_UVL32"))
375 		dest = B_UVL32;
376 	else if(!strcmp(value, "B_UVLA32"))
377 		dest = B_UVLA32;
378 	else if(!strcmp(value, "B_LAB24"))
379 		dest = B_LAB24;
380 	else if(!strcmp(value, "B_LAB32"))
381 		dest = B_LAB32;
382 	else if(!strcmp(value, "B_LABA32"))
383 		dest = B_LABA32;
384 	else if(!strcmp(value, "B_HSI24"))
385 		dest = B_HSI24;
386 	else if(!strcmp(value, "B_HSI32"))
387 		dest = B_HSI32;
388 	else if(!strcmp(value, "B_HSIA32"))
389 		dest = B_HSIA32;
390 	else if(!strcmp(value, "B_HSV24"))
391 		dest = B_HSV24;
392 	else if(!strcmp(value, "B_HSV32"))
393 		dest = B_HSV32;
394 	else if(!strcmp(value, "B_HSVA32"))
395 		dest = B_HSVA32;
396 	else if(!strcmp(value, "B_HLS24"))
397 		dest = B_HLS24;
398 	else if(!strcmp(value, "B_HLS32"))
399 		dest = B_HLS32;
400 	else if(!strcmp(value, "B_HLSA32"))
401 		dest = B_HLSA32;
402 	else if(!strcmp(value, "B_CMY24"))
403 		dest = B_CMY24;
404 	else if(!strcmp(value, "B_CMY32"))
405 		dest = B_CMY32;
406 	else if(!strcmp(value, "B_CMYA32"))
407 		dest = B_CMYA32;
408 	else if(!strcmp(value, "B_CMYK32"))
409 		dest = B_CMYK32;
410 }
411 
412 void write_media_type(
413 	media_type t,
414 	ExportContext& context) {
415 
416 	context.beginElement(MediaFormatIO::s_media_type_tag);
417 	context.beginContent();
418 
419 	switch(t) {
420 		case B_MEDIA_NO_TYPE:
421 			context.writeString("B_MEDIA_NO_TYPE");
422 			break;
423 		case B_MEDIA_UNKNOWN_TYPE:
424 			context.writeString("B_MEDIA_UNKNOWN_TYPE");
425 			break;
426 		case B_MEDIA_RAW_AUDIO:
427 			context.writeString("B_MEDIA_RAW_AUDIO");
428 			break;
429 		case B_MEDIA_RAW_VIDEO:
430 			context.writeString("B_MEDIA_RAW_VIDEO");
431 			break;
432 		case B_MEDIA_VBL:
433 			context.writeString("B_MEDIA_VBL");
434 			break;
435 		case B_MEDIA_TIMECODE:
436 			context.writeString("B_MEDIA_TIMECODE");
437 			break;
438 		case B_MEDIA_MIDI:
439 			context.writeString("B_MEDIA_MIDI");
440 			break;
441 		case B_MEDIA_TEXT:
442 			context.writeString("B_MEDIA_TEXT");
443 			break;
444 		case B_MEDIA_HTML:
445 			context.writeString("B_MEDIA_HTML");
446 			break;
447 		case B_MEDIA_MULTISTREAM:
448 			context.writeString("B_MEDIA_MULTISTREAM");
449 			break;
450 		case B_MEDIA_PARAMETERS:
451 			context.writeString("B_MEDIA_PARAMETERS");
452 			break;
453 		case B_MEDIA_ENCODED_AUDIO:
454 			context.writeString("B_MEDIA_ENCODED_AUDIO");
455 			break;
456 		case B_MEDIA_ENCODED_VIDEO:
457 			context.writeString("B_MEDIA_ENCODED_VIDEO");
458 			break;
459 		default: {
460 			BString val;
461 			val << (uint32)t;
462 			context.writeString(val);
463 		}
464 	}
465 	context.endElement();
466 }
467 
468 void import_media_type_content(
469 	media_multistream_format::avi_info& f,
470 	const char* value,
471 	ImportContext& context) {
472 
473 	if(f.type_count == 5) {
474 		// ignore
475 		// +++++ should this be an error?
476 		context.reportWarning("Ignoring media_type: maximum of 5 reached.");
477 		return;
478 	}
479 
480 	if(!strcmp(value, "B_MEDIA_NO_TYPE"))
481 		f.types[f.type_count] = B_MEDIA_NO_TYPE;
482 	else if(!strcmp(value, "B_MEDIA_UNKNOWN_TYPE"))
483 		f.types[f.type_count] = B_MEDIA_UNKNOWN_TYPE;
484 	else if(!strcmp(value, "B_MEDIA_RAW_AUDIO"))
485 		f.types[f.type_count] = B_MEDIA_RAW_AUDIO;
486 	else if(!strcmp(value, "B_MEDIA_RAW_VIDEO"))
487 		f.types[f.type_count] = B_MEDIA_RAW_VIDEO;
488 	else if(!strcmp(value, "B_MEDIA_VBL"))
489 		f.types[f.type_count] = B_MEDIA_VBL;
490 	else if(!strcmp(value, "B_MEDIA_TIMECODE"))
491 		f.types[f.type_count] = B_MEDIA_TIMECODE;
492 	else if(!strcmp(value, "B_MEDIA_MIDI"))
493 		f.types[f.type_count] = B_MEDIA_MIDI;
494 	else if(!strcmp(value, "B_MEDIA_TEXT"))
495 		f.types[f.type_count] = B_MEDIA_TEXT;
496 	else if(!strcmp(value, "B_MEDIA_HTML"))
497 		f.types[f.type_count] = B_MEDIA_HTML;
498 	else if(!strcmp(value, "B_MEDIA_MULTISTREAM"))
499 		f.types[f.type_count] = B_MEDIA_MULTISTREAM;
500 	else if(!strcmp(value, "B_MEDIA_PARAMETERS"))
501 		f.types[f.type_count] = B_MEDIA_PARAMETERS;
502 	else if(!strcmp(value, "B_MEDIA_ENCODED_AUDIO"))
503 		f.types[f.type_count] = B_MEDIA_ENCODED_AUDIO;
504 	else if(!strcmp(value, "B_MEDIA_ENCODED_VIDEO"))
505 		f.types[f.type_count] = B_MEDIA_ENCODED_VIDEO;
506 	else
507 		f.types[f.type_count] = (media_type)atol(value);
508 
509 	++f.type_count;
510 }
511 
512 
513 void export_raw_audio_attr(
514 	const media_raw_audio_format& f,
515 	ExportContext& context) {
516 
517 	media_raw_audio_format& w = media_raw_audio_format::wildcard;
518 
519 	if(f.frame_rate != w.frame_rate)
520 		context.writeAttr(gKey_frame_rate, f.frame_rate);
521 	if(f.channel_count != w.channel_count)
522 		context.writeAttr(gKey_channel_count, f.channel_count);
523 	if(f.buffer_size != w.buffer_size)
524 		context.writeAttr(gKey_buffer_size, f.buffer_size);
525 
526 	switch(f.format) {
527 		case media_raw_audio_format::B_AUDIO_UCHAR:
528 			context.writeAttr(gKey_format, "B_AUDIO_UCHAR");
529 			break;
530 		case media_raw_audio_format::B_AUDIO_SHORT:
531 			context.writeAttr(gKey_format, "B_AUDIO_SHORT");
532 			break;
533 		case media_raw_audio_format::B_AUDIO_FLOAT:
534 			context.writeAttr(gKey_format, "B_AUDIO_FLOAT");
535 			break;
536 		case media_raw_audio_format::B_AUDIO_INT:
537 			context.writeAttr(gKey_format, "B_AUDIO_INT");
538 			break;
539 		default:
540 			break;
541 	}
542 
543 	switch(f.byte_order) {
544 		case B_MEDIA_BIG_ENDIAN:
545 			context.writeAttr(gKey_byte_order, "B_MEDIA_BIG_ENDIAN");
546 			break;
547 		case B_MEDIA_LITTLE_ENDIAN:
548 			context.writeAttr(gKey_byte_order, "B_MEDIA_LITTLE_ENDIAN");
549 			break;
550 		default:
551 			break;
552 	}
553 }
554 
555 #if B_BEOS_VERSION > B_BEOS_VERSION_4_5
556 
557 void export_multi_audio_info_attr(
558 	const media_multi_audio_info& f,
559 	ExportContext& context) {
560 
561 	media_multi_audio_format& w = media_multi_audio_format::wildcard;
562 
563 	if(f.channel_mask != w.channel_mask)
564 		context.writeAttr(gKey_channel_mask, f.channel_mask);
565 
566 	if(f.valid_bits != w.valid_bits)
567 		context.writeAttr(gKey_valid_bits, f.valid_bits);
568 
569 	if(f.matrix_mask != w.matrix_mask)
570 		context.writeAttr(gKey_matrix_mask, f.matrix_mask);
571 }
572 #endif
573 
574 void export_video_display_info_attr(
575 	const media_video_display_info& d,
576 	ExportContext& context) {
577 
578 	media_video_display_info& w = media_video_display_info::wildcard;
579 
580 	if(d.line_width != w.line_width)
581 		context.writeAttr(gKey_line_width, d.line_width);
582 	if(d.line_count != w.line_count)
583 		context.writeAttr(gKey_line_count, d.line_count);
584 	if(d.bytes_per_row != w.bytes_per_row)
585 		context.writeAttr(gKey_bytes_per_row, d.bytes_per_row);
586 	if(d.pixel_offset != w.pixel_offset)
587 		context.writeAttr(gKey_pixel_offset, d.pixel_offset);
588 	if(d.line_offset != w.line_offset)
589 		context.writeAttr(gKey_line_offset, d.line_offset);
590 
591 	if(d.format != w.format)
592 		write_colorspace_attr(gKey_format, d.format, context);
593 }
594 
595 
596 void export_raw_video_attr(
597 	const media_raw_video_format& f,
598 	ExportContext& context) {
599 
600 	media_raw_video_format& w = media_raw_video_format::wildcard;
601 
602 	// attributes
603 	if(f.field_rate != w.field_rate)
604 		context.writeAttr(gKey_field_rate, f.field_rate);
605 	if(f.interlace != w.interlace)
606 		context.writeAttr(gKey_interlace, f.interlace);
607 	if(f.first_active != w.first_active)
608 		context.writeAttr(gKey_first_active, f.first_active);
609 	if(f.last_active != w.last_active)
610 		context.writeAttr(gKey_last_active, f.last_active);
611 	if(f.pixel_width_aspect != w.pixel_width_aspect)
612 		context.writeAttr(gKey_pixel_width_aspect, (uint32)f.pixel_width_aspect);
613 	if(f.pixel_height_aspect != w.pixel_height_aspect)
614 		context.writeAttr(gKey_pixel_height_aspect, (uint32)f.pixel_height_aspect);
615 
616 	switch(f.orientation) {
617 		case B_VIDEO_TOP_LEFT_RIGHT:
618 			context.writeAttr(gKey_orientation, "B_VIDEO_TOP_LEFT_RIGHT");
619 			break;
620 		case B_VIDEO_BOTTOM_LEFT_RIGHT:
621 			context.writeAttr(gKey_orientation, "B_VIDEO_BOTTOM_LEFT_RIGHT");
622 			break;
623 		default:
624 			break;
625 	}
626 }
627 
628 void export_raw_video_content(
629 	const media_raw_video_format& f,
630 	ExportContext& context) {
631 
632 	context.beginContent();
633 	context.beginElement(MediaFormatIO::s_video_display_info_tag);
634 	export_video_display_info_attr(f.display, context);
635 	context.endElement();
636 }
637 
638 void export_multistream_flags_attr(
639 	uint32 flags,
640 	ExportContext& context) {
641 
642 	if(flags & media_multistream_format::B_HEADER_HAS_FLAGS)
643 		context.writeAttr(gKey_header_has_flags, (int32)1);
644 
645 	if(flags & media_multistream_format::B_CLEAN_BUFFERS)
646 		context.writeAttr(gKey_clean_buffers, (int32)1);
647 
648 	if(flags & media_multistream_format::B_HOMOGENOUS_BUFFERS)
649 		context.writeAttr(gKey_homogenous_buffers, (int32)1);
650 }
651 
652 void export_multistream_vid_info_attr(
653 	media_multistream_format::vid_info f,
654 	ExportContext& context) {
655 
656 	// +++++ no wildcard to compare against (assume 0 == wildcard?)
657 
658 	context.writeAttr(gKey_frame_rate, f.frame_rate);
659 	context.writeAttr(gKey_width, (uint32)f.width);
660 	context.writeAttr(gKey_height, (uint32)f.height);
661 	write_colorspace_attr(gKey_space, f.space, context);
662 	context.writeAttr(gKey_sampling_rate, f.sampling_rate);
663 
664 	switch(f.sample_format) {
665 		case B_UNDEFINED_SAMPLES:
666 			context.writeAttr(gKey_sample_format, "B_UNDEFINED_SAMPLES");
667 			break;
668 		case B_LINEAR_SAMPLES:
669 			context.writeAttr(gKey_sample_format, "B_LINEAR_SAMPLES");
670 			break;
671 		case B_FLOAT_SAMPLES:
672 			context.writeAttr(gKey_sample_format, "B_FLOAT_SAMPLES");
673 			break;
674 		case B_MULAW_SAMPLES:
675 			context.writeAttr(gKey_sample_format, "B_MULAW_SAMPLES");
676 			break;
677 		default:
678 			break;
679 	}
680 
681 	switch(f.byte_order) {
682 		case B_MEDIA_BIG_ENDIAN:
683 			context.writeAttr(gKey_byte_order, "B_MEDIA_BIG_ENDIAN");
684 			break;
685 		case B_MEDIA_LITTLE_ENDIAN:
686 			context.writeAttr(gKey_byte_order, "B_MEDIA_LITTLE_ENDIAN");
687 			break;
688 		default:
689 			break;
690 	}
691 
692 	context.writeAttr(gKey_channel_count, (uint32)f.channel_count);
693 }
694 
695 void export_multistream_avi_info_attr(
696 	media_multistream_format::avi_info f,
697 	ExportContext& context) {
698 
699 	context.writeAttr(gKey_us_per_frame, f.us_per_frame);
700 	context.writeAttr(gKey_width, (uint32)f.width);
701 	context.writeAttr(gKey_height, (uint32)f.height);
702 }
703 
704 void export_multistream_avi_info_content(
705 	media_multistream_format::avi_info f,
706 	ExportContext& context) {
707 
708 	context.beginContent();
709 
710 	for(uint16 n = 0; n < f.type_count; ++n)
711 		write_media_type(f.types[n], context);
712 }
713 
714 void export_multistream_attr(
715 	const media_multistream_format& f,
716 	ExportContext& context) {
717 
718 	media_multistream_format& w = media_multistream_format::wildcard;
719 
720 	// attributes
721 	switch(f.format) {
722 		case media_multistream_format::B_ANY:
723 			context.writeAttr(gKey_multistream_format, "B_ANY");
724 			break;
725 		case media_multistream_format::B_VID:
726 			context.writeAttr(gKey_multistream_format, "B_VID");
727 			break;
728 		case media_multistream_format::B_AVI:
729 			context.writeAttr(gKey_multistream_format, "B_AVI");
730 			break;
731 		case media_multistream_format::B_MPEG1:
732 			context.writeAttr(gKey_multistream_format, "B_MPEG1");
733 			break;
734 		case media_multistream_format::B_MPEG2:
735 			context.writeAttr(gKey_multistream_format, "B_MPEG2");
736 			break;
737 		case media_multistream_format::B_QUICKTIME:
738 			context.writeAttr(gKey_multistream_format, "B_QUICKTIME");
739 			break;
740 		default:
741 			if(f.format != w.format) {
742 				// write numeric value
743 				context.writeAttr(gKey_multistream_format, f.format);
744 			}
745 			break;
746 	}
747 
748 	if(f.avg_bit_rate != w.avg_bit_rate)
749 		context.writeAttr(gKey_avg_bit_rate, f.avg_bit_rate);
750 	if(f.max_bit_rate != w.max_bit_rate)
751 		context.writeAttr(gKey_max_bit_rate, f.max_bit_rate);
752 	if(f.avg_chunk_size != w.avg_chunk_size)
753 		context.writeAttr(gKey_avg_chunk_size, f.avg_chunk_size);
754 	if(f.max_chunk_size != w.max_chunk_size)
755 		context.writeAttr(gKey_max_chunk_size, f.max_chunk_size);
756 }
757 
758 void export_multistream_content(
759 	const media_multistream_format& f,
760 	ExportContext& context) {
761 
762 	context.beginContent();
763 
764 	// write flags
765 	context.beginElement(MediaFormatIO::s_multistream_flags_tag);
766 	export_multistream_flags_attr(f.flags, context);
767 	context.endElement();
768 
769 	// write format-specific info
770 	if(f.format == media_multistream_format::B_VID) {
771 		context.beginElement(MediaFormatIO::s_multistream_vid_info_tag);
772 		export_multistream_vid_info_attr(f.u.vid, context);
773 		context.endElement();
774 	}
775 	else if(f.format == media_multistream_format::B_AVI) {
776 		context.beginElement(MediaFormatIO::s_multistream_avi_info_tag);
777 		export_multistream_avi_info_attr(f.u.avi, context);
778 		context.beginContent();
779 		export_multistream_avi_info_content(f.u.avi, context);
780 		context.endElement();
781 	}
782 }
783 
784 void export_encoded_audio_attr(
785 	const media_encoded_audio_format& f,
786 	ExportContext& context) {
787 
788 	media_encoded_audio_format& w = media_encoded_audio_format::wildcard;
789 
790 	switch(f.encoding) {
791 		case media_encoded_audio_format::B_ANY:
792 			context.writeAttr(gKey_encoding, "B_ANY");
793 			break;
794 		default:
795 			break;
796 	}
797 
798 	if(f.bit_rate != w.bit_rate)
799 		context.writeAttr(gKey_bit_rate, f.bit_rate);
800 
801 	if(f.frame_size != w.frame_size)
802 		context.writeAttr(gKey_frame_size, f.frame_size);
803 }
804 
805 void export_encoded_audio_content(
806 	const media_encoded_audio_format& f,
807 	ExportContext& context) {
808 
809 	context.beginContent();
810 
811 	context.beginElement(MediaFormatIO::s_raw_audio_tag);
812 	export_raw_audio_attr(f.output, context);
813 
814 #if B_BEOS_VERSION > B_BEOS_VERSION_4_5
815 	export_multi_audio_info_attr(f.multi_info, context);
816 #endif
817 
818 	context.endElement();
819 }
820 
821 void export_encoded_video_attr(
822 	const media_encoded_video_format& f,
823 	ExportContext& context) {
824 
825 	media_encoded_video_format& w = media_encoded_video_format::wildcard;
826 
827 	switch(f.encoding) {
828 		case media_encoded_video_format::B_ANY:
829 			context.writeAttr(gKey_encoding, "B_ANY");
830 			break;
831 		default:
832 			break;
833 	}
834 
835 	if(f.avg_bit_rate != w.avg_bit_rate)
836 		context.writeAttr(gKey_avg_bit_rate, f.avg_bit_rate);
837 	if(f.max_bit_rate != w.max_bit_rate)
838 		context.writeAttr(gKey_max_bit_rate, f.max_bit_rate);
839 	if(f.frame_size != w.frame_size)
840 		context.writeAttr(gKey_frame_size, f.frame_size);
841 	if(f.forward_history != w.forward_history)
842 		context.writeAttr(gKey_forward_history, (int32)f.forward_history);
843 	if(f.backward_history != w.backward_history)
844 		context.writeAttr(gKey_backward_history, (int32)f.backward_history);
845 }
846 
847 void export_encoded_video_content(
848 	const media_encoded_video_format& f,
849 	ExportContext& context) {
850 
851 	context.beginContent();
852 
853 	context.beginElement(MediaFormatIO::s_raw_video_tag);
854 	export_raw_video_attr(f.output, context);
855 	context.endElement();
856 }
857 
858 
859 void MediaFormatIO::xmlExportBegin(
860 	ExportContext&		context) const {
861 
862 	switch(m_format.type) {
863 
864 		case B_MEDIA_RAW_AUDIO:
865 			context.beginElement(s_raw_audio_tag);
866 			break;
867 
868 		case B_MEDIA_RAW_VIDEO:
869 			context.beginElement(s_raw_video_tag);
870 			break;
871 
872 		case B_MEDIA_MULTISTREAM:
873 			context.beginElement(s_multistream_tag);
874 			break;
875 
876 		case B_MEDIA_ENCODED_AUDIO:
877 			context.beginElement(s_encoded_audio_tag);
878 			break;
879 
880 		case B_MEDIA_ENCODED_VIDEO:
881 			context.beginElement(s_encoded_video_tag);
882 			break;
883 
884 		default:
885 			// +++++ not very polite
886 			context.reportError("MediaFormatIO: type not supported\n");
887 			break;
888 	}
889 }
890 
891 void MediaFormatIO::xmlExportAttributes(
892 	ExportContext&		context) const {
893 
894 	switch(m_format.type) {
895 		case B_MEDIA_RAW_AUDIO:
896 			export_raw_audio_attr(m_format.u.raw_audio, context);
897 #if B_BEOS_VERSION > B_BEOS_VERSION_4_5
898 			export_multi_audio_info_attr(m_format.u.raw_audio, context);
899 #endif
900 			break;
901 
902 		case B_MEDIA_RAW_VIDEO:
903 			export_raw_video_attr(m_format.u.raw_video, context);
904 			break;
905 
906 		case B_MEDIA_MULTISTREAM:
907 			export_multistream_attr(m_format.u.multistream, context);
908 			break;
909 
910 		case B_MEDIA_ENCODED_AUDIO:
911 			export_encoded_audio_attr(m_format.u.encoded_audio, context);
912 			break;
913 
914 		case B_MEDIA_ENCODED_VIDEO:
915 			export_encoded_video_attr(m_format.u.encoded_video, context);
916 			break;
917 
918 		default:
919 			break;
920 	}
921 }
922 
923 void MediaFormatIO::xmlExportContent(
924 	ExportContext&		context) const {
925 
926 	switch(m_format.type) {
927 		case B_MEDIA_RAW_VIDEO:
928 			export_raw_video_content(m_format.u.raw_video, context);
929 			break;
930 
931 		case B_MEDIA_MULTISTREAM:
932 			export_multistream_content(m_format.u.multistream, context);
933 			break;
934 
935 		case B_MEDIA_ENCODED_AUDIO:
936 			export_encoded_audio_content(m_format.u.encoded_audio, context);
937 			break;
938 
939 		case B_MEDIA_ENCODED_VIDEO:
940 			export_encoded_video_content(m_format.u.encoded_video, context);
941 			break;
942 
943 		default:
944 			break;
945 	}
946 }
947 
948 void MediaFormatIO::xmlExportEnd(
949 	ExportContext&		context) const {
950 
951 	context.endElement();
952 }
953 
954 // -------------------------------------------------------- //
955 // import
956 // -------------------------------------------------------- //
957 
958 void import_raw_audio_attribute(
959 	media_raw_audio_format& f,
960 	const char* key,
961 	const char* value,
962 	ImportContext& context) {
963 
964 	if(!strcmp(key, gKey_frame_rate))
965 		f.frame_rate = atof(value);
966 	else if(!strcmp(key, gKey_channel_count))
967 		f.channel_count = atol(value);
968 	else if(!strcmp(key, gKey_buffer_size))
969 		f.buffer_size = atol(value);
970 	else if(!strcmp(key, gKey_format)) {
971 		if(!strcmp(value, "B_AUDIO_UCHAR"))
972 			f.format = media_raw_audio_format::B_AUDIO_UCHAR;
973 		else if(!strcmp(value, "B_AUDIO_SHORT"))
974 			f.format = media_raw_audio_format::B_AUDIO_SHORT;
975 		else if(!strcmp(value, "B_AUDIO_FLOAT"))
976 			f.format = media_raw_audio_format::B_AUDIO_FLOAT;
977 		else if(!strcmp(value, "B_AUDIO_INT"))
978 			f.format = media_raw_audio_format::B_AUDIO_INT;
979 	}
980 	else if(!strcmp(key, gKey_byte_order)) {
981 		if(!strcmp(value, "B_MEDIA_BIG_ENDIAN"))
982 			f.byte_order = B_MEDIA_BIG_ENDIAN;
983 		else if(!strcmp(value, "B_MEDIA_LITTLE_ENDIAN"))
984 			f.byte_order = B_MEDIA_LITTLE_ENDIAN;
985 	}
986 }
987 
988 #if B_BEOS_VERSION > B_BEOS_VERSION_4_5
989 
990 void import_multi_audio_info_attribute(
991 	media_multi_audio_info& f,
992 	const char* key,
993 	const char* value,
994 	ImportContext& context) {
995 
996 	if(!strcmp(key, gKey_channel_mask))
997 		f.channel_mask = atol(value);
998 	else if(!strcmp(key, gKey_valid_bits))
999 		f.valid_bits = atoi(value);
1000 	else if(!strcmp(key, gKey_matrix_mask))
1001 		f.matrix_mask = atoi(value);
1002 }
1003 
1004 #endif
1005 
1006 void import_raw_video_attribute(
1007 	media_raw_video_format& f,
1008 	const char* key,
1009 	const char* value,
1010 	ImportContext& context) {
1011 
1012 	if(!strcmp(key, gKey_field_rate))
1013 		f.field_rate = atof(value);
1014 	else if(!strcmp(key, gKey_interlace))
1015 		f.interlace = atol(value);
1016 	else if(!strcmp(key, gKey_first_active))
1017 		f.first_active = atol(value);
1018 	else if(!strcmp(key, gKey_last_active))
1019 		f.last_active = atol(value);
1020 	else if(!strcmp(key, gKey_pixel_width_aspect))
1021 		f.pixel_width_aspect = atol(value);
1022 	else if(!strcmp(key, gKey_pixel_height_aspect))
1023 		f.pixel_height_aspect = atol(value);
1024 	else if(!strcmp(key, gKey_orientation)) {
1025 		if(!strcmp(value, "B_VIDEO_TOP_LEFT_RIGHT"))
1026 			f.orientation = B_VIDEO_TOP_LEFT_RIGHT;
1027 		else if(!strcmp(value, "B_VIDEO_BOTTOM_LEFT_RIGHT"))
1028 			f.orientation = B_VIDEO_BOTTOM_LEFT_RIGHT;
1029 	}
1030 }
1031 
1032 void import_video_display_info_attribute(
1033 	media_video_display_info& d,
1034 	const char* key,
1035 	const char* value,
1036 	ImportContext& context) {
1037 
1038 	if(!strcmp(key, gKey_line_width))
1039 		d.line_width = atol(value);
1040 	else if(!strcmp(key, gKey_line_count))
1041 		d.line_count = atol(value);
1042 	else if(!strcmp(key, gKey_bytes_per_row))
1043 		d.bytes_per_row = atol(value);
1044 	else if(!strcmp(key, gKey_pixel_offset))
1045 		d.pixel_offset = atol(value);
1046 	else if(!strcmp(key, gKey_line_offset))
1047 		d.line_offset = atol(value);
1048 	else if(!strcmp(key, gKey_format)) {
1049 		import_color_space(value, d.format);
1050 	}
1051 }
1052 
1053 void import_multistream_attribute(
1054 	media_multistream_format& f,
1055 	const char* key,
1056 	const char* value,
1057 	ImportContext& context) {
1058 
1059 	if(!strcmp(key, gKey_format)) {
1060 		if(!strcmp(value, "B_ANY"))
1061 			f.format = media_multistream_format::B_ANY;
1062 		else if(!strcmp(value, "B_VID"))
1063 			f.format = media_multistream_format::B_VID;
1064 		else if(!strcmp(value, "B_AVI"))
1065 			f.format = media_multistream_format::B_AVI;
1066 		else if(!strcmp(value, "B_MPEG1"))
1067 			f.format = media_multistream_format::B_MPEG1;
1068 		else if(!strcmp(value, "B_MPEG2"))
1069 			f.format = media_multistream_format::B_MPEG2;
1070 		else if(!strcmp(value, "B_QUICKTIME"))
1071 			f.format = media_multistream_format::B_QUICKTIME;
1072 		else
1073 			f.format = atol(value);
1074 	}
1075 	else if(!strcmp(key, gKey_avg_bit_rate))
1076 		f.avg_bit_rate = atof(value);
1077 	else if(!strcmp(key, gKey_max_bit_rate))
1078 		f.max_bit_rate = atof(value);
1079 	else if(!strcmp(key, gKey_avg_chunk_size))
1080 		f.avg_chunk_size = atol(value);
1081 	else if(!strcmp(key, gKey_max_chunk_size))
1082 		f.max_chunk_size = atol(value);
1083 }
1084 
1085 void import_multistream_flags_attribute(
1086 	uint32& flags,
1087 	const char* key,
1088 	const char* value,
1089 	ImportContext& context) {
1090 
1091 	if(!atol(value))
1092 		return;
1093 
1094 	if(!strcmp(key, gKey_header_has_flags))
1095 		flags |= media_multistream_format::B_HEADER_HAS_FLAGS;
1096 	else if(!strcmp(key, gKey_clean_buffers))
1097 		flags |= media_multistream_format::B_CLEAN_BUFFERS;
1098 	else if(!strcmp(key, gKey_homogenous_buffers))
1099 		flags |= media_multistream_format::B_HOMOGENOUS_BUFFERS;
1100 }
1101 
1102 void import_multistream_vid_info_attribute(
1103 	media_multistream_format::vid_info& f,
1104 	const char* key,
1105 	const char* value,
1106 	ImportContext& context) {
1107 
1108 	if(!strcmp(key, gKey_frame_rate))
1109 		f.frame_rate = atof(value);
1110 	else if(!strcmp(key, gKey_width))
1111 		f.width = atol(value);
1112 	else if(!strcmp(key, gKey_height))
1113 		f.height = atol(value);
1114 	else if(!strcmp(key, gKey_space))
1115 		import_color_space(value, f.space);
1116 	else if(!strcmp(key, gKey_sampling_rate))
1117 		f.sampling_rate = atof(value);
1118 	else if(!strcmp(key, gKey_channel_count))
1119 		f.channel_count = atol(value);
1120 	else if(!strcmp(key, gKey_sample_format)) {
1121 		if(!strcmp(value, "B_UNDEFINED_SAMPLES"))
1122 			f.sample_format = B_UNDEFINED_SAMPLES;
1123 		else if(!strcmp(value, "B_LINEAR_SAMPLES"))
1124 			f.sample_format = B_LINEAR_SAMPLES;
1125 		else if(!strcmp(value, "B_FLOAT_SAMPLES"))
1126 			f.sample_format = B_FLOAT_SAMPLES;
1127 		else if(!strcmp(value, "B_MULAW_SAMPLES"))
1128 			f.sample_format = B_MULAW_SAMPLES;
1129 	}
1130 	else if(!strcmp(key, gKey_byte_order)) {
1131 		if(!strcmp(value, "B_MEDIA_BIG_ENDIAN"))
1132 			f.byte_order = B_MEDIA_BIG_ENDIAN;
1133 		else if(!strcmp(value, "B_MEDIA_LITTLE_ENDIAN"))
1134 			f.byte_order = B_MEDIA_LITTLE_ENDIAN;
1135 	}
1136 }
1137 
1138 void import_multistream_avi_info_attribute(
1139 	media_multistream_format::avi_info& f,
1140 	const char* key,
1141 	const char* value,
1142 	ImportContext& context) {
1143 
1144 	if(!strcmp(key, gKey_us_per_frame))
1145 		f.us_per_frame = atol(value);
1146 	else if(!strcmp(key, gKey_width))
1147 		f.width = atol(value);
1148 	else if(!strcmp(key, gKey_height))
1149 		f.height = atol(value);
1150 }
1151 
1152 void import_encoded_audio_attribute(
1153 	media_encoded_audio_format& f,
1154 	const char* key,
1155 	const char* value,
1156 	ImportContext& context) {
1157 
1158 	if(!strcmp(key, gKey_encoding)) {
1159 		if(!strcmp(value, "B_ANY"))
1160 			f.encoding = media_encoded_audio_format::B_ANY;
1161 	}
1162 	else if(!strcmp(key, gKey_bit_rate))
1163 		f.bit_rate = atof(value);
1164 	else if(!strcmp(key, gKey_frame_size))
1165 		f.frame_size = atol(value);
1166 }
1167 
1168 void import_encoded_video_attribute(
1169 	media_encoded_video_format& f,
1170 	const char* key,
1171 	const char* value,
1172 	ImportContext& context) {
1173 
1174 	if(!strcmp(key, gKey_encoding)) {
1175 		if(!strcmp(value, "B_ANY"))
1176 			f.encoding = media_encoded_video_format::B_ANY;
1177 	}
1178 	else if(!strcmp(key, gKey_avg_bit_rate))
1179 		f.avg_bit_rate = atof(value);
1180 	else if(!strcmp(key, gKey_max_bit_rate))
1181 		f.max_bit_rate = atof(value);
1182 	else if(!strcmp(key, gKey_frame_size))
1183 		f.frame_size = atol(value);
1184 	else if(!strcmp(key, gKey_forward_history))
1185 		f.forward_history = atol(value);
1186 	else if(!strcmp(key, gKey_backward_history))
1187 		f.backward_history = atol(value);
1188 }
1189 
1190 // -------------------------------------------------------- //
1191 
1192 void MediaFormatIO::xmlImportBegin(
1193 	ImportContext&		context) {
1194 
1195 	// initialize format
1196 	if(!strcmp(context.element(), s_raw_audio_tag)) {
1197 		m_format.type = B_MEDIA_RAW_AUDIO;
1198 		m_format.u.raw_audio = media_raw_audio_format::wildcard;
1199 	}
1200 	else if(!strcmp(context.element(), s_raw_video_tag)) {
1201 		m_format.type = B_MEDIA_RAW_VIDEO;
1202 		m_format.u.raw_video = media_raw_video_format::wildcard;
1203 	}
1204 	else if(!strcmp(context.element(), s_multistream_tag)) {
1205 		m_format.type = B_MEDIA_MULTISTREAM;
1206 		m_format.u.multistream = media_multistream_format::wildcard;
1207 	}
1208 	else if(!strcmp(context.element(), s_encoded_audio_tag)) {
1209 		m_format.type = B_MEDIA_ENCODED_AUDIO;
1210 		m_format.u.encoded_audio = media_encoded_audio_format::wildcard;
1211 	}
1212 	else if(!strcmp(context.element(), s_encoded_video_tag)) {
1213 		m_format.type = B_MEDIA_ENCODED_VIDEO;
1214 		m_format.u.encoded_video = media_encoded_video_format::wildcard;
1215 	}
1216 	else
1217 		context.reportError("Bad element mapping?  MediaFormatIO can't cope.");
1218 }
1219 
1220 void MediaFormatIO::xmlImportAttribute(
1221 	const char*					key,
1222 	const char*					value,
1223 	ImportContext&		context) {
1224 	switch(m_format.type) {
1225 		case B_MEDIA_RAW_AUDIO:
1226 			import_raw_audio_attribute(
1227 				m_format.u.raw_audio, key, value, context);
1228 
1229 #if B_BEOS_VERSION > B_BEOS_VERSION_4_5
1230 			import_multi_audio_info_attribute(
1231 				m_format.u.raw_audio, key, value, context);
1232 #endif
1233 			break;
1234 
1235 		case B_MEDIA_RAW_VIDEO:
1236 			import_raw_video_attribute(
1237 				m_format.u.raw_video, key, value, context);
1238 			break;
1239 
1240 		case B_MEDIA_MULTISTREAM:
1241 			import_multistream_attribute(
1242 				m_format.u.multistream, key, value, context);
1243 			break;
1244 
1245 		case B_MEDIA_ENCODED_AUDIO:
1246 			import_encoded_audio_attribute(
1247 				m_format.u.encoded_audio, key, value, context);
1248 			break;
1249 
1250 		case B_MEDIA_ENCODED_VIDEO:
1251 			import_encoded_video_attribute(
1252 				m_format.u.encoded_video, key, value, context);
1253 			break;
1254 
1255 		default:
1256 			context.reportError("MediaFormatIO: bad type.");
1257 	}
1258 }
1259 
1260 void MediaFormatIO::xmlImportContent(
1261 	const char*					data,
1262 	uint32						length,
1263 	ImportContext&		context) {}
1264 
1265 void MediaFormatIO::xmlImportChild(
1266 	IPersistent*			child,
1267 	ImportContext&		context) {
1268 
1269 	MediaFormatIO* childAsFormat = dynamic_cast<MediaFormatIO*>(child);
1270 	if(m_format.type == B_MEDIA_ENCODED_AUDIO) {
1271 		if(!childAsFormat || childAsFormat->m_format.type != B_MEDIA_RAW_AUDIO)
1272 			context.reportError("Expected a raw_audio_format.");
1273 		m_format.u.encoded_audio.output = childAsFormat->m_format.u.raw_audio;
1274 	}
1275 	else if(m_format.type == B_MEDIA_ENCODED_VIDEO) {
1276 		if(!childAsFormat || childAsFormat->m_format.type != B_MEDIA_RAW_VIDEO)
1277 			context.reportError("Expected a raw_video_format.");
1278 		m_format.u.encoded_video.output = childAsFormat->m_format.u.raw_video;
1279 	}
1280 	else {
1281 		// +++++ should this be an error?
1282 		context.reportWarning("MediaFormatIO: Unexpected child element.");
1283 	}
1284 	delete child;
1285 }
1286 
1287 void MediaFormatIO::xmlImportComplete(
1288 	ImportContext&		context) {
1289 
1290 	// +++++ validity checks?
1291 
1292 	m_complete = true;
1293 }
1294 
1295 void MediaFormatIO::xmlImportChildBegin(
1296 	const char*					name,
1297 	ImportContext&		context) {
1298 
1299 	if(!strcmp(name, s_video_display_info_tag)) {
1300 		if(m_format.type != B_MEDIA_RAW_VIDEO)
1301 			context.reportError("MediaFormatIO: unexpected element.");
1302 	}
1303 	else if(!strcmp(name, s_multistream_flags_tag)) {
1304 		if(m_format.type != B_MEDIA_MULTISTREAM)
1305 			context.reportError("MediaFormatIO: unexpected element.");
1306 	}
1307 	else if(!strcmp(name, s_multistream_vid_info_tag)) {
1308 		if(m_format.type != B_MEDIA_MULTISTREAM ||
1309 			m_format.u.multistream.format != media_multistream_format::B_VID)
1310 			context.reportError("MediaFormatIO: unexpected element.");
1311 	}
1312 	else if(!strcmp(name, s_multistream_avi_info_tag)) {
1313 		if(m_format.type != B_MEDIA_MULTISTREAM ||
1314 			m_format.u.multistream.format != media_multistream_format::B_AVI)
1315 			context.reportError("MediaFormatIO: unexpected element.");
1316 	}
1317 	else if(!strcmp(name, s_media_type_tag)) {
1318 		if(m_format.type != B_MEDIA_MULTISTREAM ||
1319 			m_format.u.multistream.format != media_multistream_format::B_AVI)
1320 			context.reportError("MediaFormatIO: unexpected element.");
1321 	}
1322 }
1323 
1324 void MediaFormatIO::xmlImportChildAttribute(
1325 	const char*					key,
1326 	const char*					value,
1327 	ImportContext&		context) {
1328 
1329 	if(!strcmp(context.element(), s_video_display_info_tag))
1330 		import_video_display_info_attribute(
1331 			m_format.u.raw_video.display, key, value, context);
1332 
1333 	else if(!strcmp(context.element(), s_multistream_flags_tag	))
1334 		import_multistream_flags_attribute(
1335 			m_format.u.multistream.flags, key, value, context);
1336 
1337 	else if(!strcmp(context.element(), s_multistream_vid_info_tag	))
1338 		import_multistream_vid_info_attribute(
1339 			m_format.u.multistream.u.vid, key, value, context);
1340 
1341 	else if(!strcmp(context.element(), s_multistream_avi_info_tag	))
1342 		import_multistream_avi_info_attribute(
1343 			m_format.u.multistream.u.avi, key, value, context);
1344 
1345 	else
1346 		context.reportError("MediaFormatIO: bad child element.");
1347 }
1348 
1349 void MediaFormatIO::xmlImportChildContent(
1350 	const char*					data,
1351 	uint32						length,
1352 	ImportContext&		context) {
1353 
1354 	if(!strcmp(context.element(), s_media_type_tag)) {
1355 		m_mediaType.Append(data, length);
1356 	}
1357 }
1358 
1359 void MediaFormatIO::xmlImportChildComplete(
1360 	const char*					name,
1361 	ImportContext&		context) {
1362 
1363 	if(!strcmp(context.element(), s_media_type_tag)) {
1364 		import_media_type_content(
1365 			m_format.u.multistream.u.avi,
1366 			m_mediaType.String(),	context);
1367 
1368 		m_mediaType = "";
1369 	}
1370 }
1371 
1372 
1373 // END -- MediaFormatIO.cpp --
1374