mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-12-11 13:16:26 +00:00
avcodec/omx: Fix handling of fragmented buffers
See https://trac.ffmpeg.org/ticket/7687 If an encoded frame is returned split over two or more IL buffers due to the size, then there is a race between whether get_buffer will fail, return NULL, and a truncated frame is passed on, or IL will return the remaining part of the encoded frame. If get_buffer returns NULL, part of the frame is left behind in the codec, and will be collected on the next call. That then leaves a frame stuck in the codec. Repeat enough times and the codec FIFO is full, and the pipeline stalls. A performance improvement in the Raspberry Pi firmware means that the timing has changed, and now frequently drops into the case where get_buffer returns NULL. Add code such that should a buffer be received without OMX_BUFFERFLAG_ENDOFFRAME that get_buffer is called with wait set, so we wait for the remainder of the frame. This code has been made conditional on the Pi build in case other IL implementations don't handle ENDOFFRAME correctly. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> Signed-off-by: Aman Gupta <aman@tmm1.net> Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
23a3e1460a
commit
3d857f219e
@ -735,6 +735,7 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
OMX_BUFFERHEADERTYPE* buffer;
|
OMX_BUFFERHEADERTYPE* buffer;
|
||||||
OMX_ERRORTYPE err;
|
OMX_ERRORTYPE err;
|
||||||
|
int had_partial = 0;
|
||||||
|
|
||||||
if (frame) {
|
if (frame) {
|
||||||
uint8_t *dst[4];
|
uint8_t *dst[4];
|
||||||
@ -846,7 +847,7 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
// packet, or get EOS.
|
// packet, or get EOS.
|
||||||
buffer = get_buffer(&s->output_mutex, &s->output_cond,
|
buffer = get_buffer(&s->output_mutex, &s->output_cond,
|
||||||
&s->num_done_out_buffers, s->done_out_buffers,
|
&s->num_done_out_buffers, s->done_out_buffers,
|
||||||
!frame);
|
!frame || had_partial);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -881,6 +882,9 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
s->output_buf = NULL;
|
s->output_buf = NULL;
|
||||||
s->output_buf_size = 0;
|
s->output_buf_size = 0;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_OMX_RPI
|
||||||
|
had_partial = 1;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// End of frame, and the caller provided a preallocated frame
|
// End of frame, and the caller provided a preallocated frame
|
||||||
if ((ret = ff_alloc_packet2(avctx, pkt, s->output_buf_size + buffer->nFilledLen, 0)) < 0) {
|
if ((ret = ff_alloc_packet2(avctx, pkt, s->output_buf_size + buffer->nFilledLen, 0)) < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user