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.
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel