diff --git a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp index 4a29617244..96931a158c 100644 --- a/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp +++ b/src/apps/mediaplayer/supplier/MediaTrackVideoSupplier.cpp @@ -92,6 +92,19 @@ MediaTrackVideoSupplier::ReadFrame(void* buffer, bigtime_t* performanceTime, if (!buffer) return B_BAD_VALUE; + // Hack for single frame video (cover art). Media player really wants a + // video track and will not seek in the middle of a video frame. So we + // pretend to be a 25fps stream and keep rendering the same frame over + // and over again. + if (fVideoTrack->CountFrames() < 2) { + static int already = false; + if (already) { + wasCached = true; + return B_OK; + } + already = true; + } + status_t ret = B_OK; if (format.display.format != fFormat.u.raw_video.display.format @@ -112,11 +125,9 @@ MediaTrackVideoSupplier::ReadFrame(void* buffer, bigtime_t* performanceTime, media_header mediaHeader; ret = fVideoTrack->ReadFrames(buffer, &frameCount, &mediaHeader); - if (ret < B_OK) { - if (ret != B_LAST_BUFFER_ERROR) { - fprintf(stderr, "MediaTrackVideoSupplier::ReadFrame() - " - "error while reading frame of track: %s\n", strerror(ret)); - } + if (ret < B_OK && ret != B_LAST_BUFFER_ERROR) { + fprintf(stderr, "MediaTrackVideoSupplier::ReadFrame() - " + "error while reading frame of track: %s\n", strerror(ret)); } else fPerformanceTime = mediaHeader.start_time; @@ -137,6 +148,8 @@ delete bitmap; } #endif // DEBUG_DECODED_FRAME + if (ret == B_LAST_BUFFER_ERROR && fVideoTrack->CountFrames() < 2) + return B_OK; return ret; } @@ -147,6 +160,9 @@ MediaTrackVideoSupplier::FindKeyFrameForFrame(int64* frame) if (!fVideoTrack) return B_NO_INIT; + if (fVideoTrack->CountFrames() < 2) + return B_OK; + //int64 wantedFrame = *frame; status_t ret = fVideoTrack->FindKeyFrameForFrame(frame, B_MEDIA_SEEK_CLOSEST_BACKWARD); @@ -161,7 +177,10 @@ MediaTrackVideoSupplier::SeekToTime(bigtime_t* performanceTime) if (!fVideoTrack) return B_NO_INIT; -bigtime_t _performanceTime = *performanceTime; + if (fVideoTrack->CountFrames() < 2) + return B_OK; + + bigtime_t _performanceTime = *performanceTime; status_t ret = fVideoTrack->FindKeyFrameForTime(performanceTime, B_MEDIA_SEEK_CLOSEST_BACKWARD); if (ret < B_OK) @@ -187,6 +206,9 @@ MediaTrackVideoSupplier::SeekToFrame(int64* frame) if (!fVideoTrack) return B_NO_INIT; + if (fVideoTrack->CountFrames() < 2) + return B_OK; + int64 wantFrame = *frame; if (wantFrame == fCurrentFrame)