From 595fb3689a5076530b6d4d95c628c6b99b1e37f7 Mon Sep 17 00:00:00 2001 From: David McPaul Date: Mon, 27 Apr 2009 14:06:17 +0000 Subject: [PATCH] Now plays sound but lots of work still needed git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30461 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../plugins/asf_reader/ASFFileReader.cpp | 69 ++++++++++++++++--- .../media/plugins/asf_reader/ASFFileReader.h | 1 - .../media/plugins/asf_reader/asf_reader.cpp | 32 ++++----- 3 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp b/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp index 0a12938b97..33ca42752f 100644 --- a/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp +++ b/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp @@ -149,6 +149,10 @@ ASFFileReader::getAudioFormat(uint32 streamIndex, ASFAudioFormat *format) format->extraDataSize = audioHeader->cbSize; format->extraData = audioHeader->data; + if (stream->flags & ASF_STREAM_FLAG_EXTENDED) { + printf("num payloads for audio %d\n",stream->extended->num_payload_ext); + } + return true; } } @@ -178,7 +182,7 @@ ASFFileReader::getVideoFormat(uint32 streamIndex, ASFVideoFormat *format) if (stream->flags & ASF_STREAM_FLAG_EXTENDED) { format->FrameScale = stream->extended->avg_time_per_frame; format->FrameRate = 10000000; - format->FrameCount = stream->extended->max_obj_size; + printf("num payloads for video %d\n",stream->extended->num_payload_ext); } return true; @@ -192,34 +196,61 @@ ASFFileReader::getVideoFormat(uint32 streamIndex, ASFVideoFormat *format) bigtime_t ASFFileReader::getVideoDuration(uint32 streamIndex) { - return asf_get_duration(asfFile); + asf_stream_t *stream; + + stream = asf_get_stream(asfFile, streamIndex); + + if (stream) { + if (stream->flags & ASF_STREAM_FLAG_EXTENDED) { + printf("VIDEO end time %Ld, start time %Ld\n",stream->extended->end_time, stream->extended->start_time); + if (stream->extended->end_time - stream->extended->start_time > 0) { + return stream->extended->end_time - stream->extended->start_time; + } + } + } + + return asf_get_duration(asfFile) / 10; } bigtime_t ASFFileReader::getAudioDuration(uint32 streamIndex) { - return asf_get_duration(asfFile); + asf_stream_t *stream; + + stream = asf_get_stream(asfFile, streamIndex); + + if (stream) { + if (stream->flags & ASF_STREAM_FLAG_EXTENDED) { + printf("AUDIO end time %Ld, start time %Ld\n",stream->extended->end_time, stream->extended->start_time); + if (stream->extended->end_time - stream->extended->start_time > 0) { + return stream->extended->end_time - stream->extended->start_time; + } + } + } + + return asf_get_duration(asfFile) / 10; // convert from 100 nanosecond units to microseconds } bigtime_t ASFFileReader::getMaxDuration() { - return asf_get_duration(asfFile); + return asf_get_duration(asfFile) / 10; } +// Not really frame count, really total data packets uint32 ASFFileReader::getFrameCount(uint32 streamIndex) -{ +{ return asf_get_data_packets(asfFile); } uint32 ASFFileReader::getAudioChunkCount(uint32 streamIndex) { - return 0; + return asf_get_data_packets(asfFile); } bool @@ -277,14 +308,17 @@ bool ASFFileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo, char **buffer, uint32 *size, bool *keyframe, bigtime_t *pts) { + // Ok, Need to join payloads together that have the same payload->pts + // packet->send_time seems to be a better presentation time stamp than pts though + asf_payload_t *payload; while (!HasIndex(streamIndex, pFrameNo+1) && asf_get_packet(asfFile, packet) > 0) { for (int i=0;ipayload_count;i++) { - payload = (asf_payload_t *)(packet->payloads); + payload = (asf_payload_t *)(&packet->payloads[i]); printf("Payload %d ",i+1); - printf("Stream %d Keyframe %d pts %d frame %d, size %d\n",payload[i].stream_number,payload[i].key_frame, payload[i].pts, payload[i].media_object_number, payload[i].datalen); - AddIndex(payload[i].stream_number, payload[i].media_object_number, payload[i].key_frame, payload[i].pts, payload[i].data, payload[i].datalen); + printf("Stream %d Keyframe %d pts %d frame %d, size %d\n",payload->stream_number,payload->key_frame, payload->pts * 1000, payload->media_object_number, payload->datalen); + AddIndex(payload->stream_number, payload->media_object_number, payload->key_frame, packet->send_time * 1000, payload->data, payload->datalen); } } @@ -305,7 +339,22 @@ ASFFileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo, bool ASFFileReader::IsSupported(BPositionIO *source) { - return true; + // Read first 4 bytes and if they match 30 26 b2 75 we have a asf file + uint8 header[4]; + bool supported = false; + + off_t position = source->Position(); + + if (source->Read(&header[0],4) == 4) { + supported = header[0] == 0x30 && + header[1] == 0x26 && + header[2] == 0xb2 && + header[3] == 0x75; + } + + source->Seek(position,SEEK_SET); + + return supported; } /* static */ diff --git a/src/add-ons/media/plugins/asf_reader/ASFFileReader.h b/src/add-ons/media/plugins/asf_reader/ASFFileReader.h index 76566c8bdf..e338e34a81 100644 --- a/src/add-ons/media/plugins/asf_reader/ASFFileReader.h +++ b/src/add-ons/media/plugins/asf_reader/ASFFileReader.h @@ -116,7 +116,6 @@ public: return true; } } - printf("Searched %ld frames last Frame is %ld\n",index.size(),index.end()->frameNo); } return false; diff --git a/src/add-ons/media/plugins/asf_reader/asf_reader.cpp b/src/add-ons/media/plugins/asf_reader/asf_reader.cpp index 7344ac263a..c15acbb9a6 100644 --- a/src/add-ons/media/plugins/asf_reader/asf_reader.cpp +++ b/src/add-ons/media/plugins/asf_reader/asf_reader.cpp @@ -186,11 +186,7 @@ asfReader::AllocateCookie(int32 streamNumber, void **_cookie) cookie->frame_size = 1; cookie->duration = theFileReader->getVideoDuration(streamNumber); - if (videoFormat.FrameCount > 0) { - cookie->frame_count = videoFormat.FrameCount; - } else { - cookie->frame_count = theFileReader->getFrameCount(streamNumber); - } + cookie->frame_count = theFileReader->getFrameCount(streamNumber); TRACE("frame_count %Ld\n", cookie->frame_count); TRACE("duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration); @@ -294,17 +290,19 @@ asfReader::AllocateCookie(int32 streamNumber, void **_cookie) TRACE("BlockAlign %d\n",audioFormat.BlockAlign); TRACE("Bits %d\n",audioFormat.BitsPerSample); + uint32 sampleSize = (audioFormat.NoChannels * audioFormat.BitsPerSample / 8); + cookie->audio = true; cookie->duration = theFileReader->getAudioDuration(streamNumber); - cookie->frame_count = theFileReader->getFrameCount(streamNumber); + cookie->frame_count = (cookie->duration * audioFormat.SamplesPerSec) / sampleSize / 1000000LL; cookie->frame_pos = 0; cookie->frames_per_sec_rate = audioFormat.SamplesPerSec; cookie->frames_per_sec_scale = 1; - - TRACE("audio frame_count %Ld, duration %.6f\n", cookie->frame_count, cookie->duration / 1E6); - cookie->bytes_per_sec_rate = audioFormat.AvgBytesPerSec; -// cookie->sample_size = audioFormat.BlockAlign == 0 ? audioFormat.BitsPerSample / 8 * audioFormat.NoChannels : audioFormat.BlockAlign; + cookie->bytes_per_sec_scale = 1; + + TRACE("Chunk Count %ld\n", theFileReader->getAudioChunkCount(streamNumber)); + TRACE("audio frame_count %Ld, duration %.6f\n", cookie->frame_count, cookie->duration / 1E6 ); if (audioFormat.Compression == 0x0001) { // a raw PCM format @@ -329,7 +327,9 @@ asfReader::AllocateCookie(int32 streamNumber, void **_cookie) format->u.raw_audio.format |= B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE; format->u.raw_audio.byte_order = B_MEDIA_LITTLE_ENDIAN; format->u.raw_audio.buffer_size = audioFormat.BlockAlign; -// cookie->frame_size = cookie->sample_size; + } else if (audioFormat.Compression == 0xa) { + // Windows Media Speech + return B_ERROR; } else { // some encoded format description.family = B_WAV_FORMAT_FAMILY; @@ -494,15 +494,13 @@ asfReader::GetNextChunk(void *_cookie, const void **chunkBuffer, uint32 size; bool keyframe; - if (theFileReader->GetNextChunkInfo(cookie->stream, (cookie->frame_pos / cookie->frame_size), &(cookie->buffer), &size, &keyframe, &mediaHeader->start_time) == false) { - TRACE("LAST BUFFER : %d (%ld)\n",cookie->stream, cookie->frame_pos); + if (theFileReader->GetNextChunkInfo(cookie->stream, cookie->frame_pos, &(cookie->buffer), &size, &keyframe, &mediaHeader->start_time) == false) { + TRACE("LAST BUFFER : Stream %d (%ld)\n",cookie->stream, cookie->frame_pos); *chunkSize = 0; *chunkBuffer = NULL; return B_LAST_BUFFER_ERROR; } -// mediaHeader->start_time = bigtime_t(double(cookie->frame_pos) * 1000000.0 * double(cookie->frames_per_sec_scale)) / cookie->frames_per_sec_rate; - if (cookie->audio) { TRACE("Audio"); mediaHeader->type = B_MEDIA_ENCODED_AUDIO; @@ -516,9 +514,9 @@ asfReader::GetNextChunk(void *_cookie, const void **chunkBuffer, mediaHeader->u.encoded_video.field_number = 0; mediaHeader->u.encoded_video.field_sequence = cookie->frame_pos; } - TRACE(" stream %d: frame %ld start time %.6f Size %ld key frame %s\n",cookie->stream, (cookie->frame_pos / cookie->frame_size), mediaHeader->start_time / 1000000.0, size, keyframe ? "true" : "false"); + TRACE(" stream %d: frame %ld start time %.6f Size %ld key frame %s\n",cookie->stream, cookie->frame_pos, mediaHeader->start_time / 1000000.0, size, keyframe ? "true" : "false"); - cookie->frame_pos += cookie->frame_size; + cookie->frame_pos ++; *chunkBuffer = cookie->buffer; *chunkSize = size;