Ensure extra data is passed to decoder
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31003 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,7 +31,7 @@
|
|||||||
#include "WavReaderPlugin.h"
|
#include "WavReaderPlugin.h"
|
||||||
#include "RawFormats.h"
|
#include "RawFormats.h"
|
||||||
|
|
||||||
//#define TRACE_WAVE_READER
|
#define TRACE_WAVE_READER
|
||||||
#ifdef TRACE_WAVE_READER
|
#ifdef TRACE_WAVE_READER
|
||||||
#define TRACE printf
|
#define TRACE printf
|
||||||
#else
|
#else
|
||||||
@@ -136,12 +136,13 @@ WavReader::Sniff(int32 *streamCount)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
format_struct format;
|
wave_format_ex format;
|
||||||
wave_format_ex wav_format;
|
|
||||||
format_struct_extensible format_ext;
|
format_struct_extensible format_ext;
|
||||||
mpeg1_wav_format mpeg1_format;
|
mpeg1_wav_format mpeg1_format;
|
||||||
mpeg3_wav_format mpeg3_format;
|
mpeg3_wav_format mpeg3_format;
|
||||||
|
|
||||||
|
uint32 wavFmtSize = sizeof(format_struct) + 2;
|
||||||
|
|
||||||
fact_struct fact;
|
fact_struct fact;
|
||||||
|
|
||||||
// read all chunks and search for "fact", "fmt" (normal or extensible) and "data"
|
// read all chunks and search for "fact", "fmt" (normal or extensible) and "data"
|
||||||
@@ -167,49 +168,56 @@ WavReader::Sniff(int32 *streamCount)
|
|||||||
switch (UINT32(chunk.fourcc)) {
|
switch (UINT32(chunk.fourcc)) {
|
||||||
case FOURCC('f','m','t',' '):
|
case FOURCC('f','m','t',' '):
|
||||||
// So what do we have a std format structure, a wav_format structure or a extended structure
|
// So what do we have a std format structure, a wav_format structure or a extended structure
|
||||||
if (UINT32(chunk.len) >= sizeof(wav_format)) {
|
if (UINT32(chunk.len) >= wavFmtSize) {
|
||||||
// Read both format and wav format
|
// Must be some sort of extended format structure
|
||||||
if (sizeof(format) != Source()->ReadAt(pos, &format, sizeof(format))) {
|
// First Read common data + extra size
|
||||||
|
if (wavFmtSize != Source()->ReadAt(pos, &format, wavFmtSize)) {
|
||||||
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sizeof(wav_format) != Source()->ReadAt(pos, &wav_format, sizeof(wav_format))) {
|
|
||||||
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
// If extra size seems valid then re-read with the extra data included
|
||||||
break;
|
if (UINT16(format.extra_size) > 0 && UINT16(format.extra_size) < 64) {
|
||||||
|
// Read the extra data we need to pass across to the decoder
|
||||||
|
if ((wavFmtSize + format.extra_size) != Source()->ReadAt(pos, &format, wavFmtSize + format.extra_size)) {
|
||||||
|
ERROR("WavReader::Sniff: format extensible chunk reading failed\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foundFmt = true;
|
foundFmt = true;
|
||||||
|
|
||||||
if (UINT16(wav_format.extra_size) == 12) {
|
// Check for structure we recognise and might need values from.
|
||||||
|
if (UINT16(format.extra_size) == 12) {
|
||||||
// MPEG3 WAV FORMAT Structure
|
// MPEG3 WAV FORMAT Structure
|
||||||
if (sizeof(mpeg3_format) != Source()->ReadAt(pos, &mpeg3_format, sizeof(mpeg3_format))) {
|
if (sizeof(mpeg3_format) != Source()->ReadAt(pos, &mpeg3_format, sizeof(mpeg3_format))) {
|
||||||
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
foundMPEG3 = true;
|
foundMPEG3 = true;
|
||||||
}
|
} else if (UINT16(format.extra_size) == 22) {
|
||||||
if (UINT16(wav_format.extra_size) == 22) {
|
if (UINT16(format.format_tag) == 0xfffe) {
|
||||||
// MPEG1 WAV FORMAT Structure
|
// GUID structure
|
||||||
if (sizeof(mpeg1_format) != Source()->ReadAt(pos, &mpeg1_format, sizeof(mpeg1_format))) {
|
if (sizeof(format_ext) != Source()->ReadAt(pos, &format_ext, sizeof(format_ext))) {
|
||||||
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
ERROR("WavReader::Sniff: format extensible chunk reading failed\n");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
foundFmtExt = true;
|
||||||
|
} else {
|
||||||
|
// MPEG1 WAV FORMAT Structure
|
||||||
|
if (sizeof(mpeg1_format) != Source()->ReadAt(pos, &mpeg1_format, sizeof(mpeg1_format))) {
|
||||||
|
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
foundMPEG1 = true;
|
||||||
}
|
}
|
||||||
foundMPEG1 = true;
|
|
||||||
}
|
}
|
||||||
|
} else if (UINT32(chunk.len) >= wavFmtSize - 2) {
|
||||||
} else if (UINT32(chunk.len) >= sizeof(format)) {
|
if ((wavFmtSize - 2) != Source()->ReadAt(pos, &format, wavFmtSize - 2)) {
|
||||||
if (sizeof(format) != Source()->ReadAt(pos, &format, sizeof(format))) {
|
|
||||||
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
ERROR("WavReader::Sniff: format chunk reading failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
format.extra_size = 0;
|
||||||
foundFmt = true;
|
foundFmt = true;
|
||||||
|
|
||||||
if (UINT32(chunk.len) >= sizeof(format_ext) && UINT16(format.format_tag) == 0xfffe) {
|
|
||||||
if (sizeof(format_ext) != Source()->ReadAt(pos, &format_ext, sizeof(format_ext))) {
|
|
||||||
ERROR("WavReader::Sniff: format extensible chunk reading failed\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
foundFmtExt = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FOURCC('f','a','c','t'):
|
case FOURCC('f','a','c','t'):
|
||||||
@@ -260,8 +268,8 @@ WavReader::Sniff(int32 *streamCount)
|
|||||||
TRACE(" avg_bytes_per_sec %ld\n", UINT32(format.avg_bytes_per_sec));
|
TRACE(" avg_bytes_per_sec %ld\n", UINT32(format.avg_bytes_per_sec));
|
||||||
TRACE(" block_align %d\n", UINT16(format.block_align));
|
TRACE(" block_align %d\n", UINT16(format.block_align));
|
||||||
TRACE(" bits_per_sample %d\n", UINT16(format.bits_per_sample));
|
TRACE(" bits_per_sample %d\n", UINT16(format.bits_per_sample));
|
||||||
|
TRACE(" ext_size %d\n", UINT16(format.extra_size));
|
||||||
if (foundFmtExt) {
|
if (foundFmtExt) {
|
||||||
TRACE(" ext_size %d\n", UINT16(format_ext.ext_size));
|
|
||||||
TRACE(" valid_bits_per_sample %d\n", UINT16(format_ext.valid_bits_per_sample));
|
TRACE(" valid_bits_per_sample %d\n", UINT16(format_ext.valid_bits_per_sample));
|
||||||
TRACE(" channel_mask %ld\n", UINT32(format_ext.channel_mask));
|
TRACE(" channel_mask %ld\n", UINT32(format_ext.channel_mask));
|
||||||
TRACE(" guid[0-1] format 0x%04x\n", (format_ext.guid[1] << 8) | format_ext.guid[0]);
|
TRACE(" guid[0-1] format 0x%04x\n", (format_ext.guid[1] << 8) | format_ext.guid[0]);
|
||||||
@@ -292,7 +300,10 @@ WavReader::Sniff(int32 *streamCount)
|
|||||||
fBufferSize = BUFFER_SIZE;
|
fBufferSize = BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fMetaData.extra_size = 0;
|
fMetaData.extra_size = format.extra_size;
|
||||||
|
if (fMetaData.extra_size > 0) {
|
||||||
|
fMetaData.extra_data = format.extra_data;
|
||||||
|
}
|
||||||
fMetaData.channels = UINT16(format.channels);
|
fMetaData.channels = UINT16(format.channels);
|
||||||
fMetaData.samples_per_sec = UINT32(format.samples_per_sec);
|
fMetaData.samples_per_sec = UINT32(format.samples_per_sec);
|
||||||
fMetaData.block_align = UINT16(format.block_align);
|
fMetaData.block_align = UINT16(format.block_align);
|
||||||
@@ -420,9 +431,9 @@ WavReader::AllocateCookie(int32 streamNumber, void **cookie)
|
|||||||
data->format.u.encoded_audio.output.channel_count = fMetaData.channels;
|
data->format.u.encoded_audio.output.channel_count = fMetaData.channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("SetMetaData called with size %ld\n",sizeof(wave_format_ex));
|
printf("SetMetaData called with size %ld\n",sizeof(format_struct) + fMetaData.extra_size + 2);
|
||||||
|
|
||||||
if (data->format.SetMetaData(&fMetaData, sizeof(wave_format_ex)) != B_OK) {
|
if (data->format.SetMetaData(&fMetaData, (sizeof(format_struct) + fMetaData.extra_size + 2)) != B_OK) {
|
||||||
ERROR("WavReader::Failed to SetMetaData\n");
|
ERROR("WavReader::Failed to SetMetaData\n");
|
||||||
delete data;
|
delete data;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -457,7 +468,7 @@ WavReader::GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
|
|||||||
*duration = data->duration;
|
*duration = data->duration;
|
||||||
*format = data->format;
|
*format = data->format;
|
||||||
*infoBuffer = &fMetaData;
|
*infoBuffer = &fMetaData;
|
||||||
*infoSize = sizeof(wave_format_ex);
|
*infoSize = (sizeof(format_struct) + fMetaData.extra_size + 2);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ struct wave_format_ex {
|
|||||||
uint16 block_align;
|
uint16 block_align;
|
||||||
uint16 bits_per_sample;
|
uint16 bits_per_sample;
|
||||||
uint16 extra_size;
|
uint16 extra_size;
|
||||||
|
uint8 extra_data[64]; // allow for 64 bytes of extra data
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mpeg3_wav_format {
|
struct mpeg3_wav_format {
|
||||||
|
|||||||
Reference in New Issue
Block a user