MediaPlayer: improve handling of cover art.

Fixes #16531.
This commit is contained in:
Adrien Destugues 2020-09-20 14:44:42 +02:00
parent 5dbf9531ea
commit f6d0ea5cad

View File

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