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 [email protected] http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
