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