From ab38d6b5ee40475884befd0033f70dd40b996a57 Mon Sep 17 00:00:00 2001 From: David McPaul Date: Sun, 11 May 2008 13:09:54 +0000 Subject: [PATCH] Hardcode IMA4 sound description git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25448 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../mov_reader/libMOV/MOVFileReader.cpp | 17 +++++- .../plugins/mov_reader/libMOV/MOVParser.cpp | 19 ++++-- .../plugins/mov_reader/libMOV/QTStructs.h | 8 ++- .../media/plugins/mov_reader/mov_reader.cpp | 58 ++++++++++++++----- 4 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp index f2c27c0e0e..72d6bca455 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVFileReader.cpp @@ -457,12 +457,25 @@ const AudioMetaData *MOVFileReader::AudioFormat(uint32 stream_index) // Hmm 16bit format 32 bit FourCC. theAudio.compression = aSoundDescription.basefields.DataFormat; -// theAudio.compression = aSoundDescription.desc.CompressionID; theAudio.NoOfChannels = aSoundDescription.desc.NoOfChannels; theAudio.SampleSize = aSoundDescription.desc.SampleSize; 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.VOLSize = aSoundDescription.VOLSize; diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp index 831b4be42c..9c525bcea7 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp +++ b/src/add-ons/media/plugins/mov_reader/libMOV/MOVParser.cpp @@ -816,7 +816,8 @@ void STSDAtom::ReadSoundDescription() Read(&aSoundDescriptionV1->desc.PacketSize); 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->bytesPerPacket)); Read(&(aSoundDescriptionV1->bytesPerFrame)); @@ -824,14 +825,20 @@ void STSDAtom::ReadSoundDescription() } else { // Calculate? - aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8; - if (aSoundDescriptionV1->basefields.DataFormat == 'ima4') { - aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * 64 / 34; + if (aSoundDescriptionV1->basefields.DataFormat == AUDIO_IMA4) { + printf("Calculating IMA4 Sound Description\n"); + aSoundDescriptionV1->samplesPerPacket = 64; + aSoundDescriptionV1->bytesPerFrame = aSoundDescriptionV1->desc.NoOfChannels * 34; + + aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8; + aSoundDescriptionV1->bytesPerPacket = 64 * aSoundDescriptionV1->bytesPerFrame; } else { + printf("Calculating Sound Description\n"); + aSoundDescriptionV1->bytesPerSample = aSoundDescriptionV1->desc.SampleSize / 8; 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 diff --git a/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h b/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h index 589e3b9915..56b0eea228 100644 --- a/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h +++ b/src/add-ons/media/plugins/mov_reader/libMOV/QTStructs.h @@ -105,11 +105,13 @@ struct VideoMetaData struct AudioMetaData { - uint32 compression; // compression used + uint32 compression; // compression type used uint16 NoOfChannels; // 1 = mono, 2 = stereo uint16 SampleSize; // bits per sample - float SampleRate; // Samples per second (OR Frames per second) - uint32 PacketSize; // (Sample Rate * NoOfchannels * SampleSize)/8 = bytes per second + float SampleRate; // Samples 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; size_t VOLSize; }; diff --git a/src/add-ons/media/plugins/mov_reader/mov_reader.cpp b/src/add-ons/media/plugins/mov_reader/mov_reader.cpp index 6835af1975..82467f99d9 100644 --- a/src/add-ons/media/plugins/mov_reader/mov_reader.cpp +++ b/src/add-ons/media/plugins/mov_reader/mov_reader.cpp @@ -34,7 +34,7 @@ #include "mov_reader.h" -//#define TRACE_MOV_READER +#define TRACE_MOV_READER #ifdef TRACE_MOV_READER #define TRACE printf #else @@ -136,6 +136,8 @@ movReader::GetFileFormatInfo(media_file_format *mff) status_t movReader::AllocateCookie(int32 streamNumber, void **_cookie) { + uint32 codecID; + mov_cookie *cookie = new mov_cookie; *_cookie = cookie; @@ -172,6 +174,8 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) return B_ERROR; } + codecID = B_BENDIAN_TO_HOST_INT32(audio_format->compression); + cookie->frame_count = theFileReader->getAudioFrameCount(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_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); - } else if (audio_format->PacketSize) { - cookie->bytes_per_sec_rate = audio_format->PacketSize; + } else if (audio_format->BufferSize) { + cookie->bytes_per_sec_rate = audio_format->BufferSize; 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; 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 { @@ -259,6 +263,26 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) 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) { case AUDIO_MS_PCM02: TRACE("MS PCM02\n"); @@ -280,9 +304,13 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels; break; 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: - 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.output.frame_rate = cookie->frames_per_sec_rate / cookie->frames_per_sec_scale; 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) - format->user_data_type = B_CODEC_TYPE_INFO; - *(uint32 *)format->user_data = audio_format->compression; format->user_data[4] = 0; + TRACE("Audio NoOfChannels %d, SampleSize %d, SampleRate %f, FrameSize %ld\n",audio_format->NoOfChannels, audio_format->SampleSize, audio_format->SampleRate, audio_format->FrameSize); + + 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 size_t size = audio_format->VOLSize; const void *data = audio_format->theVOL; if (size > 0) { + TRACE("VOL SIZE %ld\n", 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; } @@ -318,6 +342,8 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie) return B_ERROR; } + codecID = B_BENDIAN_TO_HOST_INT32(video_format->compression); + cookie->audio = false; 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("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; if (stream_header->fourcc_handler == 'ekaf' || stream_header->fourcc_handler == 0) // 'fake' or 0 fourcc => used compression id