On Tue, 22 Mar 2016 23:41:29 -0400
Vittorio Giovara <vittorio.giov...@gmail.com> wrote:

> On Tue, Mar 22, 2016 at 2:09 PM, wm4 <nfx...@googlemail.com> wrote:
> > This needs to be explicitly supported by the AVCodec. Async mode can
> > be enabled for AVCodecs without explicit support too, which is treated
> > as if the codec performs all work instantly.
> > ---
> >  libavcodec/avcodec.h | 114 
> > +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  libavcodec/utils.c   |  30 ++++++++++++++
> >  2 files changed, 144 insertions(+)  
> 
> > @@ -4304,6 +4368,56 @@ int avcodec_send_frame(AVCodecContext *avctx, const 
> > AVFrame *frame);
> >   */
> >  int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
> >
> > +/**
> > + * Determine whether there is still work to do (sending input or receiving
> > + * output). See asynchronous mode section for an overview.
> > + *
> > + * If this returns 0, the caller thread can go to sleep (or do something 
> > else)
> > + * while the codec is processing previously sent input data on a worker 
> > thread.
> > + * It is guaranteed that AVCodecContext.async_notification will be called 
> > once
> > + * the API user can do more progress by calling the usual functions for 
> > sending/
> > + * receiving input/output. Strictly speaking, the callback could be invoked
> > + * _while_ the function call returns to the caller.
> > + *
> > + * Here is an example that should avoid missed wakeups due to race 
> > conditions:
> > + *
> > + *      sem_t semaphore;
> > + *      void user_async_notification(AVCodecContext *ctx) {
> > + *              // unblock the decoding loop
> > + *              sem_post(&semaphore);
> > + *      }
> > + *      void decode() {
> > + *              AVCodecContext *ctx = ...alloc and setup context...;
> > + *              ctx->flags2 |= AV_CODEC_FLAG2_ASYNC_MODE;
> > + *              ctx->async_notification = user_async_notification;
> > + *              sem_init(&semaphore, 0, 0);
> > + *              avcodec_open2(ctx, codec, NULL);
> > + *              // decoding loop
> > + *              while (1) {
> > + *                      // exchanges packets/frames; either or both of 
> > these
> > + *                      // might return AVERROR(EAGAIN)
> > + *                      avcodec_send_packet(ctx, ...);
> > + *                      avcodec_receive_frame(ctx, ...);
> > + *                      // reset the wait count to avoid unnecessary 
> > wakeups
> > + *                      while (!sem_try_wait(&semaphore));
> > + *                      // the important part is that 
> > user_async_notification
> > + *                      // could be called starting from here (_during_ 
> > and not
> > + *                      // _after_ the avcodec_check_async_progress call)
> > + *                      if (avcodec_check_async_progress(ctx) == 0)
> > + *                              sem_wait(&semaphore);
> > + *              }
> > + *              ...
> > + *      }  
> 
> Is there any way we could avoid exposing the users to the sync
> mechanism? Many applications won't need that level of control.

Not sure what you mean. Seems like you want to avoid that users have to
deal with the async API? They don't have to, unless there'll actually
be a decoder using AV_CODEC_CAP_ASYNC_ONLY. (And I'm still not sure if
that flag is needed - I only added it "in case".)
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to