diff mbox

[FFmpeg-devel,6/6] lavf: add avpriv function to register devices

Message ID 20180103004312.10ebcab171cb66235643a3e9@itanimul.li
State New
Headers show

Commit Message

Josh de Kock Jan. 3, 2018, 12:43 a.m. UTC
---
 libavdevice/alldevices.c |  6 +++++-
 libavformat/allformats.c | 44 +++++++++++++++++++++++++++++++++++++++-----
 libavformat/avformat.h   |  4 ++++
 3 files changed, 48 insertions(+), 6 deletions(-)

Comments

wm4 Jan. 3, 2018, 3:52 p.m. UTC | #1
On Wed, 3 Jan 2018 00:43:12 +0000
Josh de Kock <josh@itanimul.li> wrote:

> ---
>  libavdevice/alldevices.c |  6 +++++-
>  libavformat/allformats.c | 44 +++++++++++++++++++++++++++++++++++++++-----
>  libavformat/avformat.h   |  4 ++++
>  3 files changed, 48 insertions(+), 6 deletions(-)
> 
> diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
> index 6b2a512..041eb85 100644
> --- a/libavdevice/alldevices.c
> +++ b/libavdevice/alldevices.c
> @@ -105,6 +105,8 @@ static void av_device_init_next(void)
>      }
>      if (previn)
>          previn->next = NULL;
> +
> +    avpriv_register_devices(outdev_list, indev_list);
>  }
>  
>  void avdevice_register_all(void)
> @@ -115,9 +117,11 @@ void avdevice_register_all(void)
>  static void *device_next(void *prev, int output,
>                           AVClassCategory c1, AVClassCategory c2)
>  {
> -    pthread_once(&av_device_next_init, av_device_init_next);
>      const AVClass *pc;
>      AVClassCategory category = AV_CLASS_CATEGORY_NA;
> +
> +    pthread_once(&av_device_next_init, av_device_init_next);
> +
>      if (!prev && !(prev = (output ? (void*)outdev_list[0] : (void*)indev_list[0])))
>          return NULL;
>  
> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> index fa72acd..52b7088 100644
> --- a/libavformat/allformats.c
> +++ b/libavformat/allformats.c
> @@ -20,6 +20,7 @@
>   */
>  
>  #include "libavutil/thread.h"
> +#include "libavdevice/avdevice.h"
>  #include "avformat.h"
>  #include "rtp.h"
>  #include "rdt.h"
> @@ -482,6 +483,7 @@ const AVOutputFormat *av_muxer_iterate(void **opaque)
>  {
>      uintptr_t i = (uintptr_t)*opaque;
>      const AVOutputFormat *f = muxer_list[i];
> +
>      if (f)
>          *opaque = (void*)(i + 1);
>      return f;
> @@ -499,45 +501,77 @@ const AVInputFormat *av_demuxer_iterate(void **opaque){
>  #if FF_API_NEXT
>  pthread_once_t av_format_next_init = PTHREAD_ONCE_INIT;
>  
> +static AVInputFormat **indev_list = NULL;
> +static AVOutputFormat **outdev_list = NULL;
> +
>  static void av_format_init_next(void)
>  {
>      AVOutputFormat *prevout = NULL, *out;
>      AVInputFormat *previn = NULL, *in;
>      void *i = 0;
> -    while ((out = (AVOutputFormat*)av_muxer_iterate(&i))) {
> +
> +    for (i = 0; (out = (AVOutputFormat*)av_muxer_iterate(&i));) {
>          if (prevout)
>              prevout->next = out;
>          prevout = out;
>      }
> +
> +    if (outdev_list) {
> +        for (i = 0; (out = (AVOutputFormat*)outdev_list[(int)i]); i = (void*)(i + 1)) {
> +            if (prevout)
> +                prevout->next = out;
> +            prevout = out;
> +        }
> +    }
> +
>      if (prevout)
>          prevout->next = NULL;
>  
> -    i = 0;
> -    while ((in = (AVInputFormat*)av_demuxer_iterate(&i))) {
> +    for (i = 0; (in = (AVInputFormat*)av_demuxer_iterate(&i));) {
>          if (previn)
>              previn->next = in;
>          previn = in;
>      }
> +
> +    if (indev_list) {
> +        for (i = 0; (in = (AVInputFormat*)indev_list[(int)i]); i = (void*)(i + 1)) {
> +            if (previn)
> +                previn->next = in;
> +            previn = in;
> +        }
> +    }
> +
>      if (previn)
>          previn->next = NULL;
>  }
>  
> +void avpriv_register_devices(AVOutputFormat *o[], AVInputFormat *i[])
> +{
> +    outdev_list = o;
> +    indev_list = i;
> +    av_format_init_next();
> +}
> +
>  AVInputFormat *av_iformat_next(const AVInputFormat *f)
>  {
> +    void *i = 0;
>      pthread_once(&av_format_next_init, av_format_init_next);
>      if (f)
>          return f->next;
>      else
> -        return demuxer_list[0];
> +    /* If there are no demuxers but input devices, then return the first input device.
> +     * This will still return null if both there are both no demuxers or input devices. */
> +        return demuxer_list[0] ? (AVInputFormat*)demuxer_list[0] : (AVInputFormat*)av_indev_iterate(&i);
>  }
>  
>  AVOutputFormat *av_oformat_next(const AVOutputFormat *f)
>  {
> +    void *i = 0;
>      pthread_once(&av_format_next_init, av_format_init_next);
>      if (f)
>          return f->next;
>      else
> -        return muxer_list[0];
> +        return muxer_list[0] ? (AVOutputFormat*)muxer_list[0] : (AVOutputFormat*)av_outdev_iterate(&i);
>  }
>  
>  void av_register_all(void)
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index d38ca4e..56ec41a 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2014,6 +2014,10 @@ int avformat_network_deinit(void);
>  
>  #if FF_API_NEXT
>  /**
> +  * Register devices in deprecated format linked list.
> +  */
> +void avpriv_register_devices(AVOutputFormat *o[], AVInputFormat *i[]);
> +/**
>   * If f is NULL, returns the first registered input format,
>   * if f is non-NULL, returns the next registered input format after f
>   * or NULL if f is the last one.


I find this strange. It looks like av_iformat_next() includes
the libavdevice list, but av_muxer_iterate() does not. Is this
intended? Does using "-f" to force a muxer/demuxer on the ffmpeg.c
command line still work?

Also avpriv_register_devices() doesn't look very thread safe. You
probably want to use the libavformat mutex to protect that.

Are patches to update ffmpeg.c still missing? I think these would
unfortunately have to be done before we apply this, just to be sure
everything works.

Haven't really looked at the configure changes in all those patches.
diff mbox

Patch

diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index 6b2a512..041eb85 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -105,6 +105,8 @@  static void av_device_init_next(void)
     }
     if (previn)
         previn->next = NULL;
+
+    avpriv_register_devices(outdev_list, indev_list);
 }
 
 void avdevice_register_all(void)
@@ -115,9 +117,11 @@  void avdevice_register_all(void)
 static void *device_next(void *prev, int output,
                          AVClassCategory c1, AVClassCategory c2)
 {
-    pthread_once(&av_device_next_init, av_device_init_next);
     const AVClass *pc;
     AVClassCategory category = AV_CLASS_CATEGORY_NA;
+
+    pthread_once(&av_device_next_init, av_device_init_next);
+
     if (!prev && !(prev = (output ? (void*)outdev_list[0] : (void*)indev_list[0])))
         return NULL;
 
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index fa72acd..52b7088 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -20,6 +20,7 @@ 
  */
 
 #include "libavutil/thread.h"
+#include "libavdevice/avdevice.h"
 #include "avformat.h"
 #include "rtp.h"
 #include "rdt.h"
@@ -482,6 +483,7 @@  const AVOutputFormat *av_muxer_iterate(void **opaque)
 {
     uintptr_t i = (uintptr_t)*opaque;
     const AVOutputFormat *f = muxer_list[i];
+
     if (f)
         *opaque = (void*)(i + 1);
     return f;
@@ -499,45 +501,77 @@  const AVInputFormat *av_demuxer_iterate(void **opaque){
 #if FF_API_NEXT
 pthread_once_t av_format_next_init = PTHREAD_ONCE_INIT;
 
+static AVInputFormat **indev_list = NULL;
+static AVOutputFormat **outdev_list = NULL;
+
 static void av_format_init_next(void)
 {
     AVOutputFormat *prevout = NULL, *out;
     AVInputFormat *previn = NULL, *in;
     void *i = 0;
-    while ((out = (AVOutputFormat*)av_muxer_iterate(&i))) {
+
+    for (i = 0; (out = (AVOutputFormat*)av_muxer_iterate(&i));) {
         if (prevout)
             prevout->next = out;
         prevout = out;
     }
+
+    if (outdev_list) {
+        for (i = 0; (out = (AVOutputFormat*)outdev_list[(int)i]); i = (void*)(i + 1)) {
+            if (prevout)
+                prevout->next = out;
+            prevout = out;
+        }
+    }
+
     if (prevout)
         prevout->next = NULL;
 
-    i = 0;
-    while ((in = (AVInputFormat*)av_demuxer_iterate(&i))) {
+    for (i = 0; (in = (AVInputFormat*)av_demuxer_iterate(&i));) {
         if (previn)
             previn->next = in;
         previn = in;
     }
+
+    if (indev_list) {
+        for (i = 0; (in = (AVInputFormat*)indev_list[(int)i]); i = (void*)(i + 1)) {
+            if (previn)
+                previn->next = in;
+            previn = in;
+        }
+    }
+
     if (previn)
         previn->next = NULL;
 }
 
+void avpriv_register_devices(AVOutputFormat *o[], AVInputFormat *i[])
+{
+    outdev_list = o;
+    indev_list = i;
+    av_format_init_next();
+}
+
 AVInputFormat *av_iformat_next(const AVInputFormat *f)
 {
+    void *i = 0;
     pthread_once(&av_format_next_init, av_format_init_next);
     if (f)
         return f->next;
     else
-        return demuxer_list[0];
+    /* If there are no demuxers but input devices, then return the first input device.
+     * This will still return null if both there are both no demuxers or input devices. */
+        return demuxer_list[0] ? (AVInputFormat*)demuxer_list[0] : (AVInputFormat*)av_indev_iterate(&i);
 }
 
 AVOutputFormat *av_oformat_next(const AVOutputFormat *f)
 {
+    void *i = 0;
     pthread_once(&av_format_next_init, av_format_init_next);
     if (f)
         return f->next;
     else
-        return muxer_list[0];
+        return muxer_list[0] ? (AVOutputFormat*)muxer_list[0] : (AVOutputFormat*)av_outdev_iterate(&i);
 }
 
 void av_register_all(void)
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index d38ca4e..56ec41a 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2014,6 +2014,10 @@  int avformat_network_deinit(void);
 
 #if FF_API_NEXT
 /**
+  * Register devices in deprecated format linked list.
+  */
+void avpriv_register_devices(AVOutputFormat *o[], AVInputFormat *i[]);
+/**
  * If f is NULL, returns the first registered input format,
  * if f is non-NULL, returns the next registered input format after f
  * or NULL if f is the last one.