@@ -145,19 +145,21 @@ static int ffmmal_set_ref(AVFrame *frame, FFPoolRef *pool,
return 0;
}
-static void ffmmal_stop_decoder(AVCodecContext *avctx)
+static void ffmmal_stop_decoder(AVCodecContext *avctx, int flush_ports)
{
MMALDecodeContext *ctx = avctx->priv_data;
MMAL_COMPONENT_T *decoder = ctx->decoder;
MMAL_BUFFER_HEADER_T *buffer;
- mmal_port_disable(decoder->input[0]);
- mmal_port_disable(decoder->output[0]);
- mmal_port_disable(decoder->control);
+ if(flush_ports) {
+ mmal_port_disable(decoder->input[0]);
+ mmal_port_disable(decoder->output[0]);
+ mmal_port_disable(decoder->control);
- mmal_port_flush(decoder->input[0]);
- mmal_port_flush(decoder->output[0]);
- mmal_port_flush(decoder->control);
+ mmal_port_flush(decoder->input[0]);
+ mmal_port_flush(decoder->output[0]);
+ mmal_port_flush(decoder->control);
+ }
while ((buffer = mmal_queue_get(ctx->queue_decoded_frames)))
mmal_buffer_header_release(buffer);
@@ -185,7 +187,7 @@ static av_cold int ffmmal_close_decoder(AVCodecContext *avctx)
MMALDecodeContext *ctx = avctx->priv_data;
if (ctx->decoder)
- ffmmal_stop_decoder(avctx);
+ ffmmal_stop_decoder(avctx, 1);
mmal_component_destroy(ctx->decoder);
ctx->decoder = NULL;
@@ -456,14 +458,20 @@ static void ffmmal_flush(AVCodecContext *avctx)
MMAL_COMPONENT_T *decoder = ctx->decoder;
MMAL_STATUS_T status;
- ffmmal_stop_decoder(avctx);
+ // MMAL will freeze if ports are enabled/disabled/flushed before
+ // buffers are sent
+ int flush_ports = ctx->packets_sent || ctx->extradata_sent;
- if ((status = mmal_port_enable(decoder->control, control_port_cb)))
- goto fail;
- if ((status = mmal_port_enable(decoder->input[0], input_callback)))
- goto fail;
- if ((status = mmal_port_enable(decoder->output[0], output_callback)))
- goto fail;
+ ffmmal_stop_decoder(avctx, flush_ports);
+
+ if(flush_ports) {
+ if ((status = mmal_port_enable(decoder->control, control_port_cb)))
+ goto fail;
+ if ((status = mmal_port_enable(decoder->input[0], input_callback)))
+ goto fail;
+ if ((status = mmal_port_enable(decoder->output[0], output_callback)))
+ goto fail;
+ }
return;
When mmal_flush is called before any packets are sent, enabling/disabling the MMAL ports seems to cause the decoder to not output any packets after flushing. Bug is triggered when using 'mpv --hwdec=mmal --start=1 test.mp4'. Proposed workaround in MPV: https://github.com/mpv-player/mpv/pull/9189 Signed-off-by: Ho Ming Shun <cyph1984@gmail.com> --- libavcodec/mmaldec.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-)