xref: /haiku/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp (revision fe0570240ca77b0538554cbd8ec80991bb8356ba)
1a7871de2Sbeveloper /*
2a7871de2Sbeveloper  * Copyright (c) 2003-2004, Marcus Overhagen
3a7871de2Sbeveloper  * All rights reserved.
4a7871de2Sbeveloper  *
5a7871de2Sbeveloper  * Redistribution and use in source and binary forms, with or without modification,
6a7871de2Sbeveloper  * are permitted provided that the following conditions are met:
7a7871de2Sbeveloper  *
8a7871de2Sbeveloper  *  * Redistributions of source code must retain the above copyright notice,
9a7871de2Sbeveloper  *    this list of conditions and the following disclaimer.
10a7871de2Sbeveloper  *  * Redistributions in binary form must reproduce the above copyright notice,
11a7871de2Sbeveloper  *    this list of conditions and the following disclaimer in the documentation
12a7871de2Sbeveloper  *    and/or other materials provided with the distribution.
13a7871de2Sbeveloper  *
14a7871de2Sbeveloper  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15a7871de2Sbeveloper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16a7871de2Sbeveloper  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17a7871de2Sbeveloper  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18a7871de2Sbeveloper  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19a7871de2Sbeveloper  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20a7871de2Sbeveloper  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21a7871de2Sbeveloper  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22a7871de2Sbeveloper  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
23a7871de2Sbeveloper  * OF THE POSSIBILITY OF SUCH DAMAGE.
24a7871de2Sbeveloper  */
25ca16f5cbSbeveloper #include <stdio.h>
26bce1ab5eSbeveloper #include <string.h>
27ca16f5cbSbeveloper #include <DataIO.h>
28bb1d6ef2Sbeveloper #include <OS.h>
29bb1d6ef2Sbeveloper #include <MediaRoster.h>
30bb1d6ef2Sbeveloper #include "RawFormats.h"
31ca16f5cbSbeveloper #include "RawDecoderPlugin.h"
32bb1d6ef2Sbeveloper #include "AudioConversion.h"
33ca16f5cbSbeveloper 
34a7871de2Sbeveloper //#define TRACE_RAW_DECODER
35a7871de2Sbeveloper #ifdef TRACE_RAW_DECODER
36ca16f5cbSbeveloper   #define TRACE printf
37ca16f5cbSbeveloper #else
38bb1d6ef2Sbeveloper   #define TRACE(a...)
39ca16f5cbSbeveloper #endif
40ca16f5cbSbeveloper 
4154348708Sbeveloper inline size_t
4254348708Sbeveloper AudioBufferSize(int32 channel_count, uint32 sample_format, float frame_rate, bigtime_t buffer_duration = 50000 /* 50 ms */)
4354348708Sbeveloper {
4454348708Sbeveloper 	return (sample_format & 0xf) * channel_count * (size_t)((frame_rate * buffer_duration) / 1000000.0);
4554348708Sbeveloper }
46ca16f5cbSbeveloper 
47a0a20160SAxel Dörfler 
48a0a20160SAxel Dörfler void
496e04e144Sbeveloper RawDecoder::GetCodecInfo(media_codec_info *info)
50a0a20160SAxel Dörfler {
516e04e144Sbeveloper 	strcpy(info->short_name, "raw");
52a0a20160SAxel Dörfler 
53a0a20160SAxel Dörfler 	if (fInputFormat.IsAudio())
546e04e144Sbeveloper 		strcpy(info->pretty_name, "Raw audio decoder");
55a0a20160SAxel Dörfler 	else
566e04e144Sbeveloper 		strcpy(info->pretty_name, "Raw video decoder");
57a0a20160SAxel Dörfler }
58a0a20160SAxel Dörfler 
59a0a20160SAxel Dörfler 
60ca16f5cbSbeveloper status_t
6125305239Sbeveloper RawDecoder::Setup(media_format *ioEncodedFormat,
620d1adad3SMarcus Overhagen 				  const void *infoBuffer, size_t infoSize)
63ca16f5cbSbeveloper {
64bb1d6ef2Sbeveloper 	char s[200];
65bb1d6ef2Sbeveloper 	string_for_format(*ioEncodedFormat, s, sizeof(s));
66bb1d6ef2Sbeveloper 	TRACE("RawDecoder::Setup: %s\n", s);
67bb1d6ef2Sbeveloper 
68bce1ab5eSbeveloper 	if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO)
69ca16f5cbSbeveloper 		return B_ERROR;
70ca16f5cbSbeveloper 
7125305239Sbeveloper 	fInputFormat = *ioEncodedFormat;
7225305239Sbeveloper 
73bb1d6ef2Sbeveloper 	if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO) {
74bb1d6ef2Sbeveloper 		fInputSampleSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row;
75bb1d6ef2Sbeveloper 		fInputFrameSize = fInputSampleSize;
76bb1d6ef2Sbeveloper 	} else {
77bb1d6ef2Sbeveloper 		fInputSampleSize = (ioEncodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
78bb1d6ef2Sbeveloper 		fInputFrameSize = fInputSampleSize * ioEncodedFormat->u.raw_audio.channel_count;
79bb1d6ef2Sbeveloper 	}
80bb1d6ef2Sbeveloper 
81bb1d6ef2Sbeveloper 	// since ioEncodedFormat is later passed to the application by BMediaTrack::EncodedFormat()
82bb1d6ef2Sbeveloper 	// we need to remove non public format specifications
83bb1d6ef2Sbeveloper 
84bb1d6ef2Sbeveloper 	// remove non format bits, like channel order
85bb1d6ef2Sbeveloper 	ioEncodedFormat->u.raw_audio.format &= B_AUDIO_FORMAT_MASK;
86bb1d6ef2Sbeveloper 
87bb1d6ef2Sbeveloper 	switch (ioEncodedFormat->u.raw_audio.format) {
88bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_UINT8:
89bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT8:
90bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT16:
91bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT32:
92bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT32:
93bb1d6ef2Sbeveloper 			break; // ok to pass through
94bb1d6ef2Sbeveloper 
95bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT24:
96bb1d6ef2Sbeveloper 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_INT32;
97bb1d6ef2Sbeveloper 			break;
98bb1d6ef2Sbeveloper 
99bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT64:
100bb1d6ef2Sbeveloper 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_FLOAT32;
101bb1d6ef2Sbeveloper 			break;
102bb1d6ef2Sbeveloper 
103bb1d6ef2Sbeveloper 		default:
104bb1d6ef2Sbeveloper 			TRACE("RawDecoder::Setup: unknown input format\n");
105bb1d6ef2Sbeveloper 			return B_ERROR;
106bb1d6ef2Sbeveloper 	}
107bce1ab5eSbeveloper 
10854348708Sbeveloper 	// since we can translate to a different buffer size,
10954348708Sbeveloper 	// suggest something nicer than delivered by the
11054348708Sbeveloper 	// file reader (perhaps we should even report wildcard?)
111*fe057024SDavid McPaul 	// I don't believe we can negotiate the buffer size with the reader
112*fe057024SDavid McPaul //	ioEncodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
113*fe057024SDavid McPaul //														ioEncodedFormat->u.raw_audio.channel_count,
114*fe057024SDavid McPaul //														ioEncodedFormat->u.raw_audio.format,
115*fe057024SDavid McPaul //														ioEncodedFormat->u.raw_audio.frame_rate);
11625305239Sbeveloper 	return B_OK;
11725305239Sbeveloper }
118bce1ab5eSbeveloper 
11925305239Sbeveloper 
12025305239Sbeveloper status_t
12125305239Sbeveloper RawDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
12225305239Sbeveloper {
12325305239Sbeveloper 	// BeBook says: The codec will find and return in ioFormat its best matching format
12425305239Sbeveloper 	// => This means, we never return an error, and always change the format values
12525305239Sbeveloper 	//    that we don't support to something more applicable
1266736ae52Sbeveloper 	if (fInputFormat.type == B_MEDIA_RAW_VIDEO)
127bb1d6ef2Sbeveloper 		return NegotiateVideoOutputFormat(ioDecodedFormat);
1286736ae52Sbeveloper 	if (fInputFormat.type == B_MEDIA_RAW_AUDIO)
129bb1d6ef2Sbeveloper 		return NegotiateAudioOutputFormat(ioDecodedFormat);
1306736ae52Sbeveloper 	debugger("RawDecoder::NegotiateOutputFormat: wrong encoded format type");
131bb1d6ef2Sbeveloper 	return B_ERROR;
132bb1d6ef2Sbeveloper }
13325305239Sbeveloper 
134bb1d6ef2Sbeveloper 
135bb1d6ef2Sbeveloper status_t
136bb1d6ef2Sbeveloper RawDecoder::NegotiateVideoOutputFormat(media_format *ioDecodedFormat)
137bb1d6ef2Sbeveloper {
138bb1d6ef2Sbeveloper 	return B_ERROR;
139bb1d6ef2Sbeveloper }
140bb1d6ef2Sbeveloper 
141bb1d6ef2Sbeveloper 
142bb1d6ef2Sbeveloper status_t
143bb1d6ef2Sbeveloper RawDecoder::NegotiateAudioOutputFormat(media_format *ioDecodedFormat)
144bb1d6ef2Sbeveloper {
1454ba72fcdSbeveloper 	char s[1024];
1464ba72fcdSbeveloper 
147*fe057024SDavid McPaul 	TRACE("RawDecoder::NegotiateAudioOutputFormat enter:\n");
1484ba72fcdSbeveloper 
149bb1d6ef2Sbeveloper 	ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
150bb1d6ef2Sbeveloper 	switch (ioDecodedFormat->u.raw_audio.format) {
151bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_FLOAT:
152bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_SHORT:
153bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_UCHAR:
154bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_CHAR:
155bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = 0;
156bb1d6ef2Sbeveloper 			break; // we can produce this on request
157a3d7908eSbeveloper 
158bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_INT:
159bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
160bb1d6ef2Sbeveloper 			break; // we can produce this on request
161bb1d6ef2Sbeveloper 
162bb1d6ef2Sbeveloper 		default:
163bb1d6ef2Sbeveloper 			switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
164bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_SHORT:
165bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_UCHAR:
166bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_CHAR:
167bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK;
168bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
169bb1d6ef2Sbeveloper 					break;
170bb1d6ef2Sbeveloper 
171bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_INT:
172bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT24:
173bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT;
174bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
175bb1d6ef2Sbeveloper 					break;
176bb1d6ef2Sbeveloper 
177bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_FLOAT:
178bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT64:
179bb1d6ef2Sbeveloper 				default:
180bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
181bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
182bb1d6ef2Sbeveloper 					break;
183bb1d6ef2Sbeveloper 			}
184bb1d6ef2Sbeveloper 			break;
185bb1d6ef2Sbeveloper 	}
186bb1d6ef2Sbeveloper 
187bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.frame_rate = fInputFormat.u.raw_audio.frame_rate;
188bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.channel_count = fInputFormat.u.raw_audio.channel_count;
189bb1d6ef2Sbeveloper 
1906736ae52Sbeveloper 	fFrameRate = (int32) ioDecodedFormat->u.raw_audio.frame_rate;
1916736ae52Sbeveloper 
192bb1d6ef2Sbeveloper 	fOutputSampleSize = (ioDecodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
193bb1d6ef2Sbeveloper 	fOutputFrameSize = fOutputSampleSize * ioDecodedFormat->u.raw_audio.channel_count;
194bb1d6ef2Sbeveloper 
195bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == 0)
196bb1d6ef2Sbeveloper 		ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
197bb1d6ef2Sbeveloper 
198bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.channel_mask = 0;
199bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.matrix_mask = 0;
200bb1d6ef2Sbeveloper 
201*fe057024SDavid McPaul 	ioDecodedFormat->u.raw_audio.buffer_size = fInputFormat.u.raw_audio.buffer_size;
202*fe057024SDavid McPaul 
203*fe057024SDavid McPaul // I don't believe we can negotiate the buffer size with the reader
204*fe057024SDavid McPaul // the decoder might use a different buffer for output but it must read all bytes given.
205*fe057024SDavid McPaul //	if (ioDecodedFormat->u.raw_audio.buffer_size < 128 || ioDecodedFormat->u.raw_audio.buffer_size > 65536) {
206*fe057024SDavid McPaul //		ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
207*fe057024SDavid McPaul //														ioDecodedFormat->u.raw_audio.channel_count,
208*fe057024SDavid McPaul //														ioDecodedFormat->u.raw_audio.format,
209*fe057024SDavid McPaul //														ioDecodedFormat->u.raw_audio.frame_rate);
210*fe057024SDavid McPaul //	} else {
211bb1d6ef2Sbeveloper 		// round down to exact multiple of output frame size
212*fe057024SDavid McPaul //		ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize) * fOutputFrameSize;
213*fe057024SDavid McPaul //	}
214bb1d6ef2Sbeveloper 
215bb1d6ef2Sbeveloper 	fOutputBufferFrameCount = ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize;
216bb1d6ef2Sbeveloper 
217bb1d6ef2Sbeveloper 	// setup input swapping function
218bb1d6ef2Sbeveloper 	if (fInputFormat.u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
219bb1d6ef2Sbeveloper 		fSwapInput = 0;
220bb1d6ef2Sbeveloper 	} else {
221bb1d6ef2Sbeveloper 		switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
222bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
223bb1d6ef2Sbeveloper 				fSwapInput = &swap_int16;
224bb1d6ef2Sbeveloper 				break;
225bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT24:
226bb1d6ef2Sbeveloper 				fSwapInput = &swap_int24;
227bb1d6ef2Sbeveloper 				break;
228bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
229bb1d6ef2Sbeveloper 				fSwapInput = &swap_int32;
230bb1d6ef2Sbeveloper 				break;
231bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
232bb1d6ef2Sbeveloper 				fSwapInput = &swap_float32;
233bb1d6ef2Sbeveloper 				break;
234bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT64:
235bb1d6ef2Sbeveloper 				fSwapInput = &swap_float64;
236bb1d6ef2Sbeveloper 				break;
237bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
238bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
239bb1d6ef2Sbeveloper 				fSwapInput = 0;
240bb1d6ef2Sbeveloper 				break;
241bb1d6ef2Sbeveloper 			default:
24216611de7Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
243bb1d6ef2Sbeveloper 				break;
244bb1d6ef2Sbeveloper 		}
245bb1d6ef2Sbeveloper 	}
246bb1d6ef2Sbeveloper 
247bb1d6ef2Sbeveloper 	// setup output swapping function
248bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
249bb1d6ef2Sbeveloper 		fSwapOutput = 0;
250bb1d6ef2Sbeveloper 	} else {
251bb1d6ef2Sbeveloper 		switch (ioDecodedFormat->u.raw_audio.format) {
252bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
253bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int16;
254bb1d6ef2Sbeveloper 				break;
255bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
256bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int32;
257bb1d6ef2Sbeveloper 				break;
258bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
259bb1d6ef2Sbeveloper 				fSwapOutput = &swap_float32;
260bb1d6ef2Sbeveloper 				break;
261bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
262bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
263bb1d6ef2Sbeveloper 				fSwapOutput = 0;
264bb1d6ef2Sbeveloper 				break;
265bb1d6ef2Sbeveloper 			default:
26616611de7Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
267bb1d6ef2Sbeveloper 				break;
268bb1d6ef2Sbeveloper 		}
269bb1d6ef2Sbeveloper 	}
270bb1d6ef2Sbeveloper 
271bb1d6ef2Sbeveloper 	// setup sample conversation function
272bb1d6ef2Sbeveloper 	switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
273bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_UINT8:
274bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
275bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
276bb1d6ef2Sbeveloper 					fConvert = &uint8_to_uint8;
277bb1d6ef2Sbeveloper 					break;
278bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
279bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int8;
280bb1d6ef2Sbeveloper 					break;
281bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
282bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int16;
283bb1d6ef2Sbeveloper 					break;
284bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
285bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int32;
286bb1d6ef2Sbeveloper 					break;
287bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
288bb1d6ef2Sbeveloper 					fConvert = &uint8_to_float32;
289bb1d6ef2Sbeveloper 					break;
290bb1d6ef2Sbeveloper 				default:
29116611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
292bb1d6ef2Sbeveloper 					break;
293bb1d6ef2Sbeveloper 			}
294bb1d6ef2Sbeveloper 			break;
295bb1d6ef2Sbeveloper 
296bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT8:
297bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
298bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
299bb1d6ef2Sbeveloper 					fConvert = &int8_to_uint8;
300bb1d6ef2Sbeveloper 					break;
301bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
302bb1d6ef2Sbeveloper 					fConvert = &int8_to_int8;
303bb1d6ef2Sbeveloper 					break;
304bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
305bb1d6ef2Sbeveloper 					fConvert = &int8_to_int16;
306bb1d6ef2Sbeveloper 					break;
307bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
308bb1d6ef2Sbeveloper 					fConvert = &int8_to_int32;
309bb1d6ef2Sbeveloper 					break;
310bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
311bb1d6ef2Sbeveloper 					fConvert = &int8_to_float32;
312bb1d6ef2Sbeveloper 					break;
313bb1d6ef2Sbeveloper 				default:
31416611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
315bb1d6ef2Sbeveloper 					break;
316bb1d6ef2Sbeveloper 			}
317bb1d6ef2Sbeveloper 			break;
318bb1d6ef2Sbeveloper 
319bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT16:
320bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
321bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
322bb1d6ef2Sbeveloper 					fConvert = &int16_to_uint8;
323bb1d6ef2Sbeveloper 					break;
324bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
325bb1d6ef2Sbeveloper 					fConvert = &int16_to_int8;
326bb1d6ef2Sbeveloper 					break;
327bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
328bb1d6ef2Sbeveloper 					fConvert = &int16_to_int16;
329bb1d6ef2Sbeveloper 					break;
330bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
331bb1d6ef2Sbeveloper 					fConvert = &int16_to_int32;
332bb1d6ef2Sbeveloper 					break;
333bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
334bb1d6ef2Sbeveloper 					fConvert = &int16_to_float32;
335bb1d6ef2Sbeveloper 					break;
336bb1d6ef2Sbeveloper 				default:
33716611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
338bb1d6ef2Sbeveloper 					break;
339bb1d6ef2Sbeveloper 			}
340bb1d6ef2Sbeveloper 			break;
341bb1d6ef2Sbeveloper 
342bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT24:
343bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
344bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
345bb1d6ef2Sbeveloper 					fConvert = &int24_to_uint8;
346bb1d6ef2Sbeveloper 					break;
347bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
348bb1d6ef2Sbeveloper 					fConvert = &int24_to_int8;
349bb1d6ef2Sbeveloper 					break;
350bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
351bb1d6ef2Sbeveloper 					fConvert = &int24_to_int16;
352bb1d6ef2Sbeveloper 					break;
353bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
354bb1d6ef2Sbeveloper 					fConvert = &int24_to_int32;
355bb1d6ef2Sbeveloper 					break;
356bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
357bb1d6ef2Sbeveloper 					fConvert = &int24_to_float32;
358bb1d6ef2Sbeveloper 					break;
359bb1d6ef2Sbeveloper 				default:
36016611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
361bb1d6ef2Sbeveloper 					break;
362bb1d6ef2Sbeveloper 			}
363bb1d6ef2Sbeveloper 			break;
364bb1d6ef2Sbeveloper 
365bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT32:
366bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
367bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
368bb1d6ef2Sbeveloper 					fConvert = &int32_to_uint8;
369bb1d6ef2Sbeveloper 					break;
370bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
371bb1d6ef2Sbeveloper 					fConvert = &int32_to_int8;
372bb1d6ef2Sbeveloper 					break;
373bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
374bb1d6ef2Sbeveloper 					fConvert = &int32_to_int16;
375bb1d6ef2Sbeveloper 					break;
376bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
377bb1d6ef2Sbeveloper 					fConvert = &int32_to_int32;
378bb1d6ef2Sbeveloper 					break;
379bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
380bb1d6ef2Sbeveloper 					fConvert = &int32_to_float32;
381bb1d6ef2Sbeveloper 					break;
382bb1d6ef2Sbeveloper 				default:
38316611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
384bb1d6ef2Sbeveloper 					break;
385bb1d6ef2Sbeveloper 			}
386bb1d6ef2Sbeveloper 			break;
387bb1d6ef2Sbeveloper 
388bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT32:
389bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
390bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
391bb1d6ef2Sbeveloper 					fConvert = &float32_to_uint8;
392bb1d6ef2Sbeveloper 					break;
393bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
394bb1d6ef2Sbeveloper 					fConvert = &float32_to_int8;
395bb1d6ef2Sbeveloper 					break;
396bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
397bb1d6ef2Sbeveloper 					fConvert = &float32_to_int16;
398bb1d6ef2Sbeveloper 					break;
399bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
400bb1d6ef2Sbeveloper 					fConvert = &float32_to_int32;
401bb1d6ef2Sbeveloper 					break;
402bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
403bb1d6ef2Sbeveloper 					fConvert = &float32_to_float32;
404bb1d6ef2Sbeveloper 					break;
405bb1d6ef2Sbeveloper 				default:
40616611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
407bb1d6ef2Sbeveloper 					break;
408bb1d6ef2Sbeveloper 			}
409bb1d6ef2Sbeveloper 			break;
410bb1d6ef2Sbeveloper 
411bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT64:
412bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
413bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
414bb1d6ef2Sbeveloper 					fConvert = &float64_to_uint8;
415bb1d6ef2Sbeveloper 					break;
416bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
417bb1d6ef2Sbeveloper 					fConvert = &float64_to_int8;
418bb1d6ef2Sbeveloper 					break;
419bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
420bb1d6ef2Sbeveloper 					fConvert = &float64_to_int16;
421bb1d6ef2Sbeveloper 					break;
422bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
423bb1d6ef2Sbeveloper 					fConvert = &float64_to_int32;
424bb1d6ef2Sbeveloper 					break;
425bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
426bb1d6ef2Sbeveloper 					fConvert = &float64_to_float32;
427bb1d6ef2Sbeveloper 					break;
428bb1d6ef2Sbeveloper 				default:
42916611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
430bb1d6ef2Sbeveloper 					break;
431bb1d6ef2Sbeveloper 			}
432bb1d6ef2Sbeveloper 			break;
433bb1d6ef2Sbeveloper 
434bb1d6ef2Sbeveloper 		default:
43516611de7Sbeveloper 			debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
436bb1d6ef2Sbeveloper 			break;
437bb1d6ef2Sbeveloper 	}
438bb1d6ef2Sbeveloper 
439bb1d6ef2Sbeveloper 	fChunkBuffer = 0;
440bb1d6ef2Sbeveloper 	fChunkSize = 0;
441bb1d6ef2Sbeveloper 	fStartTime = 0;
4424ba72fcdSbeveloper 
4434ba72fcdSbeveloper 	string_for_format(*ioDecodedFormat, s, sizeof(s));
444bb1d6ef2Sbeveloper 	TRACE("RawDecoder::NegotiateAudioOutputFormat leave: %s\n", s);
4456736ae52Sbeveloper 
4466736ae52Sbeveloper 	if (ioDecodedFormat->type == 0)
4476736ae52Sbeveloper 		debugger("RawDecoder::NegotiateAudioOutputFormat ioDecodedFormat->type == 0");
448bb1d6ef2Sbeveloper /*
449bb1d6ef2Sbeveloper 	TRACE("fFrameRate              %ld\n", fFrameRate);
450bb1d6ef2Sbeveloper 	TRACE("fInputFrameSize         %ld\n", fInputFrameSize);
451bb1d6ef2Sbeveloper 	TRACE("fOutputFrameSize        %ld\n", fOutputFrameSize);
452bb1d6ef2Sbeveloper 	TRACE("fInputSampleSize        %ld\n", fInputSampleSize);
453bb1d6ef2Sbeveloper 	TRACE("fOutputSampleSize       %ld\n", fOutputSampleSize);
454bb1d6ef2Sbeveloper 	TRACE("fOutputBufferFrameCount %ld\n", fOutputBufferFrameCount);
455bb1d6ef2Sbeveloper 	TRACE("fSwapInput              %p\n", fSwapInput);
456bb1d6ef2Sbeveloper 	TRACE("fConvert                %p\n", fConvert);
457bb1d6ef2Sbeveloper 	TRACE("fSwapOutput             %p\n", fSwapOutput);
458bb1d6ef2Sbeveloper */
459ca16f5cbSbeveloper 	return B_OK;
460ca16f5cbSbeveloper }
461ca16f5cbSbeveloper 
462ca16f5cbSbeveloper 
463ca16f5cbSbeveloper status_t
464d8591482Sbeveloper RawDecoder::Seek(uint32 seekTo,
465bce1ab5eSbeveloper 				 int64 seekFrame, int64 *frame,
466bce1ab5eSbeveloper 				 bigtime_t seekTime, bigtime_t *time)
467ca16f5cbSbeveloper {
468bb1d6ef2Sbeveloper 	fChunkSize = 0;
469bb1d6ef2Sbeveloper 	fStartTime = *time;
470ca16f5cbSbeveloper 	return B_OK;
471ca16f5cbSbeveloper }
472ca16f5cbSbeveloper 
473ca16f5cbSbeveloper 
474ca16f5cbSbeveloper status_t
475ca16f5cbSbeveloper RawDecoder::Decode(void *buffer, int64 *frameCount,
476d8591482Sbeveloper 				   media_header *mediaHeader, media_decode_info *info /* = 0 */)
477ca16f5cbSbeveloper {
478bb1d6ef2Sbeveloper 	char *output_buffer = (char *)buffer;
479bb1d6ef2Sbeveloper 	mediaHeader->start_time = fStartTime;
480bb1d6ef2Sbeveloper 	*frameCount = 0;
481bb1d6ef2Sbeveloper 	while (*frameCount < fOutputBufferFrameCount) {
482bb1d6ef2Sbeveloper 		if (fChunkSize == 0) {
483bb1d6ef2Sbeveloper 			media_header mh;
4842d923d67Sbeveloper 			status_t err;
4850d1adad3SMarcus Overhagen 			err = GetNextChunk(&fChunkBuffer, &fChunkSize, &mh);
486bb1d6ef2Sbeveloper 			if (err != B_OK || fChunkSize < fInputFrameSize) {
487bb1d6ef2Sbeveloper 				fChunkSize = 0;
488bb1d6ef2Sbeveloper 				break;
489bb1d6ef2Sbeveloper 			}
490bb1d6ef2Sbeveloper 			if (fSwapInput)
4910d1adad3SMarcus Overhagen 				fSwapInput(const_cast<void *>(fChunkBuffer), fChunkSize / fInputSampleSize); // XXX TODO! FIX THIS, we write to a const buffer!!!
492bb1d6ef2Sbeveloper 			fStartTime = mh.start_time;
493bb1d6ef2Sbeveloper 			continue;
494bb1d6ef2Sbeveloper 		}
495bb1d6ef2Sbeveloper 		int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize);
49634faa5f2SMaurice Kalinowski 		if (frames == 0)
49734faa5f2SMaurice Kalinowski 			break;
49834faa5f2SMaurice Kalinowski 
499bb1d6ef2Sbeveloper 		int32 samples = frames * fInputFormat.u.raw_audio.channel_count;
500bb1d6ef2Sbeveloper 		fConvert(output_buffer, fChunkBuffer, samples);
5010d1adad3SMarcus Overhagen 		fChunkBuffer = (const char *)fChunkBuffer + frames * fInputFrameSize;
502bb1d6ef2Sbeveloper 		fChunkSize -= frames * fInputFrameSize;
503bb1d6ef2Sbeveloper 		output_buffer += frames * fOutputFrameSize;
504bb1d6ef2Sbeveloper 		*frameCount += frames;
505bb1d6ef2Sbeveloper 		fStartTime +=  (1000000LL * frames) / fFrameRate;
506bb1d6ef2Sbeveloper 	}
507bb1d6ef2Sbeveloper 	// XXX should change channel order here for
508bb1d6ef2Sbeveloper 	// B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF
5092d923d67Sbeveloper 
510bb1d6ef2Sbeveloper 	if (fSwapOutput)
511bb1d6ef2Sbeveloper 		fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count);
512*fe057024SDavid McPaul 
513*fe057024SDavid McPaul 	TRACE("framecount %Ld, time %Ld\n",*frameCount, mediaHeader->start_time);
514*fe057024SDavid McPaul 
515bb1d6ef2Sbeveloper 	return *frameCount ? B_OK : B_ERROR;
516ca16f5cbSbeveloper }
517ca16f5cbSbeveloper 
518ca16f5cbSbeveloper 
519ca16f5cbSbeveloper Decoder *
520fa8dbc01Sshatty RawDecoderPlugin::NewDecoder(uint index)
521ca16f5cbSbeveloper {
522ca16f5cbSbeveloper 	return new RawDecoder;
523ca16f5cbSbeveloper }
524ca16f5cbSbeveloper 
525fa8dbc01Sshatty 
526fa8dbc01Sshatty static media_format raw_formats[2];
527fa8dbc01Sshatty 
528bce1ab5eSbeveloper status_t
529fa8dbc01Sshatty RawDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
530bce1ab5eSbeveloper {
531fa8dbc01Sshatty 	BMediaFormats mediaFormats;
532a0a20160SAxel Dörfler 	media_format_description description;
533a0a20160SAxel Dörfler 	media_format format;
534a0a20160SAxel Dörfler 
535a0a20160SAxel Dörfler 	// audio decoder
536a0a20160SAxel Dörfler 
53740d68dd2Sbeveloper 	description.family = B_BEOS_FORMAT_FAMILY;
538a0a20160SAxel Dörfler 	description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO;
53940d68dd2Sbeveloper 	format.type = B_MEDIA_RAW_AUDIO;
54040d68dd2Sbeveloper 	format.u.raw_audio = media_multi_audio_format::wildcard;
541a0a20160SAxel Dörfler 
542fa8dbc01Sshatty 	status_t status = mediaFormats.MakeFormatFor(&description, 1, &format);
543a0a20160SAxel Dörfler 	if (status < B_OK)
544a0a20160SAxel Dörfler 		return status;
545fa8dbc01Sshatty 	raw_formats[0] = format;
546a0a20160SAxel Dörfler 
547a0a20160SAxel Dörfler 	// video decoder
548a0a20160SAxel Dörfler 
549a0a20160SAxel Dörfler 	description.u.beos.format = B_BEOS_FORMAT_RAW_VIDEO;
55040d68dd2Sbeveloper 	format.type = B_MEDIA_RAW_VIDEO;
55140d68dd2Sbeveloper 	format.u.raw_video = media_raw_video_format::wildcard;
552a0a20160SAxel Dörfler 
553fa8dbc01Sshatty 	status = mediaFormats.MakeFormatFor(&description, 1, &format);
554fa8dbc01Sshatty 	if (status < B_OK)
555fa8dbc01Sshatty 		return status;
556fa8dbc01Sshatty 	raw_formats[1] = format;
557fa8dbc01Sshatty 
558fa8dbc01Sshatty 	*formats = raw_formats;
559fa8dbc01Sshatty 	*count = 2;
560fa8dbc01Sshatty 
561fa8dbc01Sshatty 	return B_OK;
562bce1ab5eSbeveloper }
563ca16f5cbSbeveloper 
564ca16f5cbSbeveloper MediaPlugin *instantiate_plugin()
565ca16f5cbSbeveloper {
566ca16f5cbSbeveloper 	return new RawDecoderPlugin;
567ca16f5cbSbeveloper }
568