diff --git a/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp b/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp index f197a33fe2..9a20e1608b 100644 --- a/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp +++ b/src/add-ons/media/plugins/asf_reader/ASFFileReader.cpp @@ -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;ipayload_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;isend_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;ipayload_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; diff --git a/src/add-ons/media/plugins/asf_reader/ASFIndex.cpp b/src/add-ons/media/plugins/asf_reader/ASFIndex.cpp index e2f222273f..590d0b634e 100644 --- a/src/add-ons/media/plugins/asf_reader/ASFIndex.cpp +++ b/src/add-ons/media/plugins/asf_reader/ASFIndex.cpp @@ -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(); 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 2c95dd9bf0..bfa0483a94 100644 --- a/src/add-ons/media/plugins/asf_reader/asf_reader.cpp +++ b/src/add-ons/media/plugins/asf_reader/asf_reader.cpp @@ -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;