[FFmpeg-devel] [PATCH] avcodec/h264, videotoolbox: handle streams with multiple/changing PPS

Aman Gupta ffmpeg at tmm1.net
Wed Feb 15 07:33:38 EET 2017


On Tue, Feb 14, 2017 at 5:14 PM Aman Gupta <ffmpeg at tmm1.net> wrote:

> From: Aman Gupta <aman at tmm1.net>
>
> The videotoolbox hwaccel only receives SLICE and IDR_SLICE NALUs. This
> works fine most of the time, but some streams fail to decode because
> changes in PPS are not propagated to the VT decoder.


Perhaps SPS can change mid-stream, and should be passed into the VT decoder
as well? I'm not familiar enough with h264 to know.


>
> The failures in this case are incredibly annoying, as VTDecodeFrame()
> still returns noErr. Simiarly the decoder callback is invoked with noErr,
> and a NULL imageBuffer. Even though all the VT apis indicate success, no
> frames are actually decoded.
>
> When running ffmpeg via lldb however, some internal VT errors and
> warnings show up all of a sudden. These suggest that the bitstream is
> failing some internal consistency checks.
>
>     $ ffmpeg -y -loglevel error -threads 1 -hwaccel videotoolbox \
>              -i http://tmm1.s3.amazonaws.com/h264.ts -map v -f null
> /dev/null
>     ...
>     [h264 @ 0x7fdadc000000] hardware accelerator failed to decode picture
>     Error while decoding stream #0:0: Unknown error occurred
>     vt decoder cb: output image buffer is null
>     ...
>
>     $ lldb -- ffmpeg ...
>     ...
>     ffmpeg[49384:2009219] GVA error: AVC_RBSP::parseSliceHeader error
>     ffmpeg[49384:2009219] GVA error: pushPicture parseSliceHeader
>     vt decoder cb: output image buffer is null
>     ffmpeg[49384:2009219] GVA warning: OutputQueueReadyCallback status =
> 1, buffer == 0x0
>     [h264 @ 0x10300a200] hardware accelerator failed to decode picture:
> Unknown error occurred
>     Error while decoding stream #0:0: Unknown error occurred
>     ...
>
> After this patch, there are no more errors and the sample decodes as
> expected.
> ---
>  libavcodec/h264dec.c      | 7 +++++++
>  libavcodec/videotoolbox.c | 8 +++++---
>  2 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
> index 41c0964..af8b256 100644
> --- a/libavcodec/h264dec.c
> +++ b/libavcodec/h264dec.c
> @@ -755,6 +755,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
>                                                         nal->size_bits);
>              if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
>                  goto end;
> +            if (avctx->hwaccel && avctx->hwaccel->pix_fmt ==
> AV_PIX_FMT_VIDEOTOOLBOX) {
> +                ret = avctx->hwaccel->decode_slice(avctx,
> +                                                   nal->raw_data,
> +                                                   nal->raw_size);
> +                if (ret < 0)
> +                    goto end;
> +            }
>              break;
>          case H264_NAL_AUD:
>          case H264_NAL_END_SEQUENCE:
> diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
> index 1288aa5..1b5dffd 100644
> --- a/libavcodec/videotoolbox.c
> +++ b/libavcodec/videotoolbox.c
> @@ -138,8 +138,6 @@ int ff_videotoolbox_h264_start_frame(AVCodecContext
> *avctx,
>      VTContext *vtctx = avctx->internal->hwaccel_priv_data;
>      H264Context *h  = avctx->priv_data;
>
> -    vtctx->bitstream_size = 0;
> -
>      if (h->is_avc == 1) {
>          return videotoolbox_buffer_copy(vtctx, buffer, size);
>      }
> @@ -373,8 +371,12 @@ static int videotoolbox_h264_end_frame(AVCodecContext
> *avctx)
>  {
>      H264Context *h = avctx->priv_data;
>      AVFrame *frame = h->cur_pic_ptr->f;
> +    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
> +    int ret;
>
> -    return videotoolbox_common_end_frame(avctx, frame);
> +    ret = videotoolbox_common_end_frame(avctx, frame);
> +    vtctx->bitstream_size = 0;
> +    return ret;
>  }
>
>  static int videotoolbox_mpeg_start_frame(AVCodecContext *avctx,
> --
> 2.10.1 (Apple Git-78)
>
>


More information about the ffmpeg-devel mailing list