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
This commit is contained in:
David McPaul 2009-04-27 14:06:17 +00:00
parent a0be875ae3
commit 595fb3689a
3 changed files with 74 additions and 28 deletions

View File

@ -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;i<packet->payload_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 */

View File

@ -116,7 +116,6 @@ public:
return true;
}
}
printf("Searched %ld frames last Frame is %ld\n",index.size(),index.end()->frameNo);
}
return false;

View File

@ -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;