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
45const char* const MediaFormatIO::s_multi_audio_tag 			= "multi_audio_format";
46const char* const MediaFormatIO::s_raw_audio_tag 				= "raw_audio_format";
47const char* const MediaFormatIO::s_raw_video_tag 				= "raw_video_format";
48const char* const MediaFormatIO::s_multistream_tag 			= "multistream_format";
49const char* const MediaFormatIO::s_encoded_audio_tag 		= "encoded_audio_format";
50const char* const MediaFormatIO::s_encoded_video_tag 		= "encoded_video_format";
51
52// nested tags
53const char* const MediaFormatIO::s_video_display_info_tag		= "video_display_info";
54const char* const MediaFormatIO::s_multistream_flags_tag			= "multistream_flags";
55const char* const MediaFormatIO::s_multistream_vid_info_tag	= "multistream_vid_info";
56const char* const MediaFormatIO::s_multistream_avi_info_tag	= "multistream_avi_info";
57const char* const MediaFormatIO::s_multi_audio_info_tag			= "multi_audio_info";
58const char* const MediaFormatIO::s_media_type_tag						= "media_type";
59
60// -------------------------------------------------------- //
61// *** ctor/dtor
62// -------------------------------------------------------- //
63
64MediaFormatIO::~MediaFormatIO() {}
65
66MediaFormatIO::MediaFormatIO() :
67	m_complete(false) {}
68MediaFormatIO::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
79status_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*/
94void 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
119const char* const gKey_frame_rate							= "frame_rate";
120const char* const gKey_channel_count					= "channel_count";
121const char* const gKey_format									= "format";
122const char* const gKey_byte_order							= "byte_order";
123const char* const gKey_buffer_size						= "buffer_size";
124
125// *** +multi_audio_format
126const char* const gKey_channel_mask						= "channel_mask";
127const char* const gKey_valid_bits							= "valid_bits";
128const char* const gKey_matrix_mask						= "matrix_mask";
129
130// *** raw_video_format
131const char* const gKey_field_rate							= "field_rate";
132const char* const gKey_interlace							= "interlace";
133const char* const gKey_first_active						= "first_active";
134const char* const gKey_last_active						= "last_active";
135const char* const gKey_orientation						= "orientation";
136const char* const gKey_pixel_width_aspect			= "pixel_width_aspect";
137const char* const gKey_pixel_height_aspect		= "pixel_height_aspect";
138
139// *** video_display_info
140const char* const gKey_color_space						= "color_space";
141const char* const gKey_line_width							= "line_width";
142const char* const gKey_line_count							= "line_count";
143const char* const gKey_bytes_per_row					= "bytes_per_row";
144const char* const gKey_pixel_offset						= "pixel_offset";
145const char* const gKey_line_offset						= "line_offset";
146
147// *** multistream_format
148const char* const gKey_multistream_format			= "format";
149const char* const gKey_avg_bit_rate						= "avg_bit_rate";
150const char* const gKey_max_bit_rate						= "max_bit_rate";
151const char* const gKey_avg_chunk_size					= "avg_chunk_size";
152const char* const gKey_max_chunk_size					= "max_chunk_size";
153
154// *** multistream_flags
155const char* const gKey_header_has_flags				= "header_has_flags";
156const char* const gKey_clean_buffers					= "clean_buffers";
157const char* const gKey_homogenous_buffers			= "homogenous_buffers";
158
159// *** multistream_vid_info
160// frame_rate
161const char* const gKey_width									= "width";
162const char* const gKey_height									= "height";
163const char* const gKey_space									= "space";
164const char* const gKey_sampling_rate					= "sampling_rate";
165const char* const gKey_sample_format					= "sample_format";
166// byte_order
167// channel_count
168
169// *** multistream_avi_info
170const char* const gKey_us_per_frame						= "us_per_frame";
171// width
172// height
173
174// *** encoded_audio_format
175const char* const gKey_encoding								= "encoding";
176const char* const gKey_bit_rate								= "bit_rate";
177const 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
184const char* const gKey_forward_history				= "forward_history";
185const char* const gKey_backward_history				= "backward_history";
186
187// padding (number of spaces allowed for attribute name)
188const int16 g_padAttributes		= 30;
189
190// -------------------------------------------------------- //
191// export
192// -------------------------------------------------------- //
193
194void 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
337void 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
443void 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
499void 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
544void 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
588void 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
605void 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
627void 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
659void 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
669void 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
683void 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
726void 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
735void 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
745void 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
789void 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
815void 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
836void 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
852void 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
878void 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
890void 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
922void 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
954void 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
979void MediaFormatIO::xmlExportEnd(
980	ExportContext&		context) const {
981
982	context.endElement();
983}
984
985// -------------------------------------------------------- //
986// import
987// -------------------------------------------------------- //
988
989void 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
1021void 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
1037void 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
1063void 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
1084void 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
1116void 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
1133void 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
1169void 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
1183void 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
1199void 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
1223void 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
1251void 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
1291void MediaFormatIO::xmlImportContent(
1292	const char*					data,
1293	uint32						length,
1294	ImportContext&		context) {}
1295
1296void 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
1318void MediaFormatIO::xmlImportComplete(
1319	ImportContext&		context) {
1320
1321	// +++++ validity checks?
1322
1323	m_complete = true;
1324}
1325
1326void 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
1355void 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
1380void 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
1390void 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