FFMPEG Plugin: Fix performance regression on video path.
- For best performance the color conversion function expects a memory location aligned to 32 bytes. Without that alignment the color conversion function falls back to a slower conversion path. This fix was measured via DO_PROFILING and tested with various 1080p video files.
This commit is contained in:
@@ -1172,7 +1172,9 @@ AVCodecDecoder::_DecodeNextVideoFrame()
|
|||||||
bigtime_t formatConversionStart = system_time();
|
bigtime_t formatConversionStart = system_time();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_HandleNewVideoFrameAndUpdateSystemState();
|
status_t handleStatus = _HandleNewVideoFrameAndUpdateSystemState();
|
||||||
|
if (handleStatus != B_OK)
|
||||||
|
return handleStatus;
|
||||||
|
|
||||||
#if DO_PROFILING
|
#if DO_PROFILING
|
||||||
bigtime_t doneTime = system_time();
|
bigtime_t doneTime = system_time();
|
||||||
@@ -1360,12 +1362,17 @@ AVCodecDecoder::_CopyChunkToChunkBufferAndAddPadding(const void* chunk,
|
|||||||
\see _UpdateMediaHeaderForVideoFrame() and
|
\see _UpdateMediaHeaderForVideoFrame() and
|
||||||
\see _DeinterlaceAndColorConvertVideoFrame() for when you are allowed to
|
\see _DeinterlaceAndColorConvertVideoFrame() for when you are allowed to
|
||||||
call this method.
|
call this method.
|
||||||
|
|
||||||
|
\returns B_OK when video frame was handled successfully
|
||||||
|
\returnb B_NO_MEMORY when no memory is left for correct operation.
|
||||||
*/
|
*/
|
||||||
void
|
status_t
|
||||||
AVCodecDecoder::_HandleNewVideoFrameAndUpdateSystemState()
|
AVCodecDecoder::_HandleNewVideoFrameAndUpdateSystemState()
|
||||||
{
|
{
|
||||||
_UpdateMediaHeaderForVideoFrame();
|
_UpdateMediaHeaderForVideoFrame();
|
||||||
_DeinterlaceAndColorConvertVideoFrame();
|
status_t postProcessStatus = _DeinterlaceAndColorConvertVideoFrame();
|
||||||
|
if (postProcessStatus != B_OK)
|
||||||
|
return postProcessStatus;
|
||||||
|
|
||||||
ConvertAVCodecContextToVideoFrameRate(*fContext, fOutputFrameRate);
|
ConvertAVCodecContextToVideoFrameRate(*fContext, fOutputFrameRate);
|
||||||
|
|
||||||
@@ -1374,6 +1381,8 @@ AVCodecDecoder::_HandleNewVideoFrameAndUpdateSystemState()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
fFrame++;
|
fFrame++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1393,6 +1402,8 @@ AVCodecDecoder::_HandleNewVideoFrameAndUpdateSystemState()
|
|||||||
|
|
||||||
\returns B_LAST_BUFFER_ERROR No video frame left.
|
\returns B_LAST_BUFFER_ERROR No video frame left.
|
||||||
The client of the AVCodecDecoder should stop calling it now.
|
The client of the AVCodecDecoder should stop calling it now.
|
||||||
|
|
||||||
|
\returns B_NO_MEMORY No memory left for correct operation.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
AVCodecDecoder::_FlushOneVideoFrameFromDecoderBuffer()
|
AVCodecDecoder::_FlushOneVideoFrameFromDecoderBuffer()
|
||||||
@@ -1413,9 +1424,7 @@ AVCodecDecoder::_FlushOneVideoFrameFromDecoderBuffer()
|
|||||||
return B_LAST_BUFFER_ERROR;
|
return B_LAST_BUFFER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
_HandleNewVideoFrameAndUpdateSystemState();
|
return _HandleNewVideoFrameAndUpdateSystemState();
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1487,8 +1496,11 @@ AVCodecDecoder::_UpdateMediaHeaderForVideoFrame()
|
|||||||
When this function finishes the postprocessed video frame will be available
|
When this function finishes the postprocessed video frame will be available
|
||||||
in fPostProcessedDecodedPicture and fDecodedData (fDecodedDataSizeInBytes
|
in fPostProcessedDecodedPicture and fDecodedData (fDecodedDataSizeInBytes
|
||||||
will be set accordingly).
|
will be set accordingly).
|
||||||
|
|
||||||
|
\returns B_OK video frame successfully deinterlaced and color converted.
|
||||||
|
\returns B_NO_MEMORY Not enough memory available for correct operation.
|
||||||
*/
|
*/
|
||||||
void
|
status_t
|
||||||
AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame()
|
AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame()
|
||||||
{
|
{
|
||||||
int displayWidth = fRawDecodedPicture->width;
|
int displayWidth = fRawDecodedPicture->width;
|
||||||
@@ -1534,9 +1546,13 @@ AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame()
|
|||||||
|
|
||||||
fDecodedDataSizeInBytes = fHeader.size_used;
|
fDecodedDataSizeInBytes = fHeader.size_used;
|
||||||
|
|
||||||
|
if (fDecodedData == NULL) {
|
||||||
|
const size_t kOptimalAlignmentForColorConversion = 32;
|
||||||
|
posix_memalign(reinterpret_cast<void**>(&fDecodedData),
|
||||||
|
kOptimalAlignmentForColorConversion, fDecodedDataSizeInBytes);
|
||||||
|
}
|
||||||
if (fDecodedData == NULL)
|
if (fDecodedData == NULL)
|
||||||
fDecodedData
|
return B_NO_MEMORY;
|
||||||
= static_cast<uint8_t*>(malloc(fDecodedDataSizeInBytes));
|
|
||||||
|
|
||||||
fPostProcessedDecodedPicture->data[0] = fDecodedData;
|
fPostProcessedDecodedPicture->data[0] = fDecodedData;
|
||||||
fPostProcessedDecodedPicture->linesize[0]
|
fPostProcessedDecodedPicture->linesize[0]
|
||||||
@@ -1586,4 +1602,6 @@ AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame()
|
|||||||
|
|
||||||
if (fRawDecodedPicture->interlaced_frame)
|
if (fRawDecodedPicture->interlaced_frame)
|
||||||
avpicture_free(&deinterlacedPicture);
|
avpicture_free(&deinterlacedPicture);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,10 +75,10 @@ private:
|
|||||||
status_t _LoadNextChunkIfNeededAndAssignStartTime();
|
status_t _LoadNextChunkIfNeededAndAssignStartTime();
|
||||||
status_t _CopyChunkToChunkBufferAndAddPadding(const void* chunk,
|
status_t _CopyChunkToChunkBufferAndAddPadding(const void* chunk,
|
||||||
size_t chunkSize);
|
size_t chunkSize);
|
||||||
void _HandleNewVideoFrameAndUpdateSystemState();
|
status_t _HandleNewVideoFrameAndUpdateSystemState();
|
||||||
status_t _FlushOneVideoFrameFromDecoderBuffer();
|
status_t _FlushOneVideoFrameFromDecoderBuffer();
|
||||||
void _UpdateMediaHeaderForVideoFrame();
|
void _UpdateMediaHeaderForVideoFrame();
|
||||||
void _DeinterlaceAndColorConvertVideoFrame();
|
status_t _DeinterlaceAndColorConvertVideoFrame();
|
||||||
|
|
||||||
|
|
||||||
media_header fHeader;
|
media_header fHeader;
|
||||||
|
|||||||
Reference in New Issue
Block a user