Hardcode IMA4 sound description

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25448 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2008-05-11 13:09:54 +00:00
parent 2f00291de2
commit ab38d6b5ee
4 changed files with 75 additions and 27 deletions
@@ -457,12 +457,25 @@ const AudioMetaData *MOVFileReader::AudioFormat(uint32 stream_index)
// Hmm 16bit format 32 bit FourCC. // Hmm 16bit format 32 bit FourCC.
theAudio.compression = aSoundDescription.basefields.DataFormat; theAudio.compression = aSoundDescription.basefields.DataFormat;
// theAudio.compression = aSoundDescription.desc.CompressionID;
theAudio.NoOfChannels = aSoundDescription.desc.NoOfChannels; theAudio.NoOfChannels = aSoundDescription.desc.NoOfChannels;
theAudio.SampleSize = aSoundDescription.desc.SampleSize; theAudio.SampleSize = aSoundDescription.desc.SampleSize;
theAudio.SampleRate = aSoundDescription.desc.SampleRate / 65536; // Convert from fixed point decimal to float theAudio.SampleRate = aSoundDescription.desc.SampleRate / 65536; // Convert from fixed point decimal to float
theAudio.PacketSize = uint32((theAudio.SampleRate * theAudio.NoOfChannels * theAudio.SampleSize) / 8);
if (aSoundDescription.bytesPerFrame == 0) {
// XXX probably not right
theAudio.FrameSize = aSoundDescription.desc.SampleSize / 8;
} else {
theAudio.FrameSize = aSoundDescription.bytesPerFrame;
}
if (aSoundDescription.bytesPerPacket == 0) {
theAudio.BufferSize = uint32((theAudio.SampleSize * theAudio.NoOfChannels * theAudio.FrameSize) / 8);
} else {
theAudio.BufferSize = aSoundDescription.bytesPerPacket;
}
theAudio.BitRate = theAudio.SampleSize * theAudio.NoOfChannels * theAudio.SampleRate;
theAudio.theVOL = aSoundDescription.theVOL; theAudio.theVOL = aSoundDescription.theVOL;
theAudio.VOLSize = aSoundDescription.VOLSize; theAudio.VOLSize = aSoundDescription.VOLSize;
@@ -816,7 +816,8 @@ void STSDAtom::ReadSoundDescription()
Read(&aSoundDescriptionV1->desc.PacketSize); Read(&aSoundDescriptionV1->desc.PacketSize);
Read(&aSoundDescriptionV1->desc.SampleRate); Read(&aSoundDescriptionV1->desc.SampleRate);
if (aSoundDescriptionV1->desc.Version == 1) { if ((aSoundDescriptionV1->desc.Version == 1) && (aSoundDescriptionV1->basefields.DataFormat != AUDIO_IMA4)) {
printf("V1 Sound Description Found\n");
Read(&(aSoundDescriptionV1->samplesPerPacket)); Read(&(aSoundDescriptionV1->samplesPerPacket));
Read(&(aSoundDescriptionV1->bytesPerPacket)); Read(&(aSoundDescriptionV1->bytesPerPacket));
Read(&(aSoundDescriptionV1->bytesPerFrame)); Read(&(aSoundDescriptionV1->bytesPerFrame));
@@ -824,14 +825,20 @@ void STSDAtom::ReadSoundDescription()
} else { } else {
// Calculate? // Calculate?
aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8; if (aSoundDescriptionV1->basefields.DataFormat == AUDIO_IMA4) {
if (aSoundDescriptionV1->basefields.DataFormat == 'ima4') { printf("Calculating IMA4 Sound Description\n");
aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * 64 / 34; aSoundDescriptionV1->samplesPerPacket = 64;
aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * 34;
aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8;
aSoundDescriptionV1->bytesPerPacket = 64 * aSoundDescriptionV1->bytesPerFrame;
} else { } else {
printf("Calculating Sound Description\n");
aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8;
aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * aSoundDescriptionV1->bytesPerSample; aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * aSoundDescriptionV1->bytesPerSample;
aSoundDescriptionV1->bytesPerPacket = aSoundDescriptionV1->desc.PacketSize;
aSoundDescriptionV1->samplesPerPacket = aSoundDescriptionV1->desc.PacketSize / aSoundDescriptionV1->bytesPerFrame;
} }
aSoundDescriptionV1->bytesPerPacket = aSoundDescriptionV1->desc.PacketSize;
aSoundDescriptionV1->samplesPerPacket = aSoundDescriptionV1->desc.PacketSize / aSoundDescriptionV1->bytesPerFrame;
} }
// 0 means we dont have one // 0 means we dont have one
@@ -105,11 +105,13 @@ struct VideoMetaData
struct AudioMetaData struct AudioMetaData
{ {
uint32 compression; // compression used uint32 compression; // compression type used
uint16 NoOfChannels; // 1 = mono, 2 = stereo uint16 NoOfChannels; // 1 = mono, 2 = stereo
uint16 SampleSize; // bits per sample uint16 SampleSize; // bits per sample
float SampleRate; // Samples per second (OR Frames per second) float SampleRate; // Samples per second
uint32 PacketSize; // (Sample Rate * NoOfchannels * SampleSize)/8 = bytes per second uint32 BufferSize; // (Sample Rate * NoOfchannels * SampleSize) / 8 = bytes per second
uint32 FrameSize; // Size of a Frame (NoOfChannels * SampleSize) / 8
float BitRate; // Bitrate of audio
uint8 *theVOL; uint8 *theVOL;
size_t VOLSize; size_t VOLSize;
}; };
@@ -34,7 +34,7 @@
#include "mov_reader.h" #include "mov_reader.h"
//#define TRACE_MOV_READER #define TRACE_MOV_READER
#ifdef TRACE_MOV_READER #ifdef TRACE_MOV_READER
#define TRACE printf #define TRACE printf
#else #else
@@ -136,6 +136,8 @@ movReader::GetFileFormatInfo(media_file_format *mff)
status_t status_t
movReader::AllocateCookie(int32 streamNumber, void **_cookie) movReader::AllocateCookie(int32 streamNumber, void **_cookie)
{ {
uint32 codecID;
mov_cookie *cookie = new mov_cookie; mov_cookie *cookie = new mov_cookie;
*_cookie = cookie; *_cookie = cookie;
@@ -172,6 +174,8 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
return B_ERROR; return B_ERROR;
} }
codecID = B_BENDIAN_TO_HOST_INT32(audio_format->compression);
cookie->frame_count = theFileReader->getAudioFrameCount(cookie->stream); cookie->frame_count = theFileReader->getAudioFrameCount(cookie->stream);
cookie->duration = theFileReader->getAudioDuration(cookie->stream); cookie->duration = theFileReader->getAudioDuration(cookie->stream);
@@ -191,10 +195,10 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
cookie->frames_per_sec_rate = stream_header->rate; cookie->frames_per_sec_rate = stream_header->rate;
cookie->frames_per_sec_scale = 1; cookie->frames_per_sec_scale = 1;
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
} else if (audio_format->PacketSize) { } else if (audio_format->BufferSize) {
cookie->bytes_per_sec_rate = audio_format->PacketSize; cookie->bytes_per_sec_rate = audio_format->BufferSize;
cookie->bytes_per_sec_scale = 1; cookie->bytes_per_sec_scale = 1;
cookie->frames_per_sec_rate = audio_format->PacketSize * 8 / audio_format->SampleSize / audio_format->NoOfChannels; cookie->frames_per_sec_rate = audio_format->BufferSize * 8 / audio_format->SampleSize / audio_format->NoOfChannels;
cookie->frames_per_sec_scale = 1; cookie->frames_per_sec_scale = 1;
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using PacketSize)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale); TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using PacketSize)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
} else { } else {
@@ -259,6 +263,26 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
format->type = B_MEDIA_ENCODED_AUDIO; format->type = B_MEDIA_ENCODED_AUDIO;
} }
format->u.raw_audio.byte_order = B_MEDIA_BIG_ENDIAN;
if (audio_format->SampleSize <= 8)
format->u.raw_audio.format = B_AUDIO_FORMAT_UINT8;
else if (audio_format->SampleSize <= 16)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT16;
else if (audio_format->SampleSize <= 24)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT24;
else if (audio_format->SampleSize <= 32)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT32;
else {
ERROR("movReader::AllocateCookie: unhandled bits per sample %d\n", audio_format->SampleSize);
return B_ERROR;
}
format->u.encoded_audio.frame_size = audio_format->FrameSize;
format->u.encoded_audio.output.buffer_size = audio_format->BufferSize;
TRACE("compression ");
switch (audio_format->compression) { switch (audio_format->compression) {
case AUDIO_MS_PCM02: case AUDIO_MS_PCM02:
TRACE("MS PCM02\n"); TRACE("MS PCM02\n");
@@ -280,9 +304,13 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels; format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
break; break;
case AUDIO_IMA4: case AUDIO_IMA4:
TRACE("IMA4\n");
format->u.encoded_audio.bit_rate = audio_format->BitRate;
format->u.encoded_audio.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;;
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
break;
default: default:
TRACE("OTHER\n"); TRACE("OTHER %s\n",(char *)(&codecID));
format->u.encoded_audio.bit_rate = 8 * cookie->frames_per_sec_rate / cookie->frames_per_sec_scale; format->u.encoded_audio.bit_rate = 8 * cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale; format->u.encoded_audio.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale;
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels; format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
@@ -290,22 +318,18 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
} }
} }
// this doesn't seem to work (it's not even a fourcc) TRACE("Audio NoOfChannels %d, SampleSize %d, SampleRate %f, FrameSize %ld\n",audio_format->NoOfChannels, audio_format->SampleSize, audio_format->SampleRate, audio_format->FrameSize);
format->user_data_type = B_CODEC_TYPE_INFO;
*(uint32 *)format->user_data = audio_format->compression; format->user_data[4] = 0; TRACE("Audio frame_rate %f, channel_count %ld, format %ld, buffer_size %ld, frame_size %ld, bit_rate %f\n",
format->u.encoded_audio.output.frame_rate, format->u.encoded_audio.output.channel_count, format->u.encoded_audio.output.format,format->u.encoded_audio.output.buffer_size, format->u.encoded_audio.frame_size, format->u.encoded_audio.bit_rate);
// Some codecs have additional setup data that they need, put it in metadata // Some codecs have additional setup data that they need, put it in metadata
size_t size = audio_format->VOLSize; size_t size = audio_format->VOLSize;
const void *data = audio_format->theVOL; const void *data = audio_format->theVOL;
if (size > 0) { if (size > 0) {
TRACE("VOL SIZE %ld\n", size);
format->SetMetaData(data, size); format->SetMetaData(data, size);
} }
#ifdef TRACE_MOV_READER
uint8 *p = 18 + (uint8 *)data;
TRACE("extra_data: %ld: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
size - 18, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]);
#endif
return B_OK; return B_OK;
} }
@@ -318,6 +342,8 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
return B_ERROR; return B_ERROR;
} }
codecID = B_BENDIAN_TO_HOST_INT32(video_format->compression);
cookie->audio = false; cookie->audio = false;
cookie->line_count = theFileReader->MovMainHeader()->height; cookie->line_count = theFileReader->MovMainHeader()->height;
@@ -340,7 +366,7 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
TRACE("frame_count %Ld\n", cookie->frame_count); TRACE("frame_count %Ld\n", cookie->frame_count);
TRACE("duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration); TRACE("duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration);
TRACE("compression %s\n", (char *)(&video_format->compression)); TRACE("compression %s\n", (char *)(&codecID));
description.family = B_QUICKTIME_FORMAT_FAMILY; description.family = B_QUICKTIME_FORMAT_FAMILY;
if (stream_header->fourcc_handler == 'ekaf' || stream_header->fourcc_handler == 0) // 'fake' or 0 fourcc => used compression id if (stream_header->fourcc_handler == 'ekaf' || stream_header->fourcc_handler == 0) // 'fake' or 0 fourcc => used compression id