Description: TODO: Put a short summary on the line above and replace this paragraph with a longer explanation of this change. Complete the meta-information with other relevant fields (see below for details). To make it easier, the information below has been extracted from the changelog. Adjust it or drop it. . ffmpeg (7:5.1.2-3) unstable; urgency=medium . * debian/rules: Disable more tests on ppc64 (Closes: #1022764) * debian/patches: Add upstream patch to fix FTBFS after vulkan changes (Closes: #1031447) Author: Sebastian Ramacher Bug-Debian: https://bugs.debian.org/1022764 Bug-Debian: https://bugs.debian.org/1031447 --- The information above should follow the Patch Tagging Guidelines, please checkout https://dep.debian.net/deps/dep3/ to learn about the format. Here are templates for supplementary fields that you might want to add: Origin: (upstream|backport|vendor|other), (|commit:) Bug: Bug-Debian: https://bugs.debian.org/ Bug-Ubuntu: https://launchpad.net/bugs/ Forwarded: (no|not-needed|) Applied-Upstream: , (|commit:) Reviewed-By: Last-Update: 2023-03-15 --- ffmpeg-5.1.2.orig/libavcodec/allcodecs.c +++ ffmpeg-5.1.2/libavcodec/allcodecs.c @@ -34,6 +34,10 @@ #include "codec_id.h" #include "codec_internal.h" +extern const FFCodec ff_h264_omx_decoder; +extern const FFCodec ff_hevc_omx_encoder; +extern const FFCodec ff_hevc_omx_decoder; +extern const FFCodec ff_mjpeg_omx_decoder; extern const FFCodec ff_a64multi_encoder; extern const FFCodec ff_a64multi5_encoder; extern const FFCodec ff_aasc_decoder; @@ -823,11 +827,7 @@ extern const FFCodec ff_h264_cuvid_decod extern const FFCodec ff_h264_mf_encoder; extern const FFCodec ff_h264_nvenc_encoder; extern const FFCodec ff_h264_omx_encoder; -extern const FFCodec ff_h264_omx_decoder; -extern const FFCodec ff_hevc_omx_encoder; -extern const FFCodec ff_hevc_omx_decoder; extern const FFCodec ff_h264_qsv_encoder; -extern const FFCodec ff_mjpeg_omx_decoder; extern const FFCodec ff_h264_v4l2m2m_encoder; extern const FFCodec ff_h264_vaapi_encoder; extern const FFCodec ff_h264_videotoolbox_encoder; --- ffmpeg-5.1.2.orig/libavcodec/omxdec.c +++ ffmpeg-5.1.2/libavcodec/omxdec.c @@ -34,6 +34,7 @@ #include #include +#include "libavcodec/decode.h" #include "libavutil/avstring.h" #include "libavutil/avutil.h" #include "libavutil/common.h" @@ -355,6 +356,7 @@ typedef struct OMXCodecContext { int eos_sent, got_eos, evnet_bufferflag, first_get_outbuffer; int extradata_sent; + int has_cleanup; uint8_t *output_buf; int output_buf_size; @@ -943,6 +945,7 @@ static av_cold int omx_component_init(AV static av_cold void cleanup(OMXCodecContext *s) { int i, executing; + OMX_BUFFERHEADERTYPE *buffer; pthread_mutex_lock(&s->state_mutex); executing = s->state == OMX_StateExecuting; @@ -953,17 +956,24 @@ static av_cold void cleanup(OMXCodecCont wait_for_state(s, OMX_StateIdle); OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL); for (i = 0; i < s->num_in_buffers; i++) { - OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->input_mutex, &s->input_cond, + buffer = get_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, 1); if (s->input_zerocopy) buffer->pBuffer = NULL; OMX_FreeBuffer(s->handle, s->in_port, buffer); } - for (i = 0; i < s->num_out_buffers; i++) { - OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->output_mutex, &s->output_cond, - &s->num_done_out_buffers, s->done_out_buffers, 1); + + while (buffer = get_buffer(&s->output_mutex, &s->output_cond, + &s->num_done_out_buffers, s->done_out_buffers, 0)) { OMX_FreeBuffer(s->handle, s->out_port, buffer); + s->num_out_buffers--; + } + + if (s->num_out_buffers) { + s->has_cleanup = 1; + return; } + wait_for_state(s, OMX_StateLoaded); } if (s->handle) { @@ -1099,6 +1109,94 @@ fail: return ret; } +static void omx_free_out_buffer(void *opaque, uint8_t *unused) +{ + OMX_ERRORTYPE err; + OMX_BUFFERHEADERTYPE *buffer = opaque; + OMXCodecContext *s = buffer->pAppPrivate; + + if (!s->has_cleanup) { + err = OMX_FillThisBuffer(s->handle, buffer); + if (err != OMX_ErrorNone) { + append_buffer(&s->output_mutex, &s->output_cond, &s->num_done_out_buffers, s->done_out_buffers, buffer); + av_log(s->avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed, err: %x\n", err); + } + } else { + OMX_FreeBuffer(s->handle, s->out_port, buffer); + s->num_out_buffers--; + if (!s->num_out_buffers) { + wait_for_state(s, OMX_StateLoaded); + if (s->handle) { + s->omx_context->ptr_FreeHandle(s->handle); + s->handle = NULL; + } + + omx_deinit(s->omx_context); + s->omx_context = NULL; + if (s->mutex_cond_inited) { + pthread_cond_destroy(&s->state_cond); + pthread_mutex_destroy(&s->state_mutex); + pthread_cond_destroy(&s->input_cond); + pthread_mutex_destroy(&s->input_mutex); + pthread_cond_destroy(&s->output_cond); + pthread_mutex_destroy(&s->output_mutex); + pthread_cond_destroy(&s->disableEVnt_cond); + pthread_mutex_destroy(&s->disableEVnt_mutex); + s->mutex_cond_inited = 0; + } + OMXDecodeQueueDestory(&s->decode_pts_queue); + av_freep(&s->decode_pts_queue); + av_freep(&s->in_buffer_headers); + av_freep(&s->out_buffer_headers); + av_freep(&s->free_in_buffers); + av_freep(&s->done_out_buffers); + av_freep(&s->output_buf); + } + } +} + +static int omx_buf_to_swframe(OMXCodecContext *s, AVFrame *frame, OMX_BUFFERHEADERTYPE *buffer) +{ + int ret; + uint8_t *dst[4]; + int linesize[4]; + + frame->buf[0] = av_buffer_create((char *)buffer->pBuffer, buffer->nFilledLen, omx_free_out_buffer, buffer, 0); + + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + ret = av_image_fill_arrays(dst, linesize, buffer->pBuffer, + s->avctx->pix_fmt, s->stride, s->plane_size, 1); + if (ret < 0){ + av_log(s->avctx, AV_LOG_ERROR, "av_image_fill_arrays ret:%d\n", ret); + return AVERROR(EINVAL); + } + + frame->linesize[0] = linesize[0]; + frame->data[0] = frame->buf[0]->data; + + /* fixup special cases */ + switch (s->avctx->pix_fmt) { + case AV_PIX_FMT_NV12: + case AV_PIX_FMT_NV21: + frame->linesize[1] = linesize[1]; + frame->data[1] = dst[1]; + break; + + case AV_PIX_FMT_YUV420P: + frame->linesize[1] = linesize[1]; + frame->linesize[2] = linesize[2]; + frame->data[1] = dst[1]; + frame->data[2] = dst[2]; + break; + + default: + break; + } + + return 0; +} static int omx_decode_frame(AVCodecContext *avctx, AVFrame *data, int *got_packet, AVPacket *pkt) @@ -1111,9 +1209,6 @@ static int omx_decode_frame(AVCodecConte AVFrame *avframe = data; - uint8_t *dst[4]; - int linesize[4]; - av_log(avctx, AV_LOG_VERBOSE, "s->decode_flag: %d\n", s->decode_flag); av_log(avctx, AV_LOG_VERBOSE, "avctx->time_base: %d/%d \n", avctx->time_base.num, avctx->time_base.den); av_log(avctx, AV_LOG_VERBOSE, "avctx->pkt_timebase: %d/%d \n", avctx->pkt_timebase.num, avctx->pkt_timebase.den); @@ -1226,20 +1321,21 @@ static int omx_decode_frame(AVCodecConte if (buffer->nFlags & OMX_BUFFERFLAG_EOS) s->got_eos = 1; - if ((ret = ff_get_buffer(avctx, avframe, 0)) < 0) { - av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n"); + avframe->width = avctx->width; + avframe->height = avctx->height; + + ret = ff_decode_frame_props(avctx, avframe); + if(ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Unable to fill buffer props\n"); goto end; } - ret = av_image_fill_arrays(dst, linesize, buffer->pBuffer, - avctx->pix_fmt, s->stride, s->plane_size, 1); - if (ret < 0){ - av_log(avctx, AV_LOG_ERROR, "av_image_fill_arrays ret:%d\n", ret); + ret = omx_buf_to_swframe(s, avframe, buffer); + if(ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Unable to alloce frame\n"); goto end; } - av_image_copy(avframe->data, avframe->linesize, (const uint8_t**)dst, linesize, - avctx->pix_fmt, avctx->width, avctx->height); if (pkt->pts) { if (OMXDecodeQueueEmpty(&s->decode_pts_queue) != 0){ av_log(avctx, AV_LOG_ERROR, "The queue of decode pts is empty.\n"); @@ -1251,10 +1347,7 @@ static int omx_decode_frame(AVCodecConte s->decode_flag += 1; *got_packet = 1; - /* - if ((ret = av_frame_ref(data, avframe)) < 0) - goto end; - */ + return ret; end: err = OMX_FillThisBuffer(s->handle, buffer);