xref: /haiku/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp (revision 54348708ae85493f25087ea4ebc95ee53dec8c4a)
1ca16f5cbSbeveloper #include <stdio.h>
2bce1ab5eSbeveloper #include <string.h>
3ca16f5cbSbeveloper #include <DataIO.h>
4bb1d6ef2Sbeveloper #include <OS.h>
5bb1d6ef2Sbeveloper #include <MediaRoster.h>
6bb1d6ef2Sbeveloper #include "RawFormats.h"
7ca16f5cbSbeveloper #include "RawDecoderPlugin.h"
8bb1d6ef2Sbeveloper #include "AudioConversion.h"
9ca16f5cbSbeveloper 
10ca16f5cbSbeveloper #define TRACE_THIS 1
11ca16f5cbSbeveloper #if TRACE_THIS
12ca16f5cbSbeveloper   #define TRACE printf
13ca16f5cbSbeveloper #else
14bb1d6ef2Sbeveloper   #define TRACE(a...)
15ca16f5cbSbeveloper #endif
16ca16f5cbSbeveloper 
17*54348708Sbeveloper inline size_t
18*54348708Sbeveloper AudioBufferSize(int32 channel_count, uint32 sample_format, float frame_rate, bigtime_t buffer_duration = 50000 /* 50 ms */)
19*54348708Sbeveloper {
20*54348708Sbeveloper 	return (sample_format & 0xf) * channel_count * (size_t)((frame_rate * buffer_duration) / 1000000.0);
21*54348708Sbeveloper }
22ca16f5cbSbeveloper 
23ca16f5cbSbeveloper status_t
2425305239Sbeveloper RawDecoder::Setup(media_format *ioEncodedFormat,
25bce1ab5eSbeveloper 				  const void *infoBuffer, int32 infoSize)
26ca16f5cbSbeveloper {
27bb1d6ef2Sbeveloper 	char s[200];
28bb1d6ef2Sbeveloper 	string_for_format(*ioEncodedFormat, s, sizeof(s));
29bb1d6ef2Sbeveloper 	TRACE("RawDecoder::Setup: %s\n", s);
30bb1d6ef2Sbeveloper 
31bce1ab5eSbeveloper 	if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO)
32ca16f5cbSbeveloper 		return B_ERROR;
33ca16f5cbSbeveloper 
3425305239Sbeveloper 	fInputFormat = *ioEncodedFormat;
3525305239Sbeveloper 
36bb1d6ef2Sbeveloper 	if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO) {
37bb1d6ef2Sbeveloper 		fInputSampleSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row;
38bb1d6ef2Sbeveloper 		fInputFrameSize = fInputSampleSize;
39bb1d6ef2Sbeveloper 	} else {
40bb1d6ef2Sbeveloper 		fInputSampleSize = (ioEncodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
41bb1d6ef2Sbeveloper 		fInputFrameSize = fInputSampleSize * ioEncodedFormat->u.raw_audio.channel_count;
42bb1d6ef2Sbeveloper 	}
43bb1d6ef2Sbeveloper 
44bb1d6ef2Sbeveloper 	// since ioEncodedFormat is later passed to the application by BMediaTrack::EncodedFormat()
45bb1d6ef2Sbeveloper 	// we need to remove non public format specifications
46bb1d6ef2Sbeveloper 
47bb1d6ef2Sbeveloper 	// remove non format bits, like channel order
48bb1d6ef2Sbeveloper 	ioEncodedFormat->u.raw_audio.format &= B_AUDIO_FORMAT_MASK;
49bb1d6ef2Sbeveloper 
50bb1d6ef2Sbeveloper 	switch (ioEncodedFormat->u.raw_audio.format) {
51bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_UINT8:
52bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT8:
53bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT16:
54bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT32:
55bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT32:
56bb1d6ef2Sbeveloper 			break; // ok to pass through
57bb1d6ef2Sbeveloper 
58bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT24:
59bb1d6ef2Sbeveloper 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_INT32;
60bb1d6ef2Sbeveloper 			break;
61bb1d6ef2Sbeveloper 
62bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT64:
63bb1d6ef2Sbeveloper 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_FLOAT32;
64bb1d6ef2Sbeveloper 			break;
65bb1d6ef2Sbeveloper 
66bb1d6ef2Sbeveloper 		default:
67bb1d6ef2Sbeveloper 			TRACE("RawDecoder::Setup: unknown input format\n");
68bb1d6ef2Sbeveloper 			return B_ERROR;
69bb1d6ef2Sbeveloper 	}
70bce1ab5eSbeveloper 
71*54348708Sbeveloper 	// since we can translate to a different buffer size,
72*54348708Sbeveloper 	// suggest something nicer than delivered by the
73*54348708Sbeveloper 	// file reader (perhaps we should even report wildcard?)
74*54348708Sbeveloper 	ioEncodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
75*54348708Sbeveloper 														ioEncodedFormat->u.raw_audio.channel_count,
76*54348708Sbeveloper 														ioEncodedFormat->u.raw_audio.format,
77*54348708Sbeveloper 														ioEncodedFormat->u.raw_audio.frame_rate);
7825305239Sbeveloper 	return B_OK;
7925305239Sbeveloper }
80bce1ab5eSbeveloper 
8125305239Sbeveloper 
8225305239Sbeveloper status_t
8325305239Sbeveloper RawDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
8425305239Sbeveloper {
8525305239Sbeveloper 	// BeBook says: The codec will find and return in ioFormat its best matching format
8625305239Sbeveloper 	// => This means, we never return an error, and always change the format values
8725305239Sbeveloper 	//    that we don't support to something more applicable
88bb1d6ef2Sbeveloper 	if (ioDecodedFormat->type == B_MEDIA_RAW_VIDEO)
89bb1d6ef2Sbeveloper 		return NegotiateVideoOutputFormat(ioDecodedFormat);
90bb1d6ef2Sbeveloper 	if (ioDecodedFormat->type == B_MEDIA_RAW_AUDIO)
91bb1d6ef2Sbeveloper 		return NegotiateAudioOutputFormat(ioDecodedFormat);
92bb1d6ef2Sbeveloper 	return B_ERROR;
93bb1d6ef2Sbeveloper }
9425305239Sbeveloper 
95bb1d6ef2Sbeveloper 
96bb1d6ef2Sbeveloper status_t
97bb1d6ef2Sbeveloper RawDecoder::NegotiateVideoOutputFormat(media_format *ioDecodedFormat)
98bb1d6ef2Sbeveloper {
99bb1d6ef2Sbeveloper 	return B_ERROR;
100bb1d6ef2Sbeveloper }
101bb1d6ef2Sbeveloper 
102bb1d6ef2Sbeveloper 
103bb1d6ef2Sbeveloper status_t
104bb1d6ef2Sbeveloper RawDecoder::NegotiateAudioOutputFormat(media_format *ioDecodedFormat)
105bb1d6ef2Sbeveloper {
1064ba72fcdSbeveloper 	char s[1024];
1074ba72fcdSbeveloper 
1084ba72fcdSbeveloper 	string_for_format(*ioDecodedFormat, s, sizeof(s));
109bb1d6ef2Sbeveloper 	TRACE("RawDecoder::NegotiateAudioOutputFormat enter: %s\n", s);
1104ba72fcdSbeveloper 
111bb1d6ef2Sbeveloper 	ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
112bb1d6ef2Sbeveloper 	switch (ioDecodedFormat->u.raw_audio.format) {
113bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_FLOAT:
114bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_SHORT:
115bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_UCHAR:
116bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_CHAR:
117bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = 0;
118bb1d6ef2Sbeveloper 			break; // we can produce this on request
119a3d7908eSbeveloper 
120bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_INT:
121bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
122bb1d6ef2Sbeveloper 			break; // we can produce this on request
123bb1d6ef2Sbeveloper 
124bb1d6ef2Sbeveloper 		default:
125bb1d6ef2Sbeveloper 			switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
126bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_SHORT:
127bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_UCHAR:
128bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_CHAR:
129bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK;
130bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
131bb1d6ef2Sbeveloper 					break;
132bb1d6ef2Sbeveloper 
133bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_INT:
134bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT24:
135bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT;
136bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
137bb1d6ef2Sbeveloper 					break;
138bb1d6ef2Sbeveloper 
139bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_FLOAT:
140bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT64:
141bb1d6ef2Sbeveloper 				default:
142bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
143bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
144bb1d6ef2Sbeveloper 					break;
145bb1d6ef2Sbeveloper 			}
146bb1d6ef2Sbeveloper 			break;
147bb1d6ef2Sbeveloper 	}
148bb1d6ef2Sbeveloper 
149bb1d6ef2Sbeveloper 	fFrameRate = (int32) ioDecodedFormat->u.raw_audio.frame_rate;
150bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.frame_rate = fInputFormat.u.raw_audio.frame_rate;
151bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.channel_count = fInputFormat.u.raw_audio.channel_count;
152bb1d6ef2Sbeveloper 
153bb1d6ef2Sbeveloper 	fOutputSampleSize = (ioDecodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
154bb1d6ef2Sbeveloper 	fOutputFrameSize = fOutputSampleSize * ioDecodedFormat->u.raw_audio.channel_count;
155bb1d6ef2Sbeveloper 
156bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == 0)
157bb1d6ef2Sbeveloper 		ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
158bb1d6ef2Sbeveloper 
159bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.channel_mask = 0;
160bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.matrix_mask = 0;
161bb1d6ef2Sbeveloper 
162bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.buffer_size < 128 || ioDecodedFormat->u.raw_audio.buffer_size > 65536) {
163*54348708Sbeveloper 		ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
164bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.channel_count,
165bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.format,
166bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.frame_rate);
167bb1d6ef2Sbeveloper 	} else {
168bb1d6ef2Sbeveloper 		// round down to exact multiple of output frame size
169bb1d6ef2Sbeveloper 		ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize) * fOutputFrameSize;
170bb1d6ef2Sbeveloper 	}
171bb1d6ef2Sbeveloper 
172bb1d6ef2Sbeveloper 	fOutputBufferFrameCount = ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize;
173bb1d6ef2Sbeveloper 
174bb1d6ef2Sbeveloper 	// setup input swapping function
175bb1d6ef2Sbeveloper 	if (fInputFormat.u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
176bb1d6ef2Sbeveloper 		fSwapInput = 0;
177bb1d6ef2Sbeveloper 	} else {
178bb1d6ef2Sbeveloper 		switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
179bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
180bb1d6ef2Sbeveloper 				fSwapInput = &swap_int16;
181bb1d6ef2Sbeveloper 				break;
182bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT24:
183bb1d6ef2Sbeveloper 				fSwapInput = &swap_int24;
184bb1d6ef2Sbeveloper 				break;
185bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
186bb1d6ef2Sbeveloper 				fSwapInput = &swap_int32;
187bb1d6ef2Sbeveloper 				break;
188bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
189bb1d6ef2Sbeveloper 				fSwapInput = &swap_float32;
190bb1d6ef2Sbeveloper 				break;
191bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT64:
192bb1d6ef2Sbeveloper 				fSwapInput = &swap_float64;
193bb1d6ef2Sbeveloper 				break;
194bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
195bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
196bb1d6ef2Sbeveloper 				fSwapInput = 0;
197bb1d6ef2Sbeveloper 				break;
198bb1d6ef2Sbeveloper 			default:
199bb1d6ef2Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unkown input format\n");
200bb1d6ef2Sbeveloper 				break;
201bb1d6ef2Sbeveloper 		}
202bb1d6ef2Sbeveloper 	}
203bb1d6ef2Sbeveloper 
204bb1d6ef2Sbeveloper 	// setup output swapping function
205bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
206bb1d6ef2Sbeveloper 		fSwapOutput = 0;
207bb1d6ef2Sbeveloper 	} else {
208bb1d6ef2Sbeveloper 		switch (ioDecodedFormat->u.raw_audio.format) {
209bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
210bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int16;
211bb1d6ef2Sbeveloper 				break;
212bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
213bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int32;
214bb1d6ef2Sbeveloper 				break;
215bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
216bb1d6ef2Sbeveloper 				fSwapOutput = &swap_float32;
217bb1d6ef2Sbeveloper 				break;
218bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
219bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
220bb1d6ef2Sbeveloper 				fSwapOutput = 0;
221bb1d6ef2Sbeveloper 				break;
222bb1d6ef2Sbeveloper 			default:
223bb1d6ef2Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
224bb1d6ef2Sbeveloper 				break;
225bb1d6ef2Sbeveloper 		}
226bb1d6ef2Sbeveloper 	}
227bb1d6ef2Sbeveloper 
228bb1d6ef2Sbeveloper 	// setup sample conversation function
229bb1d6ef2Sbeveloper 	switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
230bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_UINT8:
231bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
232bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
233bb1d6ef2Sbeveloper 					fConvert = &uint8_to_uint8;
234bb1d6ef2Sbeveloper 					break;
235bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
236bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int8;
237bb1d6ef2Sbeveloper 					break;
238bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
239bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int16;
240bb1d6ef2Sbeveloper 					break;
241bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
242bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int32;
243bb1d6ef2Sbeveloper 					break;
244bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
245bb1d6ef2Sbeveloper 					fConvert = &uint8_to_float32;
246bb1d6ef2Sbeveloper 					break;
247bb1d6ef2Sbeveloper 				default:
248bb1d6ef2Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
249bb1d6ef2Sbeveloper 					break;
250bb1d6ef2Sbeveloper 			}
251bb1d6ef2Sbeveloper 			break;
252bb1d6ef2Sbeveloper 
253bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT8:
254bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
255bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
256bb1d6ef2Sbeveloper 					fConvert = &int8_to_uint8;
257bb1d6ef2Sbeveloper 					break;
258bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
259bb1d6ef2Sbeveloper 					fConvert = &int8_to_int8;
260bb1d6ef2Sbeveloper 					break;
261bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
262bb1d6ef2Sbeveloper 					fConvert = &int8_to_int16;
263bb1d6ef2Sbeveloper 					break;
264bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
265bb1d6ef2Sbeveloper 					fConvert = &int8_to_int32;
266bb1d6ef2Sbeveloper 					break;
267bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
268bb1d6ef2Sbeveloper 					fConvert = &int8_to_float32;
269bb1d6ef2Sbeveloper 					break;
270bb1d6ef2Sbeveloper 				default:
271bb1d6ef2Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
272bb1d6ef2Sbeveloper 					break;
273bb1d6ef2Sbeveloper 			}
274bb1d6ef2Sbeveloper 			break;
275bb1d6ef2Sbeveloper 
276bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT16:
277bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
278bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
279bb1d6ef2Sbeveloper 					fConvert = &int16_to_uint8;
280bb1d6ef2Sbeveloper 					break;
281bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
282bb1d6ef2Sbeveloper 					fConvert = &int16_to_int8;
283bb1d6ef2Sbeveloper 					break;
284bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
285bb1d6ef2Sbeveloper 					fConvert = &int16_to_int16;
286bb1d6ef2Sbeveloper 					break;
287bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
288bb1d6ef2Sbeveloper 					fConvert = &int16_to_int32;
289bb1d6ef2Sbeveloper 					break;
290bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
291bb1d6ef2Sbeveloper 					fConvert = &int16_to_float32;
292bb1d6ef2Sbeveloper 					break;
293bb1d6ef2Sbeveloper 				default:
294bb1d6ef2Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
295bb1d6ef2Sbeveloper 					break;
296bb1d6ef2Sbeveloper 			}
297bb1d6ef2Sbeveloper 			break;
298bb1d6ef2Sbeveloper 
299bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT24:
300bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
301bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
302bb1d6ef2Sbeveloper 					fConvert = &int24_to_uint8;
303bb1d6ef2Sbeveloper 					break;
304bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
305bb1d6ef2Sbeveloper 					fConvert = &int24_to_int8;
306bb1d6ef2Sbeveloper 					break;
307bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
308bb1d6ef2Sbeveloper 					fConvert = &int24_to_int16;
309bb1d6ef2Sbeveloper 					break;
310bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
311bb1d6ef2Sbeveloper 					fConvert = &int24_to_int32;
312bb1d6ef2Sbeveloper 					break;
313bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
314bb1d6ef2Sbeveloper 					fConvert = &int24_to_float32;
315bb1d6ef2Sbeveloper 					break;
316bb1d6ef2Sbeveloper 				default:
317bb1d6ef2Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
318bb1d6ef2Sbeveloper 					break;
319bb1d6ef2Sbeveloper 			}
320bb1d6ef2Sbeveloper 			break;
321bb1d6ef2Sbeveloper 
322bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT32:
323bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
324bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
325bb1d6ef2Sbeveloper 					fConvert = &int32_to_uint8;
326bb1d6ef2Sbeveloper 					break;
327bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
328bb1d6ef2Sbeveloper 					fConvert = &int32_to_int8;
329bb1d6ef2Sbeveloper 					break;
330bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
331bb1d6ef2Sbeveloper 					fConvert = &int32_to_int16;
332bb1d6ef2Sbeveloper 					break;
333bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
334bb1d6ef2Sbeveloper 					fConvert = &int32_to_int32;
335bb1d6ef2Sbeveloper 					break;
336bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
337bb1d6ef2Sbeveloper 					fConvert = &int32_to_float32;
338bb1d6ef2Sbeveloper 					break;
339bb1d6ef2Sbeveloper 				default:
340bb1d6ef2Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
341bb1d6ef2Sbeveloper 					break;
342bb1d6ef2Sbeveloper 			}
343bb1d6ef2Sbeveloper 			break;
344bb1d6ef2Sbeveloper 
345bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT32:
346bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
347bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
348bb1d6ef2Sbeveloper 					fConvert = &float32_to_uint8;
349bb1d6ef2Sbeveloper 					break;
350bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
351bb1d6ef2Sbeveloper 					fConvert = &float32_to_int8;
352bb1d6ef2Sbeveloper 					break;
353bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
354bb1d6ef2Sbeveloper 					fConvert = &float32_to_int16;
355bb1d6ef2Sbeveloper 					break;
356bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
357bb1d6ef2Sbeveloper 					fConvert = &float32_to_int32;
358bb1d6ef2Sbeveloper 					break;
359bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
360bb1d6ef2Sbeveloper 					fConvert = &float32_to_float32;
361bb1d6ef2Sbeveloper 					break;
362bb1d6ef2Sbeveloper 				default:
363bb1d6ef2Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
364bb1d6ef2Sbeveloper 					break;
365bb1d6ef2Sbeveloper 			}
366bb1d6ef2Sbeveloper 			break;
367bb1d6ef2Sbeveloper 
368bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT64:
369bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
370bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
371bb1d6ef2Sbeveloper 					fConvert = &float64_to_uint8;
372bb1d6ef2Sbeveloper 					break;
373bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
374bb1d6ef2Sbeveloper 					fConvert = &float64_to_int8;
375bb1d6ef2Sbeveloper 					break;
376bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
377bb1d6ef2Sbeveloper 					fConvert = &float64_to_int16;
378bb1d6ef2Sbeveloper 					break;
379bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
380bb1d6ef2Sbeveloper 					fConvert = &float64_to_int32;
381bb1d6ef2Sbeveloper 					break;
382bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
383bb1d6ef2Sbeveloper 					fConvert = &float64_to_float32;
384bb1d6ef2Sbeveloper 					break;
385bb1d6ef2Sbeveloper 				default:
386bb1d6ef2Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unkown output format\n");
387bb1d6ef2Sbeveloper 					break;
388bb1d6ef2Sbeveloper 			}
389bb1d6ef2Sbeveloper 			break;
390bb1d6ef2Sbeveloper 
391bb1d6ef2Sbeveloper 		default:
392bb1d6ef2Sbeveloper 			debugger("RawDecoder::NegotiateAudioOutputFormat unkown input format\n");
393bb1d6ef2Sbeveloper 			break;
394bb1d6ef2Sbeveloper 	}
395bb1d6ef2Sbeveloper 
396bb1d6ef2Sbeveloper 	fChunkBuffer = 0;
397bb1d6ef2Sbeveloper 	fChunkSize = 0;
398bb1d6ef2Sbeveloper 	fStartTime = 0;
3994ba72fcdSbeveloper 
4004ba72fcdSbeveloper 	string_for_format(*ioDecodedFormat, s, sizeof(s));
401bb1d6ef2Sbeveloper 	TRACE("RawDecoder::NegotiateAudioOutputFormat leave: %s\n", s);
402bb1d6ef2Sbeveloper /*
403bb1d6ef2Sbeveloper 	TRACE("fFrameRate              %ld\n", fFrameRate);
404bb1d6ef2Sbeveloper 	TRACE("fInputFrameSize         %ld\n", fInputFrameSize);
405bb1d6ef2Sbeveloper 	TRACE("fOutputFrameSize        %ld\n", fOutputFrameSize);
406bb1d6ef2Sbeveloper 	TRACE("fInputSampleSize        %ld\n", fInputSampleSize);
407bb1d6ef2Sbeveloper 	TRACE("fOutputSampleSize       %ld\n", fOutputSampleSize);
408bb1d6ef2Sbeveloper 	TRACE("fOutputBufferFrameCount %ld\n", fOutputBufferFrameCount);
409bb1d6ef2Sbeveloper 	TRACE("fSwapInput              %p\n", fSwapInput);
410bb1d6ef2Sbeveloper 	TRACE("fConvert                %p\n", fConvert);
411bb1d6ef2Sbeveloper 	TRACE("fSwapOutput             %p\n", fSwapOutput);
412bb1d6ef2Sbeveloper */
413ca16f5cbSbeveloper 	return B_OK;
414ca16f5cbSbeveloper }
415ca16f5cbSbeveloper 
416ca16f5cbSbeveloper 
417ca16f5cbSbeveloper status_t
418d8591482Sbeveloper RawDecoder::Seek(uint32 seekTo,
419bce1ab5eSbeveloper 				 int64 seekFrame, int64 *frame,
420bce1ab5eSbeveloper 				 bigtime_t seekTime, bigtime_t *time)
421ca16f5cbSbeveloper {
422bb1d6ef2Sbeveloper 	fChunkSize = 0;
423bb1d6ef2Sbeveloper 	fStartTime = *time;
424ca16f5cbSbeveloper 	return B_OK;
425ca16f5cbSbeveloper }
426ca16f5cbSbeveloper 
427ca16f5cbSbeveloper 
428ca16f5cbSbeveloper status_t
429ca16f5cbSbeveloper RawDecoder::Decode(void *buffer, int64 *frameCount,
430d8591482Sbeveloper 				   media_header *mediaHeader, media_decode_info *info /* = 0 */)
431ca16f5cbSbeveloper {
432bb1d6ef2Sbeveloper 	char *output_buffer = (char *)buffer;
433bb1d6ef2Sbeveloper 	mediaHeader->start_time = fStartTime;
434bb1d6ef2Sbeveloper 	*frameCount = 0;
435bb1d6ef2Sbeveloper 	while (*frameCount < fOutputBufferFrameCount) {
436bb1d6ef2Sbeveloper 		if (fChunkSize == 0) {
437bb1d6ef2Sbeveloper 			media_header mh;
4382d923d67Sbeveloper 			status_t err;
439bb1d6ef2Sbeveloper 			err = GetNextChunk((void **)&fChunkBuffer, &fChunkSize, &mh);
440bb1d6ef2Sbeveloper 			if (err != B_OK || fChunkSize < fInputFrameSize) {
441bb1d6ef2Sbeveloper 				fChunkSize = 0;
442bb1d6ef2Sbeveloper 				break;
443bb1d6ef2Sbeveloper 			}
444bb1d6ef2Sbeveloper 			if (fSwapInput)
445bb1d6ef2Sbeveloper 				fSwapInput(fChunkBuffer, fChunkSize / fInputSampleSize);
446bb1d6ef2Sbeveloper 			fStartTime = mh.start_time;
447bb1d6ef2Sbeveloper 			continue;
448bb1d6ef2Sbeveloper 		}
449bb1d6ef2Sbeveloper 		int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize);
450bb1d6ef2Sbeveloper 		int32 samples = frames * fInputFormat.u.raw_audio.channel_count;
451bb1d6ef2Sbeveloper 		fConvert(output_buffer, fChunkBuffer, samples);
452bb1d6ef2Sbeveloper 		fChunkBuffer += frames * fInputFrameSize;
453bb1d6ef2Sbeveloper 		fChunkSize -= frames * fInputFrameSize;
454bb1d6ef2Sbeveloper 		output_buffer += frames * fOutputFrameSize;
455bb1d6ef2Sbeveloper 		*frameCount += frames;
456bb1d6ef2Sbeveloper 		fStartTime +=  (1000000LL * frames) / fFrameRate;
457bb1d6ef2Sbeveloper 	}
458bb1d6ef2Sbeveloper 	// XXX should change channel order here for
459bb1d6ef2Sbeveloper 	// B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF
4602d923d67Sbeveloper 
461bb1d6ef2Sbeveloper 	if (fSwapOutput)
462bb1d6ef2Sbeveloper 		fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count);
463bb1d6ef2Sbeveloper 	return *frameCount ? B_OK : B_ERROR;
464ca16f5cbSbeveloper }
465ca16f5cbSbeveloper 
466ca16f5cbSbeveloper 
467ca16f5cbSbeveloper Decoder *
468ca16f5cbSbeveloper RawDecoderPlugin::NewDecoder()
469ca16f5cbSbeveloper {
470ca16f5cbSbeveloper 	return new RawDecoder;
471ca16f5cbSbeveloper }
472ca16f5cbSbeveloper 
473bce1ab5eSbeveloper status_t
474bce1ab5eSbeveloper RawDecoderPlugin::RegisterPlugin()
475bce1ab5eSbeveloper {
476bb1d6ef2Sbeveloper 	PublishDecoder("audiocodec/raw", "raw", "RAW audio decoder");
477da87cefeSbeveloper 	PublishDecoder("videocodec/raw", "raw", "RAW video decoder");
478bce1ab5eSbeveloper 	return B_OK;
479bce1ab5eSbeveloper }
480ca16f5cbSbeveloper 
481ca16f5cbSbeveloper MediaPlugin *instantiate_plugin()
482ca16f5cbSbeveloper {
483ca16f5cbSbeveloper 	return new RawDecoderPlugin;
484ca16f5cbSbeveloper }
485