diff mbox

[FFmpeg-devel,3/3] avcodec/videotoolboxenc: fix invalid session on iOS

Message ID 20180614154807.14311-1-thomas@gllm.fr
State Accepted
Commit 513e6a30fb013ca34812ccaaf3d090680ac868c5
Headers show

Commit Message

Thomas Guillem June 14, 2018, 3:48 p.m. UTC
Cf. comment. Restart the VT session when the APP goes from foreground to
background and vice versa.
---
 libavcodec/videotoolboxenc.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

Comments

Thomas Guillem June 18, 2018, 9:21 a.m. UTC | #1
Ping?

On Thu, Jun 14, 2018, at 17:48, Thomas Guillem wrote:
> Cf. comment. Restart the VT session when the APP goes from foreground to
> background and vice versa.
> ---
>  libavcodec/videotoolboxenc.c | 23 +++++++++++++++++++++--
>  1 file changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
> index 1060055ba5..ac847358ab 100644
> --- a/libavcodec/videotoolboxenc.c
> +++ b/libavcodec/videotoolboxenc.c
> @@ -2175,8 +2175,27 @@ static int create_cv_pixel_buffer(AVCodecContext   
> *avctx,
>  #if TARGET_OS_IPHONE
>      pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx-
> >session);
>      if (!pix_buf_pool) {
> -        av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.
> \n");
> -        return AVERROR_EXTERNAL;
> +        /* On iOS, the VT session is invalidated when the APP switches 
> from
> +         * foreground to background and vice versa. Fetch the actual 
> error code
> +         * of the VT session to detect that case and restart the VT 
> session
> +         * accordingly. */
> +        OSStatus vtstatus;
> +
> +        vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx-
> >session);
> +        if (vtstatus == kVTInvalidSessionErr) {
> +            CFRelease(vtctx->session);
> +            vtctx->session = NULL;
> +            status = vtenc_configure_encoder(avctx);
> +            if (status == 0)
> +                pix_buf_pool = 
> VTCompressionSessionGetPixelBufferPool(vtctx->session);
> +        }
> +        if (!pix_buf_pool) {
> +            av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer 
> pool.\n");
> +            return AVERROR_EXTERNAL;
> +        }
> +        else
> +            av_log(avctx, AV_LOG_WARNING, "VT session restarted because 
> of a "
> +                   "kVTInvalidSessionErr error.\n");
>      }
>  
>      status = CVPixelBufferPoolCreatePixelBuffer(NULL,
> -- 
> 2.17.1
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Aman Karmani June 18, 2018, 6:50 p.m. UTC | #2
On Mon, Jun 18, 2018 at 2:22 AM Thomas Guillem <thomas@gllm.fr> wrote:

> Ping?
>

Applied to master and release/4.0 branches.

Aman


>
> On Thu, Jun 14, 2018, at 17:48, Thomas Guillem wrote:
> > Cf. comment. Restart the VT session when the APP goes from foreground to
> > background and vice versa.
> > ---
> >  libavcodec/videotoolboxenc.c | 23 +++++++++++++++++++++--
> >  1 file changed, 21 insertions(+), 2 deletions(-)
> >
> > diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
> > index 1060055ba5..ac847358ab 100644
> > --- a/libavcodec/videotoolboxenc.c
> > +++ b/libavcodec/videotoolboxenc.c
> > @@ -2175,8 +2175,27 @@ static int create_cv_pixel_buffer(AVCodecContext
>
> > *avctx,
> >  #if TARGET_OS_IPHONE
> >      pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx-
> > >session);
> >      if (!pix_buf_pool) {
> > -        av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.
> > \n");
> > -        return AVERROR_EXTERNAL;
> > +        /* On iOS, the VT session is invalidated when the APP switches
> > from
> > +         * foreground to background and vice versa. Fetch the actual
> > error code
> > +         * of the VT session to detect that case and restart the VT
> > session
> > +         * accordingly. */
> > +        OSStatus vtstatus;
> > +
> > +        vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx-
> > >session);
> > +        if (vtstatus == kVTInvalidSessionErr) {
> > +            CFRelease(vtctx->session);
> > +            vtctx->session = NULL;
> > +            status = vtenc_configure_encoder(avctx);
> > +            if (status == 0)
> > +                pix_buf_pool =
> > VTCompressionSessionGetPixelBufferPool(vtctx->session);
> > +        }
> > +        if (!pix_buf_pool) {
> > +            av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer
> > pool.\n");
> > +            return AVERROR_EXTERNAL;
> > +        }
> > +        else
> > +            av_log(avctx, AV_LOG_WARNING, "VT session restarted because
> > of a "
> > +                   "kVTInvalidSessionErr error.\n");
> >      }
> >
> >      status = CVPixelBufferPoolCreatePixelBuffer(NULL,
> > --
> > 2.17.1
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
diff mbox

Patch

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index 1060055ba5..ac847358ab 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -2175,8 +2175,27 @@  static int create_cv_pixel_buffer(AVCodecContext   *avctx,
 #if TARGET_OS_IPHONE
     pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
     if (!pix_buf_pool) {
-        av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.\n");
-        return AVERROR_EXTERNAL;
+        /* On iOS, the VT session is invalidated when the APP switches from
+         * foreground to background and vice versa. Fetch the actual error code
+         * of the VT session to detect that case and restart the VT session
+         * accordingly. */
+        OSStatus vtstatus;
+
+        vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
+        if (vtstatus == kVTInvalidSessionErr) {
+            CFRelease(vtctx->session);
+            vtctx->session = NULL;
+            status = vtenc_configure_encoder(avctx);
+            if (status == 0)
+                pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
+        }
+        if (!pix_buf_pool) {
+            av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.\n");
+            return AVERROR_EXTERNAL;
+        }
+        else
+            av_log(avctx, AV_LOG_WARNING, "VT session restarted because of a "
+                   "kVTInvalidSessionErr error.\n");
     }
 
     status = CVPixelBufferPoolCreatePixelBuffer(NULL,