[FFmpeg-devel] [PATCH] videotoolbox: allow to enable the async decoding.

Clément Bœsch u at pkh.me
Tue Oct 6 17:09:35 CEST 2015


On Thu, Sep 24, 2015 at 11:45:42AM +0200, Clément Bœsch wrote:
> On Sun, Aug 09, 2015 at 01:11:44PM +0200, Sebastien Zwickert wrote:
> > This patch allows to use the Videotoolbox API in asynchonous mode.
> > Note that when using async decoding the user is responsible for
> > releasing the async frame.
> > Moreover, an option called videotoolbox_async was added to enable
> > async decoding with ffmpeg CLI.
> > 
> > ---
> >  ffmpeg.h                  |   1 +
> >  ffmpeg_opt.c              |   1 +
> >  ffmpeg_videotoolbox.c     |  69 +++++++++++++----
> >  libavcodec/videotoolbox.c | 186 ++++++++++++++++++++++++++++++++++++++++------
> >  libavcodec/videotoolbox.h |  73 ++++++++++++++++++
> >  5 files changed, 294 insertions(+), 36 deletions(-)
> > 
> 
> Ping and more comments on this:
> 
> - is it meaningful to have a limit on the internal queue size (for memory
>   load for instance), or it's not relevant in case of hw accel?
> 

To answer myself: a limit is actually required or it causes a crash at
least on iOS after about 150 frames in the queue.

Following is a hack I needed:

diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
index 9664f16..73b9023 100644
--- a/libavcodec/videotoolbox.c
+++ b/libavcodec/videotoolbox.c
@@ -222,6 +222,8 @@ static void videotoolbox_clear_queue(struct AVVideotoolboxContext *videotoolbox)
         av_videotoolbox_release_async_frame(top_frame);
     }
 
+    videotoolbox->nb_frames = 0;
+
     videotoolbox_lock_operation(&videotoolbox->queue_mutex, AV_LOCK_RELEASE);
 }
 
@@ -379,6 +381,9 @@ static void videotoolbox_decoder_callback(void *opaque,
 
         videotoolbox_lock_operation(&videotoolbox->queue_mutex, AV_LOCK_OBTAIN);
 
+        while (videotoolbox->nb_frames == 16)
+            pthread_cond_wait(&videotoolbox->queue_reduce, videotoolbox->queue_mutex);
+
         queue_walker = videotoolbox->queue;
 
         if (!queue_walker || (new_frame->pts < queue_walker->pts)) {
@@ -401,6 +406,7 @@ static void videotoolbox_decoder_callback(void *opaque,
             }
         }
 
+        videotoolbox->nb_frames++;
         videotoolbox_lock_operation(&videotoolbox->queue_mutex, AV_LOCK_RELEASE);
     }
 }
@@ -617,6 +623,8 @@ static int videotoolbox_default_init(AVCodecContext *avctx)
             return -1;
 
         videotoolbox_lock_operation(&videotoolbox->queue_mutex, AV_LOCK_CREATE);
+
+        pthread_cond_init(&videotoolbox->queue_reduce, NULL);
     }
 
     switch( avctx->codec_id ) {
@@ -700,6 +708,8 @@ static void videotoolbox_default_free(AVCodecContext *avctx)
 
             videotoolbox_clear_queue(videotoolbox);
 
+            pthread_cond_destroy(&s->queue_reduce);
+
             if (videotoolbox->queue_mutex != NULL)
                 videotoolbox_lock_operation(&videotoolbox->queue_mutex, AV_LOCK_DESTROY);
         }
@@ -826,8 +836,11 @@ AVVideotoolboxAsyncFrame *av_videotoolbox_pop_async_frame(AVVideotoolboxContext
     videotoolbox_lock_operation(&videotoolbox->queue_mutex, AV_LOCK_OBTAIN);
     top_frame = videotoolbox->queue;
     videotoolbox->queue = top_frame->next_frame;
+    videotoolbox->nb_frames--;
     videotoolbox_lock_operation(&videotoolbox->queue_mutex, AV_LOCK_RELEASE);
 
+    pthread_cond_signal(&videotoolbox->queue_reduce);
+
     return top_frame;
 }
 
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index b5bf030..db41b4a 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -113,6 +113,9 @@ typedef struct AVVideotoolboxContext {
      */
     void *queue_mutex;
 
+    pthread_cond_t queue_reduce;
+    int nb_frames;
+
 } AVVideotoolboxContext;
 
 /**


> - isn't it missing a flush mechanism so seeking can be accurate?

videotoolbox_clear_queue() should probably be exported

[...]

But again all of this is more in the spirit of a proper async API...

BTW, I can confirm it fixes the playback speed on these devices.

-- 
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20151006/8a6ff59a/attachment.sig>


More information about the ffmpeg-devel mailing list