Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Subject: [FFmpeg-devel] [PATCH 32/44] avformat/utils: Move matching stream specificiers to avformat.c
Date: Sat,  7 May 2022 13:28:18 +0200
Message-ID: <AS8PR01MB79440520713F28F53D0641B68FC49@AS8PR01MB7944.eurprd01.prod.exchangelabs.com> (raw)
In-Reply-To: <AS8PR01MB794467A492C922D9DA178B408FC59@AS8PR01MB7944.eurprd01.prod.exchangelabs.com>

It is not to call this with a muxer, so move it to avformat.c
and not demux_utils.c.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/avformat.c | 179 +++++++++++++++++++++++++++++++++++++++++
 libavformat/utils.c    | 179 -----------------------------------------
 2 files changed, 179 insertions(+), 179 deletions(-)

diff --git a/libavformat/avformat.c b/libavformat/avformat.c
index ac0e28a6a9..7fab0dd99d 100644
--- a/libavformat/avformat.c
+++ b/libavformat/avformat.c
@@ -21,9 +21,12 @@
 
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
+#include "libavutil/channel_layout.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/samplefmt.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/bsf.h"
 #include "libavcodec/packet_internal.h"
@@ -257,6 +260,182 @@ void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx)
     }
 }
 
+/**
+ * Matches a stream specifier (but ignores requested index).
+ *
+ * @param indexptr set to point to the requested stream index if there is one
+ *
+ * @return <0 on error
+ *         0  if st is NOT a matching stream
+ *         >0 if st is a matching stream
+ */
+static int match_stream_specifier(const AVFormatContext *s, const AVStream *st,
+                                  const char *spec, const char **indexptr,
+                                  const AVProgram **p)
+{
+    int match = 1;                      /* Stores if the specifier matches so far. */
+    while (*spec) {
+        if (*spec <= '9' && *spec >= '0') { /* opt:index */
+            if (indexptr)
+                *indexptr = spec;
+            return match;
+        } else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
+                   *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */
+            enum AVMediaType type;
+            int nopic = 0;
+
+            switch (*spec++) {
+            case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
+            case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
+            case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
+            case 'd': type = AVMEDIA_TYPE_DATA;       break;
+            case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
+            case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break;
+            default:  av_assert0(0);
+            }
+            if (*spec && *spec++ != ':')         /* If we are not at the end, then another specifier must follow. */
+                return AVERROR(EINVAL);
+
+            if (type != st->codecpar->codec_type)
+                match = 0;
+            if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+                match = 0;
+        } else if (*spec == 'p' && *(spec + 1) == ':') {
+            int prog_id;
+            int found = 0;
+            char *endptr;
+            spec += 2;
+            prog_id = strtol(spec, &endptr, 0);
+            /* Disallow empty id and make sure that if we are not at the end, then another specifier must follow. */
+            if (spec == endptr || (*endptr && *endptr++ != ':'))
+                return AVERROR(EINVAL);
+            spec = endptr;
+            if (match) {
+                for (unsigned i = 0; i < s->nb_programs; i++) {
+                    if (s->programs[i]->id != prog_id)
+                        continue;
+
+                    for (unsigned j = 0; j < s->programs[i]->nb_stream_indexes; j++) {
+                        if (st->index == s->programs[i]->stream_index[j]) {
+                            found = 1;
+                            if (p)
+                                *p = s->programs[i];
+                            i = s->nb_programs;
+                            break;
+                        }
+                    }
+                }
+            }
+            if (!found)
+                match = 0;
+        } else if (*spec == '#' ||
+                   (*spec == 'i' && *(spec + 1) == ':')) {
+            int stream_id;
+            char *endptr;
+            spec += 1 + (*spec == 'i');
+            stream_id = strtol(spec, &endptr, 0);
+            if (spec == endptr || *endptr)                /* Disallow empty id and make sure we are at the end. */
+                return AVERROR(EINVAL);
+            return match && (stream_id == st->id);
+        } else if (*spec == 'm' && *(spec + 1) == ':') {
+            const AVDictionaryEntry *tag;
+            char *key, *val;
+            int ret;
+
+            if (match) {
+                spec += 2;
+                val = strchr(spec, ':');
+
+                key = val ? av_strndup(spec, val - spec) : av_strdup(spec);
+                if (!key)
+                    return AVERROR(ENOMEM);
+
+                tag = av_dict_get(st->metadata, key, NULL, 0);
+                if (tag) {
+                    if (!val || !strcmp(tag->value, val + 1))
+                        ret = 1;
+                    else
+                        ret = 0;
+                } else
+                    ret = 0;
+
+                av_freep(&key);
+            }
+            return match && ret;
+        } else if (*spec == 'u' && *(spec + 1) == '\0') {
+            const AVCodecParameters *par = st->codecpar;
+            int val;
+            switch (par->codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+                val = par->sample_rate && par->ch_layout.nb_channels;
+                if (par->format == AV_SAMPLE_FMT_NONE)
+                    return 0;
+                break;
+            case AVMEDIA_TYPE_VIDEO:
+                val = par->width && par->height;
+                if (par->format == AV_PIX_FMT_NONE)
+                    return 0;
+                break;
+            case AVMEDIA_TYPE_UNKNOWN:
+                val = 0;
+                break;
+            default:
+                val = 1;
+                break;
+            }
+            return match && (par->codec_id != AV_CODEC_ID_NONE && val != 0);
+        } else {
+            return AVERROR(EINVAL);
+        }
+    }
+
+    return match;
+}
+
+int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
+                                    const char *spec)
+{
+    int ret, index;
+    char *endptr;
+    const char *indexptr = NULL;
+    const AVProgram *p = NULL;
+    int nb_streams;
+
+    ret = match_stream_specifier(s, st, spec, &indexptr, &p);
+    if (ret < 0)
+        goto error;
+
+    if (!indexptr)
+        return ret;
+
+    index = strtol(indexptr, &endptr, 0);
+    if (*endptr) {                  /* We can't have anything after the requested index. */
+        ret = AVERROR(EINVAL);
+        goto error;
+    }
+
+    /* This is not really needed but saves us a loop for simple stream index specifiers. */
+    if (spec == indexptr)
+        return (index == st->index);
+
+    /* If we requested a matching stream index, we have to ensure st is that. */
+    nb_streams = p ? p->nb_stream_indexes : s->nb_streams;
+    for (int i = 0; i < nb_streams && index >= 0; i++) {
+        const AVStream *candidate = s->streams[p ? p->stream_index[i] : i];
+        ret = match_stream_specifier(s, candidate, spec, NULL, NULL);
+        if (ret < 0)
+            goto error;
+        if (ret > 0 && index-- == 0 && st == candidate)
+            return 1;
+    }
+    return 0;
+
+error:
+    if (ret == AVERROR(EINVAL))
+        av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
+    return ret;
+}
+
 int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt,
                                                   AVStream *ost, const AVStream *ist,
                                                   enum AVTimebaseSource copy_tb)
diff --git a/libavformat/utils.c b/libavformat/utils.c
index f5d24e7a3a..ebee44f47d 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -26,9 +26,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
-#include "libavutil/dict.h"
 #include "libavutil/internal.h"
-#include "libavutil/pixfmt.h"
 #include "libavutil/thread.h"
 #include "libavutil/time.h"
 
@@ -855,183 +853,6 @@ AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *f
     return fr;
 }
 
-/**
- * Matches a stream specifier (but ignores requested index).
- *
- * @param indexptr set to point to the requested stream index if there is one
- *
- * @return <0 on error
- *         0  if st is NOT a matching stream
- *         >0 if st is a matching stream
- */
-static int match_stream_specifier(const AVFormatContext *s, const AVStream *st,
-                                  const char *spec, const char **indexptr,
-                                  const AVProgram **p)
-{
-    int match = 1;                      /* Stores if the specifier matches so far. */
-    while (*spec) {
-        if (*spec <= '9' && *spec >= '0') { /* opt:index */
-            if (indexptr)
-                *indexptr = spec;
-            return match;
-        } else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
-                   *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */
-            enum AVMediaType type;
-            int nopic = 0;
-
-            switch (*spec++) {
-            case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
-            case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
-            case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
-            case 'd': type = AVMEDIA_TYPE_DATA;       break;
-            case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
-            case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break;
-            default:  av_assert0(0);
-            }
-            if (*spec && *spec++ != ':')         /* If we are not at the end, then another specifier must follow. */
-                return AVERROR(EINVAL);
-
-            if (type != st->codecpar->codec_type)
-                match = 0;
-            if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
-                match = 0;
-        } else if (*spec == 'p' && *(spec + 1) == ':') {
-            int prog_id;
-            int found = 0;
-            char *endptr;
-            spec += 2;
-            prog_id = strtol(spec, &endptr, 0);
-            /* Disallow empty id and make sure that if we are not at the end, then another specifier must follow. */
-            if (spec == endptr || (*endptr && *endptr++ != ':'))
-                return AVERROR(EINVAL);
-            spec = endptr;
-            if (match) {
-                for (unsigned i = 0; i < s->nb_programs; i++) {
-                    if (s->programs[i]->id != prog_id)
-                        continue;
-
-                    for (unsigned j = 0; j < s->programs[i]->nb_stream_indexes; j++) {
-                        if (st->index == s->programs[i]->stream_index[j]) {
-                            found = 1;
-                            if (p)
-                                *p = s->programs[i];
-                            i = s->nb_programs;
-                            break;
-                        }
-                    }
-                }
-            }
-            if (!found)
-                match = 0;
-        } else if (*spec == '#' ||
-                   (*spec == 'i' && *(spec + 1) == ':')) {
-            int stream_id;
-            char *endptr;
-            spec += 1 + (*spec == 'i');
-            stream_id = strtol(spec, &endptr, 0);
-            if (spec == endptr || *endptr)                /* Disallow empty id and make sure we are at the end. */
-                return AVERROR(EINVAL);
-            return match && (stream_id == st->id);
-        } else if (*spec == 'm' && *(spec + 1) == ':') {
-            const AVDictionaryEntry *tag;
-            char *key, *val;
-            int ret;
-
-            if (match) {
-                spec += 2;
-                val = strchr(spec, ':');
-
-                key = val ? av_strndup(spec, val - spec) : av_strdup(spec);
-                if (!key)
-                    return AVERROR(ENOMEM);
-
-                tag = av_dict_get(st->metadata, key, NULL, 0);
-                if (tag) {
-                    if (!val || !strcmp(tag->value, val + 1))
-                        ret = 1;
-                    else
-                        ret = 0;
-                } else
-                    ret = 0;
-
-                av_freep(&key);
-            }
-            return match && ret;
-        } else if (*spec == 'u' && *(spec + 1) == '\0') {
-            const AVCodecParameters *par = st->codecpar;
-            int val;
-            switch (par->codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-                val = par->sample_rate && par->ch_layout.nb_channels;
-                if (par->format == AV_SAMPLE_FMT_NONE)
-                    return 0;
-                break;
-            case AVMEDIA_TYPE_VIDEO:
-                val = par->width && par->height;
-                if (par->format == AV_PIX_FMT_NONE)
-                    return 0;
-                break;
-            case AVMEDIA_TYPE_UNKNOWN:
-                val = 0;
-                break;
-            default:
-                val = 1;
-                break;
-            }
-            return match && (par->codec_id != AV_CODEC_ID_NONE && val != 0);
-        } else {
-            return AVERROR(EINVAL);
-        }
-    }
-
-    return match;
-}
-
-
-int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
-                                    const char *spec)
-{
-    int ret, index;
-    char *endptr;
-    const char *indexptr = NULL;
-    const AVProgram *p = NULL;
-    int nb_streams;
-
-    ret = match_stream_specifier(s, st, spec, &indexptr, &p);
-    if (ret < 0)
-        goto error;
-
-    if (!indexptr)
-        return ret;
-
-    index = strtol(indexptr, &endptr, 0);
-    if (*endptr) {                  /* We can't have anything after the requested index. */
-        ret = AVERROR(EINVAL);
-        goto error;
-    }
-
-    /* This is not really needed but saves us a loop for simple stream index specifiers. */
-    if (spec == indexptr)
-        return (index == st->index);
-
-    /* If we requested a matching stream index, we have to ensure st is that. */
-    nb_streams = p ? p->nb_stream_indexes : s->nb_streams;
-    for (int i = 0; i < nb_streams && index >= 0; i++) {
-        const AVStream *candidate = s->streams[p ? p->stream_index[i] : i];
-        ret = match_stream_specifier(s, candidate, spec, NULL, NULL);
-        if (ret < 0)
-            goto error;
-        if (ret > 0 && index-- == 0 && st == candidate)
-            return 1;
-    }
-    return 0;
-
-error:
-    if (ret == AVERROR(EINVAL))
-        av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
-    return ret;
-}
-
 void ff_format_io_close_default(AVFormatContext *s, AVIOContext *pb)
 {
     avio_close(pb);
-- 
2.32.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2022-05-07 11:34 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-06 10:31 [FFmpeg-devel] [PATCH] lib*/version: Move library version functions into files of their own Andreas Rheinhardt
2022-05-06 11:09 ` Martin Storsjö
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 02/44] avformat/utils: Use av_realloc_array for reallocating array Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 03/44] avformat/internal: Move muxing-only functions to new mux.h header Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 04/44] avformat/mux: Move ff_choose_timebase to nutenc, its only user Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 05/44] avformat/mux: Move ff_choose_chroma_location to mxfenc, " Andreas Rheinhardt
2022-05-10  7:25   ` Tomas Härdin
2022-05-10  7:29     ` Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 06/44] avformat/utils: Move ff_stream_add_bitstream_filter to mux.c Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 07/44] avformat/utils: Move stream_options, avformat_new_stream to options.c Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 08/44] avformat/mux_utils: Move ff_format_shift_data to new file for mux utils Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 09/44] avformat/utils: Move ff_get_packet_palette() to rawutils.c Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 10/44] avformat/utils: Move creation-time functions to mux_utils Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 11/44] avformat/utils: Move ff_format_output_open() to mux_utils.c Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 12/44] avformat/utils: Move avformat_query_codec() " Andreas Rheinhardt
2022-05-07 11:27 ` [FFmpeg-devel] [PATCH 13/44] avformat/utils: Move av_stream_get_end_pts() " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 14/44] avformat/utils: Move ff_stream_encode_params_copy() " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 15/44] avformat/demux: Add new demux.h header Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 16/44] avformat/internal: Move definition of FFStream->info to demux.h Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 17/44] avformat/utils: Move parser functions to a new file, demux_utils.c Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 18/44] avdevice/v4l2*: Improve included headers Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 19/44] avformat/utils: Move avpriv_new_chapter to demux_utils.c Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 20/44] avformat/utils: Move av_format_inject_global_side_data " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 21/44] avformat/utils: Move avformat_queue_attached_pictures " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 22/44] avformat/utils: Move ff_add_attached_pic " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 23/44] avformat/utils: Move ff_add_param_change " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 24/44] avformat/utils: Move av_read_(play|pause) " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 25/44] avformat/utils: Move ff_generate_avci_extradata " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 26/44] avformat/internal: Make AVFormatContext* a logctx in ff_get_extradata Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 27/44] avformat/utils: Move ff_get_extradata to demux_utils.c Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 28/44] avformat/utils: Move freeing AVFormatContext to a new file avformat.c Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 29/44] avformat/utils: Move av_stream_*_side_data API to avformat.c Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 30/44] avformat/utils: Move adding AVProgram " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 31/44] avformat/utils: Move internal stream timebase stuff " Andreas Rheinhardt
2022-05-07 11:28 ` Andreas Rheinhardt [this message]
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 33/44] avformat/utils: Move guessing frame rate/SAR " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 34/44] avformat/utils: Move av_find_program_from_stream " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 35/44] avformat/utils: Move av_find_default_stream_index " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 36/44] avformat/utils: Move av_find_best_stream " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 37/44] avformat/asf: Move ASF GUIDs to a new file Andreas Rheinhardt
2022-05-07 11:59   ` [FFmpeg-devel] [PATCH v2 " Andreas Rheinhardt
2022-05-07 12:23     ` Soft Works
2022-05-07 12:28       ` Andreas Rheinhardt
2022-05-07 12:52         ` Soft Works
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 38/44] avformat/utils: Move ff_find_stream_index to demux_utils.c Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 39/44] avformat/utils: Move ff_is_intra_only to avformat.c Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 40/44] avformat/utils: Move ff_format_set_url " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 41/44] avformat/utils: Move ff_copy_whiteblacklists " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 42/44] avformat/utils: Move avpriv_set_pts_info() " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 43/44] avformat/utils: Move ff_stream_side_data_copy " Andreas Rheinhardt
2022-05-07 11:28 ` [FFmpeg-devel] [PATCH 44/44] avformat/utils: Move ff_format_io_close.* to options.c, avformat.c Andreas Rheinhardt
2022-05-09 19:14 ` [FFmpeg-devel] [PATCH] lib*/version: Move library version functions into files of their own Andreas Rheinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AS8PR01MB79440520713F28F53D0641B68FC49@AS8PR01MB7944.eurprd01.prod.exchangelabs.com \
    --to=andreas.rheinhardt@outlook.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git