fix issue 1779 - crash on mov with audio

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25444 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2008-05-11 02:07:01 +00:00
parent 29ede77343
commit 4a3e5e36ca
3 changed files with 29 additions and 49 deletions
@@ -439,7 +439,7 @@ const mov_main_header *MOVFileReader::MovMainHeader()
return &theMainHeader; return &theMainHeader;
} }
const AudioMetaData *MOVFileReader::AudioFormat(uint32 stream_index, size_t *size) const AudioMetaData *MOVFileReader::AudioFormat(uint32 stream_index)
{ {
if (IsAudio(stream_index)) { if (IsAudio(stream_index)) {
@@ -113,7 +113,7 @@ public:
bool GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe); bool GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe);
// Return all Audio Meta Data // Return all Audio Meta Data
const AudioMetaData *AudioFormat(uint32 stream_index, size_t *size = 0); const AudioMetaData *AudioFormat(uint32 stream_index);
// Return all Video Meta Data // Return all Video Meta Data
const VideoMetaData *VideoFormat(uint32 stream_index); const VideoMetaData *VideoFormat(uint32 stream_index);
@@ -252,6 +252,7 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
format->u.raw_audio.buffer_size = stream_header->suggested_buffer_size; format->u.raw_audio.buffer_size = stream_header->suggested_buffer_size;
} else { } else {
description.family = B_QUICKTIME_FORMAT_FAMILY; description.family = B_QUICKTIME_FORMAT_FAMILY;
description.u.quicktime.codec = audio_format->compression; description.u.quicktime.codec = audio_format->compression;
if (B_OK != formats.GetFormatFor(description, format)) { if (B_OK != formats.GetFormatFor(description, format)) {
@@ -278,6 +279,8 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
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;
break; break;
case AUDIO_IMA4:
default: default:
TRACE("OTHER\n"); TRACE("OTHER\n");
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;
@@ -287,49 +290,16 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
} }
} }
/* if (audio_format->compression == 0x0001) {
// a raw PCM format
description.family = B_BEOS_FORMAT_FAMILY;
description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO;
if (B_OK != formats.GetFormatFor(description, format))
format->type = B_MEDIA_RAW_AUDIO;
format->u.raw_audio.frame_rate = audio_format->SampleRate;
format->u.raw_audio.channel_count = audio_format->NoOfChannels;
if (audio_format->bits_per_sample <= 8)
format->u.raw_audio.format = B_AUDIO_FORMAT_UINT8;
else if (audio_format->bits_per_sample <= 16)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT16;
else if (audio_format->bits_per_sample <= 24)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT24;
else if (audio_format->bits_per_sample <= 32)
format->u.raw_audio.format = B_AUDIO_FORMAT_INT32;
else {
ERROR("movReader::AllocateCookie: unhandled bits per sample %d\n", audio_format->bits_per_sample);
return B_ERROR;
}
format->u.raw_audio.format |= B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE;
format->u.raw_audio.byte_order = B_MEDIA_BIG_ENDIAN;
format->u.raw_audio.buffer_size = stream_header->suggested_buffer_size;
} else {
// some encoded format
description.family = B_WAV_FORMAT_FAMILY;
description.u.wav.codec = audio_format->compression;
if (B_OK != formats.GetFormatFor(description, format))
format->type = B_MEDIA_ENCODED_AUDIO;
format->u.encoded_audio.bit_rate = 8 * audio_format->PacketSize;
TRACE("bit_rate %.3f\n", format->u.encoded_audio.bit_rate);
format->u.encoded_audio.output.frame_rate = audio_format->SampleRate;
format->u.encoded_audio.output.channel_count = audio_format->NoOfChannels;
}
*/
// this doesn't seem to work (it's not even a fourcc) // this doesn't seem to work (it's not even a fourcc)
format->user_data_type = B_CODEC_TYPE_INFO; format->user_data_type = B_CODEC_TYPE_INFO;
*(uint32 *)format->user_data = audio_format->compression; format->user_data[4] = 0; *(uint32 *)format->user_data = audio_format->compression; format->user_data[4] = 0;
// put the Audio struct, including extra data, into the format meta data. // Some codecs have additional setup data that they need, put it in metadata
size_t size; size_t size = audio_format->VOLSize;
const void *data = theFileReader->AudioFormat(cookie->stream, &size); const void *data = audio_format->theVOL;
format->SetMetaData(data, size); if (size > 0) {
format->SetMetaData(data, size);
}
#ifdef TRACE_MOV_READER #ifdef TRACE_MOV_READER
uint8 *p = 18 + (uint8 *)data; uint8 *p = 18 + (uint8 *)data;
@@ -382,6 +352,7 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
format->user_data_type = B_CODEC_TYPE_INFO; format->user_data_type = B_CODEC_TYPE_INFO;
*(uint32 *)format->user_data = description.u.quicktime.codec; format->user_data[4] = 0; *(uint32 *)format->user_data = description.u.quicktime.codec; format->user_data[4] = 0;
format->u.encoded_video.max_bit_rate = 8 * theFileReader->MovMainHeader()->max_bytes_per_sec; format->u.encoded_video.max_bit_rate = 8 * theFileReader->MovMainHeader()->max_bytes_per_sec;
format->u.encoded_video.avg_bit_rate = format->u.encoded_video.max_bit_rate / 2; // XXX fix this format->u.encoded_video.avg_bit_rate = format->u.encoded_video.max_bit_rate / 2; // XXX fix this
format->u.encoded_video.output.field_rate = cookie->frames_per_sec_rate / (float)cookie->frames_per_sec_scale; format->u.encoded_video.output.field_rate = cookie->frames_per_sec_rate / (float)cookie->frames_per_sec_scale;
@@ -391,7 +362,6 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT; format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
format->u.encoded_video.output.pixel_width_aspect = 1; format->u.encoded_video.output.pixel_width_aspect = 1;
format->u.encoded_video.output.pixel_height_aspect = 1; format->u.encoded_video.output.pixel_height_aspect = 1;
// format->u.encoded_video.output.display.format = 0;
format->u.encoded_video.output.display.line_width = theFileReader->MovMainHeader()->width; format->u.encoded_video.output.display.line_width = theFileReader->MovMainHeader()->width;
format->u.encoded_video.output.display.line_count = cookie->line_count; format->u.encoded_video.output.display.line_count = cookie->line_count;
format->u.encoded_video.output.display.bytes_per_row = 0; // format->u.encoded_video.output.display.line_width * 4; format->u.encoded_video.output.display.bytes_per_row = 0; // format->u.encoded_video.output.display.line_width * 4;
@@ -402,11 +372,11 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
TRACE("max_bit_rate %.3f\n", format->u.encoded_video.max_bit_rate); TRACE("max_bit_rate %.3f\n", format->u.encoded_video.max_bit_rate);
TRACE("field_rate %.3f\n", format->u.encoded_video.output.field_rate); TRACE("field_rate %.3f\n", format->u.encoded_video.output.field_rate);
// Set the VOL // Some decoders need additional metadata passed via a special Atom
if (video_format->VOLSize > 0) { size_t size = video_format->VOLSize;
TRACE("VOL SIZE %ld\n", video_format->VOLSize); const void *data = video_format->theVOL;
size_t size = video_format->VOLSize; if (size > 0) {
const void *data = video_format->theVOL; TRACE("VOL SIZE %ld\n", size);
format->SetMetaData(data, size); format->SetMetaData(data, size);
} }
@@ -439,8 +409,18 @@ movReader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration,
*frameCount = cookie->frame_count; *frameCount = cookie->frame_count;
*duration = cookie->duration; *duration = cookie->duration;
*format = cookie->format; *format = cookie->format;
*infoBuffer = 0;
*infoSize = 0; // Copy metadata to infoBuffer
if (theFileReader->IsVideo(cookie->stream)) {
const VideoMetaData *video_format = theFileReader->VideoFormat(cookie->stream);
*infoBuffer = video_format->theVOL;
*infoSize = video_format->VOLSize;
} else {
const AudioMetaData *audio_format = theFileReader->AudioFormat(cookie->stream);
*infoBuffer = audio_format->theVOL;
*infoSize = audio_format->VOLSize;
}
return B_OK; return B_OK;
} }