FFMPEG Plugin: Fix video start_time handling
- I misinterpreted the semantics of reordered_opaque. I thought it would establish the correct relationship between the start_time returned by GetNextChunk() and the next video frame successfully decoded. But for this to work reordered_opaque expects to be filled with presentation time stamps. A series of presentation time stamps may be jumping back in time due to the presence of B-frames. The decoded frame presentation time stamps series would then be ordered in a monotonically increased way. But actually GetNextChunk() always returns monotonically increasing start times. Mapping this behaviour to FFMPEG's expectations means labeling those start times as decoding time stamps (dts). Though for those start times to be related to the correct decoded video frames you have to assign the start time with the AVPacket containing the data to be decoded. - This commit finally makes DVB video playback working for me with the TV app. Though no audio yet. - The documentation was updated accordingly.
This commit is contained in:
parent
b77f1724a2
commit
ed9de7dfca
@ -741,7 +741,7 @@ AVCodecDecoder::_DecodeNextVideoFrame()
|
||||
|
||||
while (true) {
|
||||
status_t loadingChunkStatus
|
||||
= _LoadNextVideoChunkIfNeededAndUpdateStartTime();
|
||||
= _LoadNextVideoChunkIfNeededAndAssignStartTime();
|
||||
|
||||
if (loadingChunkStatus == B_LAST_BUFFER_ERROR)
|
||||
return _FlushOneVideoFrameFromDecoderBuffer();
|
||||
@ -822,21 +822,21 @@ AVCodecDecoder::_DecodeNextVideoFrame()
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Loads the next video chunk into fVideoChunkBuffer and assigns it to
|
||||
fTempPacket accordingly only if fTempPacket is empty. Updates fContext
|
||||
with the start time of the new data chunk.
|
||||
/*! \brief Loads the next video chunk into fVideoChunkBuffer and assigns it
|
||||
(including the start time) to fTempPacket accordingly only if
|
||||
fTempPacket is empty.
|
||||
|
||||
\returns B_OK
|
||||
1. meaning: Next video chunk is loaded and fContext is updated.
|
||||
2. meaning: No need to load and update anything. Proceed as usual.
|
||||
1. meaning: Next video chunk is loaded.
|
||||
2. meaning: No need to load and assign anything. Proceed as usual.
|
||||
\returns B_LAST_BUFFER_ERROR No more video chunks available.
|
||||
fVideoChunkBuffer, fTempPacket and fContext are left untouched.
|
||||
\returns Other errors Caller should bail out because fVideoChunkBuffer,
|
||||
fTempPacket and fContext are in unknown states. Normal operation cannot
|
||||
be guaranteed.
|
||||
fVideoChunkBuffer and fTempPacket are left untouched.
|
||||
\returns Other errors Caller should bail out because fVideoChunkBuffer and
|
||||
fTempPacket are in unknown states. Normal operation cannot be
|
||||
guaranteed.
|
||||
*/
|
||||
status_t
|
||||
AVCodecDecoder::_LoadNextVideoChunkIfNeededAndUpdateStartTime()
|
||||
AVCodecDecoder::_LoadNextVideoChunkIfNeededAndAssignStartTime()
|
||||
{
|
||||
// TODO: Rename fVideoChunkBuffer to fChunkBuffer, once the audio path is
|
||||
// responsible for releasing the chunk buffer, too.
|
||||
@ -863,16 +863,11 @@ AVCodecDecoder::_LoadNextVideoChunkIfNeededAndUpdateStartTime()
|
||||
|
||||
fTempPacket.data = fVideoChunkBuffer;
|
||||
fTempPacket.size = fChunkBufferSize;
|
||||
|
||||
fContext->reordered_opaque = chunkMediaHeader.start_time;
|
||||
// Let FFMPEG handle the relationship between start_time and
|
||||
// decoded video frame.
|
||||
//
|
||||
// Explanation:
|
||||
// The received chunk buffer may not contain the next video
|
||||
// frame to be decoded, due to frame reordering (e.g. MPEG1/2
|
||||
// provides encoded video frames in a different order than the
|
||||
// decoded video frame).
|
||||
fTempPacket.dts = chunkMediaHeader.start_time;
|
||||
// Let FFMPEG handle the correct relationship between start_time and
|
||||
// decoded video frame. By doing so we are simply copying the way how
|
||||
// it is implemented in ffplay.c
|
||||
// \see http://git.videolan.org/?p=ffmpeg.git;a=blob;f=ffplay.c;h=09623db374e5289ed20b7cc28c262c4375a8b2e4;hb=9153b33a742c4e2a85ff6230aea0e75f5a8b26c2#l1502
|
||||
//
|
||||
// FIXME: Research how to establish a meaningful relationship
|
||||
// between start_time and decoded video frame when the received
|
||||
@ -1039,7 +1034,7 @@ AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
|
||||
fHeader.type = B_MEDIA_RAW_VIDEO;
|
||||
fHeader.file_pos = 0;
|
||||
fHeader.orig_size = 0;
|
||||
fHeader.start_time = fRawDecodedPicture->reordered_opaque;
|
||||
fHeader.start_time = fRawDecodedPicture->pkt_dts;
|
||||
fHeader.size_used = fDecodedDataSizeInBytes;
|
||||
fHeader.u.raw_video.display_line_width = fRawDecodedPicture->width;
|
||||
fHeader.u.raw_video.display_line_count = fRawDecodedPicture->height;
|
||||
|
@ -61,7 +61,7 @@ private:
|
||||
media_header* mediaHeader,
|
||||
media_decode_info* info);
|
||||
status_t _DecodeNextVideoFrame();
|
||||
status_t _LoadNextVideoChunkIfNeededAndUpdateStartTime();
|
||||
status_t _LoadNextVideoChunkIfNeededAndAssignStartTime();
|
||||
// TODO: Remove the "Video" word once
|
||||
// the audio path is responsible for
|
||||
// freeing the chunk buffer, too.
|
||||
|
Loading…
x
Reference in New Issue
Block a user