Now plays 2 out of 3 files and that is good yes

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30548 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2009-05-02 04:29:36 +00:00
parent 4328106485
commit 008c3af957
3 changed files with 71 additions and 39 deletions
@@ -156,10 +156,6 @@ ASFFileReader::getAudioFormat(uint32 streamIndex, ASFAudioFormat *format)
format->BitsPerSample = audioHeader->wBitsPerSample;
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;
}
@@ -189,8 +185,8 @@ ASFFileReader::getVideoFormat(uint32 streamIndex, ASFVideoFormat *format)
if (stream->flags & ASF_STREAM_FLAG_EXTENDED) {
format->FrameScale = stream->extended->avg_time_per_frame;
format->FrameRate = 10000000;
printf("num payloads for video %d\n",stream->extended->num_payload_ext);
format->FrameRate = 10000000L;
printf("num avg time per frame for video %Ld\n",stream->extended->avg_time_per_frame);
}
return true;
@@ -221,7 +217,7 @@ ASFFileReader::getStreamDuration(uint32 streamIndex)
}
}
return asf_get_duration(asfFile) / 10;
return asf_get_duration(asfFile) / 10L;
}
uint32
@@ -303,16 +299,16 @@ ASFFileReader::ParseIndex() {
while (asf_get_packet(asfFile, packet) > 0) {
for (int i=0;i<packet->payload_count;i++) {
payload = (asf_payload_t *)(&packet->payloads[i]);
// printf("Payload %d Stream %d Keyframe %d send time %ld pts %ld id %d size %d\n",i+1,payload->stream_number,payload->key_frame, packet->send_time * 1000L, payload->pts * 1000L, payload->media_object_number, payload->datalen);
// printf("Payload %d Stream %d Keyframe %d send time %Ld pts %Ld id %d size %d\n",i+1,payload->stream_number,payload->key_frame, 1000L * bigtime_t(packet->send_time), 1000L * bigtime_t(payload->pts), payload->media_object_number, payload->datalen);
if (payload->stream_number < streams.size()) {
streams[payload->stream_number].AddPayload(payload->media_object_number, payload->key_frame, packet->send_time * 1000, payload->datalen, false);
streams[payload->stream_number].AddPayload(payload->media_object_number, payload->key_frame, 1000L * payload->pts, payload->datalen, false);
}
}
}
for (uint32 i=0;i<streams.size();i++) {
streams[i].AddPayload(0, false, 0, 0, true);
streams[i].setDuration((packet->send_time + packet->duration) * 1000);
streams[i].setDuration(1000L * (packet->send_time + packet->duration));
}
if (asf_seek_to_msec(asfFile,0) < 0) {
@@ -326,7 +322,9 @@ ASFFileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo,
{
// Ok, Need to join payloads together that have the same payload->media_object_number
asf_payload_t *payload;
int64_t seekResult;
int packetSize;
IndexEntry indexEntry = GetIndex(streamIndex, pFrameNo);
if (indexEntry.noPayloads == 0) {
@@ -334,16 +332,42 @@ ASFFileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo,
return false;
}
while (packet->send_time * 1000 < indexEntry.pts) {
if (asf_get_packet(asfFile, packet) < 0) {
return false;
}
}
// printf("Stream %ld need pts %Ld, packet start %Ld packet end %Ld\n",streamIndex,indexEntry.pts,1000LL * packet->send_time,1000LL * (packet->send_time + packet->duration));
if (packet->send_time * 1000 > indexEntry.pts) {
// seek back to pts
printf("seeking back to %Ld status %Ld\n",indexEntry.pts, asf_seek_to_msec(asfFile, indexEntry.pts/1000));
if (asf_get_packet(asfFile, packet) < 0) {
if (1000LL * packet->send_time > indexEntry.pts || 1000LL * (packet->send_time + packet->duration) < indexEntry.pts) {
seekResult = asf_seek_to_msec(asfFile, indexEntry.pts/1000);
if (seekResult >= 0) {
// printf("Stream %ld seeked to %Ld got %Ld\n",streamIndex,indexEntry.pts, 1000L * seekResult);
packetSize = asf_get_packet(asfFile, packet);
if (packetSize <= 0) {
printf("Failed to Get Packet after seek result (%d)\n",packetSize);
return false;
}
} else if (seekResult == ASF_ERROR_SEEKABLE) {
// Stream not seekeable. Is what we want forward in the stream, if so seek using Get Packet
if (1000LL * (packet->send_time + packet->duration) < indexEntry.pts) {
while (1000LL * (packet->send_time + packet->duration) < indexEntry.pts) {
packetSize = asf_get_packet(asfFile, packet);
if (packetSize <= 0) {
printf("Failed to Seek using Get Packet result (%d)\n",packetSize);
return false;
}
// printf("Stream %ld searching forward for pts %Ld, got packet start %Ld packet end %Ld\n",streamIndex,indexEntry.pts,1000LL * packet->send_time,1000LL * (packet->send_time + packet->duration));
}
} else {
// seek to 0 and read forward, going to be a killer on performance
seekResult = asf_seek_to_msec(asfFile, 0);
while (1000LL * (packet->send_time + packet->duration) < indexEntry.pts) {
packetSize = asf_get_packet(asfFile, packet);
if (packetSize <= 0) {
printf("Failed to Seek using Get Packet result (%d)\n",packetSize);
return false;
}
// printf("Stream %ld searching forward from 0 for pts %Ld, got packet start %Ld packet end %Ld\n",streamIndex,indexEntry.pts,1000LL * packet->send_time,1000LL * (packet->send_time + packet->duration));
}
}
} else {
printf("Seek failed\n");
return false;
}
}
@@ -373,7 +397,8 @@ ASFFileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo,
}
// combine packets into a single buffer
while ((asf_get_packet(asfFile, packet) > 0) && (expectedPayloads > 0)) {
packetSize = asf_get_packet(asfFile, packet);
while ((packetSize > 0) && (expectedPayloads > 0)) {
for (int i=0;i<packet->payload_count;i++) {
payload = (asf_payload_t *)(&packet->payloads[i]);
// find the first payload matching the id we want and then
@@ -388,6 +413,13 @@ ASFFileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo,
}
}
}
packetSize = asf_get_packet(asfFile, packet);
}
if (packetSize == ASF_ERROR_EOF) {
printf("Unexpected EOF file truncated?\n");
} else {
printf("EOF? %ld,%d\n",expectedPayloads, packetSize);
}
return false;
@@ -134,13 +134,17 @@ StreamEntry::AddPayload(uint32 id, bool keyFrame, bigtime_t pts, uint32 dataSize
{
if (isLast) {
maxPTS = indexEntry.pts;
index.push_back(indexEntry);
printf("Stream Index Loaded for Stream %d Max Index %ld Max PTS %Ld\n",streamIndex, frameCount, maxPTS);
if (frameCount > 0) {
index.push_back(indexEntry);
// printf("Stream %d added Index %ld PTS %Ld payloads %d\n",streamIndex, indexEntry.frameNo, indexEntry.pts, indexEntry.noPayloads);
printf("Stream Index Loaded for Stream %d Max Frame %ld Max PTS %Ld size %ld\n",streamIndex, frameCount-1, maxPTS, index.size());
}
} else {
if (id > lastID) {
if (lastID != 0) {
if (id != lastID) {
if (frameCount != 0) {
// add indexEntry to Index
index.push_back(indexEntry);
// printf("Stream %d added Index %ld PTS %Ld payloads %d\n",streamIndex, indexEntry.frameNo, indexEntry.pts, indexEntry.noPayloads);
}
lastID = id;
indexEntry.Clear();
@@ -190,22 +190,18 @@ asfReader::AllocateCookie(int32 streamNumber, void **_cookie)
TRACE("frame_count %Ld\n", cookie->frame_count);
TRACE("duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration);
TRACE("calculated fps=%ld\n", cookie->frame_count * 1000000LL / cookie->duration);
// asf does not have a frame rate! The extended descriptor defines an average time per frame which is generally useless.
cookie->frames_per_sec_rate = cookie->frame_count;
cookie->frames_per_sec_scale = cookie->duration / 1000000LL;
TRACE("frames_per_sec_rate %ld, frames_per_sec_scale %ld (using both)\n", cookie->frames_per_sec_rate, cookie->frames_per_sec_scale);
// if (videoFormat.FrameScale && videoFormat.FrameRate) {
// cookie->frames_per_sec_rate = videoFormat.FrameRate;
// cookie->frames_per_sec_scale = videoFormat.FrameScale;
// TRACE("frames_per_sec_rate %ld, frames_per_sec_scale %ld (using both)\n", cookie->frames_per_sec_rate, cookie->frames_per_sec_scale);
// } else {
// cookie->frames_per_sec_rate = 25;
// cookie->frames_per_sec_scale = 1;
// TRACE("frames_per_sec_rate %ld, frames_per_sec_scale %ld (using fallback)\n", cookie->frames_per_sec_rate, cookie->frames_per_sec_scale);
// }
if (videoFormat.FrameScale && videoFormat.FrameRate) {
cookie->frames_per_sec_rate = videoFormat.FrameRate;
cookie->frames_per_sec_scale = videoFormat.FrameScale;
TRACE("frames_per_sec_rate %ld, frames_per_sec_scale %ld (using average time per frame)\n", cookie->frames_per_sec_rate, cookie->frames_per_sec_scale);
} else {
cookie->frames_per_sec_rate = cookie->frame_count;
cookie->frames_per_sec_scale = cookie->duration / 1000000LL;
TRACE("frames_per_sec_rate %ld, frames_per_sec_scale %ld (duration over frame count)\n", cookie->frames_per_sec_rate, cookie->frames_per_sec_scale);
}
description.family = B_AVI_FORMAT_FAMILY;
description.u.avi.codec = videoFormat.Compression;