Re: [FFmpeg-devel] [PATCH] avformat/oggparsevorbis: Update end_trimming for the last packet

2021-07-06 Thread Lynne
6 Jul 2021, 08:02 by sunguangy...@gmail.com:

> On Mon, Jun 21, 2021 at 9:06 AM Guangyu Sun  wrote:
>
>>
>> From: Guangyu Sun 
>>
>> Without end_trimming, the last packet will contain unexpected samples used
>> for padding.
>>
>> This commit partially fixes #6367 when the audio length is long enough.
>>
>> dd if=/dev/zero of=./silence.raw count=20 bs=500
>> oggenc --raw silence.raw --output=silence.ogg
>> oggdec --raw --output silence.oggdec.raw silence.ogg
>> ffmpeg -codec:a libvorbis -i silence.ogg -f s16le -codec:a pcm_s16le 
>> silence.libvorbis.ffmpeg.raw
>> ffmpeg -i silence.ogg -f s16le -codec:a pcm_s16le silence.native.ffmpeg.raw
>> ls -l *.raw
>>
>> The original test case in #6367 is still not fixed due to a remaining issue.
>>
>> The remaining issue is that ogg_stream->private is not kept during
>> ogg_save()/ogg_restore(). Field final_duration in the private data is
>> important to calculate end_trimming.
>>
>> Some common operations such as avformat_open_input() and
>> avformat_find_stream_info() before reading packet will trigger ogg_save()
>> and ogg_restore().
>>
>> Luckily, final_duration will not get updated until the last ogg page. The
>> save/restore mentioned above will not change final_duration most of the
>> time. But if the audio length is short, those reads may be performed on
>> the last ogg page, causing trouble keeping the correct value of
>> final_duration. We probably need a more complicated patch to address this
>> issue.
>>
>> Signed-off-by: Guangyu Sun 
>> ---
>>  libavformat/oggparsevorbis.c | 6 +-
>>  1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
>> index 0e8c25c030..c48658ceda 100644
>> --- a/libavformat/oggparsevorbis.c
>> +++ b/libavformat/oggparsevorbis.c
>> @@ -492,8 +492,12 @@ static int vorbis_packet(AVFormatContext *s, int idx)
>>  priv->final_pts  = os->lastpts;
>>  priv->final_duration = 0;
>>  }
>> -if (os->segp == os->nsegs)
>> +if (os->segp == os->nsegs) {
>> +int64_t skip = priv->final_pts + priv->final_duration + 
>> os->pduration - os->granule;
>> +if (skip > 0)
>> +os->end_trimming = skip;
>>  os->pduration = os->granule - priv->final_pts - priv->final_duration;
>> +}
>>  priv->final_duration += os->pduration;
>>  }
>>
>> --
>> 2.30.1
>>
>
> After fixing AV_PKT_DATA_SKIP_SAMPLES for reading vorbis packets from
> ogg, the actual decoded samples become fewer. As a result, three fate
> tests are failing:
>
> fate-vorbis-encode:
> This exposes another bug in the vorbis encoder that initial_padding is
> not set. I will fix that in a separate patch.
>
> fate-webm-dash-chapters:
> The original vorbis_chapter_extension_demo.ogg is transmuxed to
> dash-webm. The ref file webm-dash-chapters needs to be updated.
>
> fate-vorbis-20:
> The samples in 6.ogg are not frame aligned. 6.pcm file was generated
> by ffmpeg before the fix. After the fix, the decoded pcm file does not
> match anymore. The ref file 6.pcm needs to be updated.
>
> My question is that to fix fate-vorbis-20, a new file 6_v2.pcm needs
> to be uploaded to the fate suite server. How should I do that? The doc
> says it should be sent to samples-request but I am not sure if it is
> an email or something else.
>

Just put a link to it here and someone will upload it. Then a day will have
to pass to let all fate clients pull it before pushing the patch.
Patch looks good to me as-is, since it's just a copy of what Opus does.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


[FFmpeg-devel] [PATCH v3 02/34] avdevice/dshow: add use_video_device_timestamps to docs

2021-07-06 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 doc/indevs.texi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index b377924c2f..685b1357a6 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -611,6 +611,12 @@ Save the currently used video capture filter device and its
 parameters (if the filter supports it) to a file.
 If a file with the same name exists it will be overwritten.
 
+@item use_video_device_timestamps
+If set to @option{false}, the timestamp for video frames will be
+derived from the wallclock instead of the timestamp provided by
+the capture device. This allows working around devices that
+provide unreliable timestamps.
+
 @end table
 
 @subsection Examples
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 03/34] avdevice/dshow: query graph and sample time only once

2021-07-06 Thread Diederick Niehorster
No need to query twice, use value we've already unconditionally got.
Improve variable names

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow_pin.c | 28 
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c
index 8e56dccbfe..1d0e880480 100644
--- a/libavdevice/dshow_pin.c
+++ b/libavdevice/dshow_pin.c
@@ -295,9 +295,10 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 uint8_t *buf;
 int buf_size; /* todo should be a long? */
 int index;
-int64_t curtime;
-int64_t orig_curtime;
+int64_t chosentime;
+int64_t sampletime;
 int64_t graphtime;
+int use_sample_time = 1;
 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
 IReferenceClock *clock = pin->filter->clock;
 int64_t dummy;
@@ -313,24 +314,27 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 s = priv_data;
 ctx = s->priv_data;
 
-IMediaSample_GetTime(sample, &orig_curtime, &dummy);
-orig_curtime += pin->filter->start_time;
+IMediaSample_GetTime(sample, &sampletime, &dummy);
 IReferenceClock_GetTime(clock, &graphtime);
 if (devtype == VideoDevice && !ctx->use_video_device_timestamps) {
 /* PTS from video devices is unreliable. */
-IReferenceClock_GetTime(clock, &curtime);
+chosentime = graphtime;
+use_sample_time = 0;
 } else {
-IMediaSample_GetTime(sample, &curtime, &dummy);
-if(curtime > 40LL) {
+if (sampletime > 40LL) {
 /* initial frames sometimes start < 0 (shown as a very large 
number here,
-   like 437650244077016960 which FFmpeg doesn't like.
+   like 437650244077016960 which FFmpeg doesn't like).
TODO figure out math. For now just drop them. */
 av_log(NULL, AV_LOG_DEBUG,
-"dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", curtime);
+"dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", sampletime);
 return S_OK;
 }
-curtime += pin->filter->start_time;
+chosentime = sampletime;
 }
+// media sample time is relative to graph start time
+sampletime += pin->filter->start_time;
+if (use_sample_time)
+chosentime += pin->filter->start_time;
 
 buf_size = IMediaSample_GetActualDataLength(sample);
 IMediaSample_GetPointer(sample, &buf);
@@ -338,8 +342,8 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 
 av_log(NULL, AV_LOG_VERBOSE, "dshow passing through packet of type %s size 
%8d "
 "timestamp %"PRId64" orig timestamp %"PRId64" graph timestamp 
%"PRId64" diff %"PRId64" %s\n",
-devtypename, buf_size, curtime, orig_curtime, graphtime, graphtime - 
orig_curtime, ctx->device_name[devtype]);
-pin->filter->callback(priv_data, index, buf, buf_size, curtime, devtype);
+devtypename, buf_size, chosentime, sampletime, graphtime, graphtime - 
sampletime, ctx->device_name[devtype]);
+pin->filter->callback(priv_data, index, buf, buf_size, chosentime, 
devtype);
 
 return S_OK;
 }
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 04/34] avdevice/dshow: handle unknown sample time

2021-07-06 Thread Diederick Niehorster
GetTime may return an error indication that the sample has not
timestamps, or may return a NULL start time. In those cases, fall back
to graph time.
Better debug message in case sample dropped: could now be audio or
video frame

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow_pin.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c
index 1d0e880480..310f48c85e 100644
--- a/libavdevice/dshow_pin.c
+++ b/libavdevice/dshow_pin.c
@@ -295,14 +295,15 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 uint8_t *buf;
 int buf_size; /* todo should be a long? */
 int index;
-int64_t chosentime;
-int64_t sampletime;
-int64_t graphtime;
+int64_t chosentime = 0;
+int64_t sampletime = 0;
+int64_t graphtime = 0;
 int use_sample_time = 1;
 const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
 IReferenceClock *clock = pin->filter->clock;
 int64_t dummy;
 struct dshow_ctx *ctx;
+HRESULT hr;
 
 
 dshowdebug("ff_dshow_meminputpin_Receive(%p)\n", this);
@@ -314,22 +315,26 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 s = priv_data;
 ctx = s->priv_data;
 
-IMediaSample_GetTime(sample, &sampletime, &dummy);
+hr = IMediaSample_GetTime(sample, &sampletime, &dummy);
 IReferenceClock_GetTime(clock, &graphtime);
 if (devtype == VideoDevice && !ctx->use_video_device_timestamps) {
 /* PTS from video devices is unreliable. */
 chosentime = graphtime;
 use_sample_time = 0;
 } else {
-if (sampletime > 40LL) {
+if (hr == VFW_E_SAMPLE_TIME_NOT_SET || sampletime == 0) {
+chosentime = graphtime;
+use_sample_time = 0;
+}
+else if (sampletime > 40LL) {
 /* initial frames sometimes start < 0 (shown as a very large 
number here,
like 437650244077016960 which FFmpeg doesn't like).
TODO figure out math. For now just drop them. */
 av_log(NULL, AV_LOG_DEBUG,
 "dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", sampletime);
 return S_OK;
-}
-chosentime = sampletime;
+} else
+chosentime = sampletime;
 }
 // media sample time is relative to graph start time
 sampletime += pin->filter->start_time;
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 05/34] avdevice/dshow: set no-seek flags

2021-07-06 Thread Diederick Niehorster
avdevice/dshow is a realtime device and as such does not support
seeking. Therefore, its demuxer format should define the
AVFMT_NOBINSEARCH, AVFMT_NOGENSEARCH and AVFMT_NO_BYTE_SEEK flags.
With these flags set, attempting to seek (with, e.g.,
avformat_seek_file()) correctly yields -1 (operation not permitted)
instead of -22 (invalid argument).

This actually seems to apply to many other devices, at least the
gdigrab, v4l2, vfwcap, x11grab, fbdev, kmsgrab and android_camera
devices, from reading the source.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 2e9f9ddf3f..389daa6380 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1336,6 +1336,6 @@ const AVInputFormat ff_dshow_demuxer = {
 .read_header= dshow_read_header,
 .read_packet= dshow_read_packet,
 .read_close = dshow_read_close,
-.flags  = AVFMT_NOFILE,
+.flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | 
AVFMT_NO_BYTE_SEEK,
 .priv_class = &dshow_class,
 };
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 06/34] avdevice/dshow: implement get_device_list

2021-07-06 Thread Diederick Niehorster
Needed to enable programmatic discovery of DirectShow devices

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 80 +
 1 file changed, 73 insertions(+), 7 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 389daa6380..25de6b1acd 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -202,11 +202,14 @@ fail:
  * retrieve the device with type specified by devtype and return the
  * pointer to the object found in *pfilter.
  * If pfilter is NULL, list all device names.
+ * If device_list is not NULL, populate it with found devices instead of
+ * outputting device names to log
  */
 static int
 dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
 enum dshowDeviceType devtype, enum dshowSourceFilterType 
sourcetype,
-IBaseFilter **pfilter, char **device_unique_name)
+IBaseFilter **pfilter, char **device_unique_name,
+AVDeviceInfoList **device_list)
 {
 struct dshow_ctx *ctx = avctx->priv_data;
 IBaseFilter *device_filter = NULL;
@@ -238,6 +241,7 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 IBindCtx *bind_ctx = NULL;
 LPOLESTR olestr = NULL;
 LPMALLOC co_malloc = NULL;
+AVDeviceInfo *device = NULL;
 int i;
 
 r = CoGetMalloc(1, &co_malloc);
@@ -282,11 +286,39 @@ dshow_cycle_devices(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 // success, loop will end now
 }
 } else {
-av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
-av_log(avctx, AV_LOG_INFO, "Alternative name \"%s\"\n", 
unique_name);
+if (device_list) {
+device = av_mallocz(sizeof(AVDeviceInfo));
+if (!device)
+goto fail1;
+
+device->device_name = av_strdup(friendly_name);
+device->device_description = av_strdup(unique_name);
+if (!device->device_name || !device->device_description)
+goto fail1;
+
+// store to device_list output
+if (av_reallocp_array(&(*device_list)->devices,
+ (*device_list)->nb_devices + 1,
+ sizeof(*(*device_list)->devices)) < 0)
+goto fail1;
+(*device_list)->devices[(*device_list)->nb_devices] = device;
+(*device_list)->nb_devices++;
+device = NULL;  // copied into array, make sure not freed below
+}
+else {
+av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
+av_log(avctx, AV_LOG_INFO, "Alternative name \"%s\"\n", 
unique_name);
+}
 }
 
 fail1:
+if (device) {
+if (device->device_name)
+av_freep(&device->device_name);
+if (device->device_name)
+av_freep(&device->device_description);
+av_free(device);
+}
 if (olestr && co_malloc)
 IMalloc_Free(co_malloc, olestr);
 if (bind_ctx)
@@ -312,6 +344,39 @@ fail1:
 return 0;
 }
 
+static int dshow_get_device_list(AVFormatContext *avctx, AVDeviceInfoList 
*device_list)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+ICreateDevEnum *devenum = NULL;
+int r;
+int ret = AVERROR(EIO);
+
+if (!device_list)
+return AVERROR(EINVAL);
+
+CoInitialize(0);
+
+r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
+&IID_ICreateDevEnum, (void**)&devenum);
+if (r != S_OK) {
+av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
+goto error;
+}
+
+ret = dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, 
NULL, NULL, &device_list);
+if (ret < S_OK)
+goto error;
+ret = dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, 
NULL, NULL, &device_list);
+
+error:
+if (devenum)
+ICreateDevEnum_Release(devenum);
+
+CoUninitialize();
+
+return ret;
+}
+
 /**
  * Cycle through available formats using the specified pin,
  * try to set parameters specified through AVOptions and if successful
@@ -713,7 +778,7 @@ dshow_list_device_options(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 char *device_unique_name = NULL;
 int r;
 
-if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name)) < 0)
+if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name, NULL)) < 0)
 return r;
 ctx->device_filter[devtype] = device_filter;
 if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, 
NULL)) < 0)
@@ -773,7 +838,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 av

[FFmpeg-devel] [PATCH v3 07/34] avdevice/dshow: list_devices: show media type(s) per device

2021-07-06 Thread Diederick Niehorster
the list_devices option of dshow didn't indicate whether a specific
device provides audio or video output. This patch iterates through all
media formats of all pins exposed by the device to see what types it
provides for capture, and prints this to the console for each device.
Importantly, this now allows to find devices that provide both audio and
video, and devices that provide neither.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 103 +---
 1 file changed, 98 insertions(+), 5 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 25de6b1acd..8e693875c6 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -197,6 +197,79 @@ fail:
 return;
 }
 
+static void dshow_get_device_media_types(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
+ enum dshowSourceFilterType 
sourcetype, IBaseFilter *device_filter,
+ enum AVMediaType **media_types, int 
*nb_media_types)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+IEnumPins *pins = 0;
+IPin *pin;
+int has_audio = 0, has_video = 0;
+
+if (IBaseFilter_EnumPins(device_filter, &pins) != S_OK)
+return;
+
+while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
+IKsPropertySet *p = NULL;
+PIN_INFO info = { 0 };
+GUID category;
+DWORD r2;
+IEnumMediaTypes *types = NULL;
+AM_MEDIA_TYPE *type;
+
+if (IPin_QueryPinInfo(pin, &info) != S_OK)
+goto next;
+IBaseFilter_Release(info.pFilter);
+
+if (info.dir != PINDIR_OUTPUT)
+goto next;
+if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != 
S_OK)
+goto next;
+if (IKsPropertySet_Get(p, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
+   NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
+goto next;
+if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
+goto next;
+
+if (IPin_EnumMediaTypes(pin, &types) != S_OK)
+goto next;
+
+// enumerate media types exposed by pin
+// NB: don't know if a pin can expose both audio and video, check 'm 
all to be safe
+IEnumMediaTypes_Reset(types);
+while (IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
+if (IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) {
+has_video = 1;
+} else if (IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) {
+has_audio = 1;
+}
+CoTaskMemFree(type);
+}
+
+next:
+if (types)
+IEnumMediaTypes_Release(types);
+if (p)
+IKsPropertySet_Release(p);
+if (pin)
+IPin_Release(pin);
+}
+
+IEnumPins_Release(pins);
+
+if (has_audio || has_video) {
+int nb_types = has_audio + has_video;
+*media_types = av_malloc_array(nb_types, sizeof(enum AVMediaType));
+if (*media_types) {
+if (has_audio)
+(*media_types)[0] = AVMEDIA_TYPE_AUDIO;
+if (has_video)
+(*media_types)[0 + has_audio] = AVMEDIA_TYPE_VIDEO;
+*nb_media_types = nb_types;
+}
+}
+}
+
 /**
  * Cycle through available devices using the device enumerator devenum,
  * retrieve the device with type specified by devtype and return the
@@ -242,6 +315,8 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 LPOLESTR olestr = NULL;
 LPMALLOC co_malloc = NULL;
 AVDeviceInfo *device = NULL;
+enum AVMediaType *media_types = NULL;
+int nb_media_types = 0;
 int i;
 
 r = CoGetMalloc(1, &co_malloc);
@@ -286,6 +361,12 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 // success, loop will end now
 }
 } else {
+// get media types exposed by pins of device
+if (IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void* ) 
&device_filter) == S_OK) {
+dshow_get_device_media_types(avctx, devtype, sourcetype, 
device_filter, &media_types, &nb_media_types);
+IBaseFilter_Release(device_filter);
+device_filter = NULL;
+}
 if (device_list) {
 device = av_mallocz(sizeof(AVDeviceInfo));
 if (!device)
@@ -306,12 +387,26 @@ dshow_cycle_devices(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 device = NULL;  // copied into array, make sure not freed below
 }
 else {
-av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name);
-av_log(avctx, AV_LOG_INFO, "Alternative name \"%s\"\n", 
unique_name);
+av_log(avctx, AV_LOG_INFO, "\"%s\"", friendly_name);
+if (nb_media_types > 0 && media_types) {
+ 

[FFmpeg-devel] [PATCH v3 08/34] avdevice: add info about media types(s) to AVDeviceInfo

2021-07-06 Thread Diederick Niehorster
An avdevice, regardless of whether its category says its an audio or
video device, may provide access to devices providing different media
types, or even single devices providing multiple media types. Also, some
devices may provide no media types. dshow is an example encompassing all
of these cases. Users should be provided with this information, so
AVDeviceInfo is extended to provide it.

Bump avdevice version

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 2 ++
 libavdevice/avdevice.h | 2 ++
 libavdevice/version.h  | 2 +-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 22b7595ab1..4a40929007 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -158,6 +158,8 @@ void avdevice_free_list_devices(AVDeviceInfoList 
**device_list)
 if (dev) {
 av_freep(&dev->device_name);
 av_freep(&dev->device_description);
+if (dev->media_types)
+av_freep(&dev->media_types);
 av_free(dev);
 }
 }
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 8370bbc7f2..6f24976dcc 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -457,6 +457,8 @@ void avdevice_capabilities_free(AVDeviceCapabilitiesQuery 
**caps, AVFormatContex
 typedef struct AVDeviceInfo {
 char *device_name;   /**< device name, format depends on 
device */
 char *device_description;/**< human friendly name */
+enum AVMediaType *media_types;   /**< array indicating what media 
types(s), if any, a device can provide. If null, cannot provide any */
+int nb_media_types;  /**< length of media_types array, 0 
if device cannot provide any media types */
 } AVDeviceInfo;
 
 /**
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 6021a0dd65..6e593ba00e 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVDEVICE_VERSION_MAJOR  59
-#define LIBAVDEVICE_VERSION_MINOR   0
+#define LIBAVDEVICE_VERSION_MINOR   1
 #define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 09/34] avdevice/dshow: add media type info to get_device_list

2021-07-06 Thread Diederick Niehorster
The list returned by get_device_list now contains info about what media
type(s), if any, can be provided by each device.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 8e693875c6..dae0ae5d70 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -377,6 +377,11 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 if (!device->device_name || !device->device_description)
 goto fail1;
 
+device->nb_media_types = nb_media_types;
+device->media_types = media_types;
+nb_media_types = 0;
+media_types = NULL;
+
 // store to device_list output
 if (av_reallocp_array(&(*device_list)->devices,
  (*device_list)->nb_devices + 1,
@@ -412,6 +417,8 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 av_freep(&device->device_name);
 if (device->device_name)
 av_freep(&device->device_description);
+if (device->media_types)
+av_freep(&device->media_types);
 av_free(device);
 }
 if (olestr && co_malloc)
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 10/34] fftools: provide media type info for devices

2021-07-06 Thread Diederick Niehorster
fftools now print info about what media type(s), if any, are provided by
sink and source avdevices.

Signed-off-by: Diederick Niehorster 
---
 fftools/cmdutils.c | 34 --
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 4148285971..390dc77dab 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -2205,9 +2205,29 @@ double get_rotation(AVStream *st)
 }
 
 #if CONFIG_AVDEVICE
+static void print_device_list(const AVDeviceInfoList *device_list)
+{
+// print devices
+for (int i = 0; i < device_list->nb_devices; i++) {
+const AVDeviceInfo *device = device_list->devices[i];
+printf("%s %s [%s] (", device_list->default_device == i ? "*" : " ",
+device->device_name, device->device_description);
+if (device->nb_media_types > 0 && device->media_types) {
+for (int j = 0; j < device->nb_media_types; ++j) {
+const char* media_type = 
av_get_media_type_string(device->media_types[j]);
+if (j > 0)
+printf(", ");
+printf("%s", media_type ? media_type : "unknown");
+}
+} else {
+printf("none");
+}
+printf(")\n");
+}
+}
 static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts)
 {
-int ret, i;
+int ret;
 AVDeviceInfoList *device_list = NULL;
 
 if (!fmt || !fmt->priv_class  || 
!AV_IS_INPUT_DEVICE(fmt->priv_class->category))
@@ -2225,10 +2245,7 @@ static int print_device_sources(const AVInputFormat 
*fmt, AVDictionary *opts)
 goto fail;
 }
 
-for (i = 0; i < device_list->nb_devices; i++) {
-printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
-   device_list->devices[i]->device_name, 
device_list->devices[i]->device_description);
-}
+print_device_list(device_list);
 
   fail:
 avdevice_free_list_devices(&device_list);
@@ -2237,7 +2254,7 @@ static int print_device_sources(const AVInputFormat *fmt, 
AVDictionary *opts)
 
 static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts)
 {
-int ret, i;
+int ret;
 AVDeviceInfoList *device_list = NULL;
 
 if (!fmt || !fmt->priv_class  || 
!AV_IS_OUTPUT_DEVICE(fmt->priv_class->category))
@@ -2255,10 +2272,7 @@ static int print_device_sinks(const AVOutputFormat *fmt, 
AVDictionary *opts)
 goto fail;
 }
 
-for (i = 0; i < device_list->nb_devices; i++) {
-printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ",
-   device_list->devices[i]->device_name, 
device_list->devices[i]->device_description);
-}
+print_device_list(device_list);
 
   fail:
 avdevice_free_list_devices(&device_list);
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 11/34] avformat: add control_message function to AVInputFormat

2021-07-06 Thread Diederick Niehorster
Control messages are useful for programmatic control of not only outdevs
but also indevs.

Bumping avformat version.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 8 +---
 libavformat/avformat.h | 6 ++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 4a40929007..e339cebf2d 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -53,9 +53,11 @@ const char * avdevice_license(void)
 int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum 
AVAppToDevMessageType type,
 void *data, size_t data_size)
 {
-if (!s->oformat || !s->oformat->control_message)
-return AVERROR(ENOSYS);
-return s->oformat->control_message(s, type, data, data_size);
+if (s->oformat && s->oformat->control_message)
+return s->oformat->control_message(s, type, data, data_size);
+if (s->iformat && s->iformat->control_message)
+return s->iformat->control_message(s, type, data, data_size);
+return AVERROR(ENOSYS);
 }
 
 int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum 
AVDevToAppMessageType type,
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index cd7b0d941c..ed02b48c84 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -742,6 +742,12 @@ typedef struct AVInputFormat {
  */
 int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t 
min_ts, int64_t ts, int64_t max_ts, int flags);
 
+/**
+ * Allows sending messages from application to device.
+ */
+int (*control_message)(struct AVFormatContext *s, int type,
+   void *data, size_t data_size);
+
 /**
  * Returns device list with it properties.
  * @see avdevice_list_devices() for more details.
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 12/34] avdevice/dshow: implement control_message interface

2021-07-06 Thread Diederick Niehorster
This allows programmatic users of avdevice to start and stop the
DirectShow Capture graph (i.e. receive frames or not). This is important
because now the buffer fills up and starts dropping samples when
enqueued packets are not read out immediately after the demuxer is
opened.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 42 +
 libavdevice/dshow_capture.h |  1 +
 2 files changed, 43 insertions(+)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index dae0ae5d70..3793923acf 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1079,6 +1079,45 @@ error:
 return ret;
 }
 
+static int dshow_control_message(AVFormatContext *avctx, int type, void *data, 
size_t data_size)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+int run_state = ctx->is_running;
+HRESULT hr;
+
+switch (type) {
+case AV_APP_TO_DEV_PAUSE:
+run_state = 0;
+break;
+case AV_APP_TO_DEV_PLAY:
+run_state = 1;
+break;
+case AV_APP_TO_DEV_TOGGLE_PAUSE:
+run_state = !run_state;
+break;
+}
+
+// if play state change requested, apply
+if (run_state != ctx->is_running) {
+if (run_state)
+hr = IMediaControl_Run(ctx->control);
+else
+hr = IMediaControl_Pause(ctx->control);
+
+if (hr == S_FALSE) {
+OAFilterState pfs;
+hr = IMediaControl_GetState(ctx->control, 0, &pfs);
+}
+if (hr != S_OK) {
+av_log(avctx, AV_LOG_ERROR, "Could not run/pause graph\n");
+return AVERROR(EIO);
+}
+ctx->is_running = run_state;
+}
+
+return 0;
+}
+
 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
 {
 switch (sample_fmt) {
@@ -1317,6 +1356,7 @@ static int dshow_read_header(AVFormatContext *avctx)
 }
 }
 }
+ctx->is_running = 0;
 if (ctx->device_name[VideoDevice]) {
 if ((r = dshow_open_device(avctx, devenum, VideoDevice, 
VideoSourceDevice)) < 0 ||
 (r = dshow_add_device(avctx, VideoDevice)) < 0) {
@@ -1390,6 +1430,7 @@ static int dshow_read_header(AVFormatContext *avctx)
 av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by 
a device already in use by other application)\n");
 goto error;
 }
+ctx->is_running = 1;
 
 ret = 0;
 
@@ -1502,6 +1543,7 @@ const AVInputFormat ff_dshow_demuxer = {
 .read_packet= dshow_read_packet,
 .read_close = dshow_read_close,
 .get_device_list= dshow_get_device_list,
+.control_message = dshow_control_message,
 .flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | 
AVFMT_NO_BYTE_SEEK,
 .priv_class = &dshow_class,
 };
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
index 5a2691518c..bb0f76a8f2 100644
--- a/libavdevice/dshow_capture.h
+++ b/libavdevice/dshow_capture.h
@@ -331,6 +331,7 @@ struct dshow_ctx {
 
 IMediaControl *control;
 IMediaEvent *media_event;
+int is_running;
 
 enum AVPixelFormat pixel_format;
 enum AVCodecID video_codec_id;
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 13/34] avdevice: adding control message requesting to show config dialog

2021-07-06 Thread Diederick Niehorster
This control message can be used to programmatically ask a device to
show one of its configuration dialogs.

Adding documentation of this message's int argument.

Bumping avdevice version.

Signed-off-by: Diederick Niehorster 
---
 doc/indevs.texi| 34 ++
 libavdevice/avdevice.h | 10 ++
 libavdevice/version.h  |  2 +-
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 685b1357a6..970441ee06 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -668,6 +668,40 @@ $ ffmpeg -f dshow -show_video_device_dialog true 
-crossbar_video_input_pin_numbe
 
 @end itemize
 
+@subsection Libavdevice user notes
+
+The dshow device supports the @code{avdevice_app_to_dev_control_message}
+interface.
+
+It understands the @code{AV_APP_TO_DEV_PAUSE}, @code{AV_APP_TO_DEV_PLAY}
+and @code{AV_APP_TO_DEV_TOGGLE_PAUSE} commands, which respective stop and
+start whether data is captured from the connected device, and toggle
+capture state.
+
+It furthermore understands the @code{AV_APP_TO_DEV_CONFIG} message, which
+requests the device to show a configuration dialog (if available). An
+@code{int} should be passed along with this command to indicate which
+configuration dialog should be shown. The bits in this @code{int} have
+the following meaning:
+
+@itemize @bullet
+@item
+1st bit: If set, the dialog for the audio device will be shown. If not set
+the dialog for the video device will be shown.
+
+@item
+2nd bit: If set, show property dialog for the audio or video capture device,
+allowing to change audio or video filter properties and configurations
+manually.
+
+@item
+3rd bit: If set, show property dialog where crossbar pin routings of the
+audio/video device can be manually modified.
+
+@item
+4th bit: If set, show property dialog where TV channels and frequencies can be 
manually modified (in case of video device), or TV audio (like mono vs. stereo, 
Language A, B or C) can be manually modified in case of audio device.
+@end itemize
+
 @section fbdev
 
 Linux framebuffer input device.
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 6f24976dcc..bbeb1ae21b 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -190,6 +190,16 @@ enum AVAppToDevMessageType {
  */
 AV_APP_TO_DEV_GET_VOLUME = MKBETAG('G', 'V', 'O', 'L'),
 AV_APP_TO_DEV_GET_MUTE   = MKBETAG('G', 'M', 'U', 'T'),
+
+/**
+ * Request to show configuration dialog.
+ * 
+ * If device has a configuration dialog of type indicated by
+ * data, show it.
+ * 
+ * data: int (device-specific).
+ */
+AV_APP_TO_DEV_CONFIG = MKBETAG('C', 'O', 'N', 'F'),
 };
 
 /**
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 6e593ba00e..0381d6cd0d 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVDEVICE_VERSION_MAJOR  59
-#define LIBAVDEVICE_VERSION_MINOR   1
+#define LIBAVDEVICE_VERSION_MINOR   2
 #define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 14/34] avdevice/dshow: accept show config dialog control message

2021-07-06 Thread Diederick Niehorster
DirectShow source will pop up its configuration dialog when
AV_APP_TO_DEV_CONFIG is received. Implementation for several other
possible configuration dialogs is more involved and will be provided in
the next commit.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 3793923acf..e693770b3f 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1084,6 +1084,7 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 struct dshow_ctx *ctx = avctx->priv_data;
 int run_state = ctx->is_running;
 HRESULT hr;
+int ret = 0;
 
 switch (type) {
 case AV_APP_TO_DEV_PAUSE:
@@ -1095,6 +1096,32 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 case AV_APP_TO_DEV_TOGGLE_PAUSE:
 run_state = !run_state;
 break;
+case AV_APP_TO_DEV_CONFIG: {
+/* For documentation of dialog variable, see ffmpeg-devices.html in 
docs */
+int dialog;
+enum dshowDeviceType devtype;
+
+if (!data)
+av_log(avctx, AV_LOG_ERROR, "Use the data argument to indicate 
which dialog should be shown.");
+dialog = *(int *) data;
+devtype = (dialog & 1) ? AudioDevice : VideoDevice;
+
+if (dialog & 1<<1) {
+// device_dialog
+if (ctx->device_filter[devtype])
+ff_dshow_show_filter_properties(ctx->device_filter[devtype], 
avctx);
+} else if (dialog & 1<<2) {
+// crossbar_connection_dialog
+// TODO
+} else if (dialog & 1<<3) {
+// tv_tuner_dialog
+// TODO
+}
+break;
+}
+
+default:
+ret = AVERROR(ENOSYS);
 }
 
 // if play state change requested, apply
@@ -1115,7 +1142,7 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 ctx->is_running = run_state;
 }
 
-return 0;
+return ret;
 }
 
 static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 15/34] avdevice/dshow: tv_tuner_audio_dialog cleanup missing

2021-07-06 Thread Diederick Niehorster
Cleanup was missing for when the show_analog_tv_tuner_audio_dialog is
true.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow_crossbar.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavdevice/dshow_crossbar.c b/libavdevice/dshow_crossbar.c
index 2438683cde..961defe690 100644
--- a/libavdevice/dshow_crossbar.c
+++ b/libavdevice/dshow_crossbar.c
@@ -204,5 +204,9 @@ end:
 IAMTVTuner_Release(tv_tuner_filter);
 if (tv_tuner_base_filter)
 IBaseFilter_Release(tv_tuner_base_filter);
+if (tv_audio_filter)
+IAMAudioInputMixer_Release(tv_audio_filter);
+if (tv_audio_base_filter)
+IBaseFilter_Release(tv_audio_base_filter);
 return hr;
 }
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 16/34] avdevice/dshow: add config dialog command for crossbar and tv tuner

2021-07-06 Thread Diederick Niehorster
The "show config dialog" command message can now also trigger dialog
boxes for the crossbar connecting pins filter the analog tuner
audio / analog tuner filters.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c  | 51 ++--
 libavdevice/dshow_capture.h  | 10 
 libavdevice/dshow_crossbar.c | 91 +++-
 3 files changed, 114 insertions(+), 38 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index e693770b3f..61e14a4c82 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -60,6 +60,11 @@ dshow_read_close(AVFormatContext *s)
 struct dshow_ctx *ctx = s->priv_data;
 PacketList *pktl;
 
+if (ctx->graph_builder2[VideoDevice])
+ICaptureGraphBuilder2_Release(ctx->graph_builder2[VideoDevice]);
+if (ctx->graph_builder2[AudioDevice])
+ICaptureGraphBuilder2_Release(ctx->graph_builder2[AudioDevice]);
+
 if (ctx->control) {
 IMediaControl_Stop(ctx->control);
 IMediaControl_Release(ctx->control);
@@ -1040,6 +1045,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n");
 goto error;
 }
+ctx->graph_builder2[devtype] = graph_builder2;
 ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph);
 if (r != S_OK) {
 av_log(avctx, AV_LOG_ERROR, "Could not set graph for 
CaptureGraphBuilder2\n");
@@ -1064,9 +1070,6 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 ret = 0;
 
 error:
-if (graph_builder2 != NULL)
-ICaptureGraphBuilder2_Release(graph_builder2);
-
 if (pers_stream)
 IPersistStream_Release(pers_stream);
 
@@ -1112,10 +1115,48 @@ static int dshow_control_message(AVFormatContext 
*avctx, int type, void *data, s
 ff_dshow_show_filter_properties(ctx->device_filter[devtype], 
avctx);
 } else if (dialog & 1<<2) {
 // crossbar_connection_dialog
-// TODO
+if (ctx->device_filter[devtype] && ctx->graph_builder2[devtype]) {
+IAMCrossbar *cross_bar = NULL;
+IBaseFilter *cross_bar_base_filter = NULL;
+hr = 
ff_dshow_get_crossbar_and_filter(ctx->graph_builder2[devtype], 
ctx->device_filter[devtype], cross_bar, &cross_bar_base_filter);
+
+if (hr == S_OK && cross_bar_base_filter)
+ff_dshow_show_filter_properties(cross_bar_base_filter, 
avctx);
+
+if (cross_bar)
+IAMCrossbar_Release(cross_bar);
+if (cross_bar_base_filter)
+IBaseFilter_Release(cross_bar_base_filter);
+}
 } else if (dialog & 1<<3) {
 // tv_tuner_dialog
-// TODO
+if (ctx->device_filter[devtype] && ctx->graph_builder2[devtype]) {
+if (devtype == VideoDevice) {
+IAMTVTuner *tv_tuner_filter = NULL;
+IBaseFilter *tv_tuner_base_filter = NULL;
+hr = 
ff_dshow_get_tvtuner_and_filter(ctx->graph_builder2[devtype], 
ctx->device_filter[devtype], tv_tuner_filter, tv_tuner_base_filter);
+
+if (hr == S_OK && tv_tuner_base_filter)
+ff_dshow_show_filter_properties(tv_tuner_base_filter, 
avctx);
+
+if (tv_tuner_filter)
+IAMTVTuner_Release(tv_tuner_filter);
+if (tv_tuner_base_filter)
+IBaseFilter_Release(tv_tuner_base_filter);
+} else {
+IAMAudioInputMixer *tv_audio_filter = NULL;
+IBaseFilter *tv_audio_base_filter = NULL;
+hr = 
ff_dshow_get_audiomixer_and_filter(ctx->graph_builder2[devtype], 
ctx->device_filter[devtype], tv_audio_filter, tv_audio_base_filter);
+
+if (hr == S_OK && tv_audio_base_filter)
+ff_dshow_show_filter_properties(tv_audio_base_filter, 
avctx);
+
+if (tv_audio_filter)
+IAMAudioInputMixer_Release(tv_audio_filter);
+if (tv_audio_base_filter)
+IBaseFilter_Release(tv_audio_base_filter);
+}
+}
 }
 break;
 }
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
index bb0f76a8f2..127695a86b 100644
--- a/libavdevice/dshow_capture.h
+++ b/libavdevice/dshow_capture.h
@@ -318,6 +318,7 @@ struct dshow_ctx {
 IPin*device_pin[2];
 DShowFilter *capture_filter[2];
 DShowPin*capture_pin[2];
+ICaptureGraphBuilder2 *graph_builder2[2];
 
 HANDLE mutex;
 HANDLE event[2]; /* event[0] is set by DirectShow
@@ -352,6 +353,15 @@ struct dshow_ctx {
 HRESULT ff_dshow_try_setup_crossbar_options(ICaptureGraphBuilder2 
*graph_builder2,
 IBaseFilter *device_filter, enum dshowDeviceType devtype, AV

[FFmpeg-devel] [PATCH v3 17/34] avdevice/dshow: discover source color range/space/etc

2021-07-06 Thread Diederick Niehorster
Enabled discovering a DirectShow device's color range, space, primaries,
transfer characteristics and chroma location, if the device exposes that
information. Sets them in the stream's codecpars.

Co-authored-by: Valerii Zapodovnikov 
Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 255 +++-
 1 file changed, 254 insertions(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 61e14a4c82..d941107197 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -29,6 +29,31 @@
 #include "libavcodec/raw.h"
 #include "objidl.h"
 #include "shlwapi.h"
+// NB: technically, we should include dxva.h and use
+// DXVA_ExtendedFormat, but that type is not defined in
+// the MinGW headers. The DXVA2_ExtendedFormat and the
+// contents of its fields is identical to
+// DXVA_ExtendedFormat (see 
https://docs.microsoft.com/en-us/windows/win32/medfound/extended-color-information#color-space-in-media-types)
+// and is provided by MinGW as well, so we use that
+// instead. NB also that per the Microsoft docs, the
+// lowest 8 bits of the structure, i.e. the SampleFormat
+// field, contain AMCONTROL_xxx flags instead of sample
+// format information, and should thus not be used.
+// NB further that various values in the structure's
+// fields (e.g. BT.2020 color space) are not provided
+// for either of the DXVA structs, but are provided in
+// the flags of the corresponding fields of Media Foundation.
+// These may be provided by DirectShow devices (e.g. LAVFilters
+// does so). So we use those values here too (the equivalence is
+// indicated by Microsoft example code: 
https://docs.microsoft.com/en-us/windows/win32/api/dxva2api/ns-dxva2api-dxva2_videodesc)
+typedef DWORD D3DFORMAT;// dxva2api.h header needs these types defined 
before include apparently in WinSDK (not MinGW).
+typedef DWORD D3DPOOL;
+#include "dxva2api.h"
+
+#ifndef AMCONTROL_COLORINFO_PRESENT
+// not defined in some versions of MinGW's dvdmedia.h
+#   define AMCONTROL_COLORINFO_PRESENT 0x0080 // if set, indicates DXVA 
color info is present in the upper (24) bits of the dwControlFlags
+#endif
 
 
 static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, WORD biBitCount)
@@ -54,6 +79,192 @@ static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, 
WORD biBitCount)
 return avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), biCompression); 
// all others
 }
 
+static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info)
+{
+switch (fmt_info->NominalRange)
+{
+case DXVA2_NominalRange_Unknown:
+return AVCOL_RANGE_UNSPECIFIED;
+case DXVA2_NominalRange_Normal: // equal to DXVA2_NominalRange_0_255
+return AVCOL_RANGE_JPEG;
+case DXVA2_NominalRange_Wide:   // equal to DXVA2_NominalRange_16_235
+return AVCOL_RANGE_MPEG;
+case DXVA2_NominalRange_48_208:
+// not an ffmpeg color range
+return AVCOL_RANGE_UNSPECIFIED;
+
+// values from MediaFoundation SDK (mfobjects.h)
+case 4: // MFNominalRange_64_127
+// not an ffmpeg color range
+return AVCOL_RANGE_UNSPECIFIED;
+
+default:
+return DXVA2_NominalRange_Unknown;
+}
+}
+
+static enum AVColorSpace dshow_color_space(DXVA2_ExtendedFormat *fmt_info)
+{
+enum AVColorSpace ret = AVCOL_SPC_UNSPECIFIED;
+
+switch (fmt_info->VideoTransferMatrix)
+{
+case DXVA2_VideoTransferMatrix_BT709:
+ret = AVCOL_SPC_BT709;
+break;
+case DXVA2_VideoTransferMatrix_BT601:
+ret = AVCOL_SPC_BT470BG;
+break;
+case DXVA2_VideoTransferMatrix_SMPTE240M:
+ret = AVCOL_SPC_SMPTE240M;
+break;
+
+// values from MediaFoundation SDK (mfobjects.h)
+case 4: // MFVideoTransferMatrix_BT2020_10
+case 5: // MFVideoTransferMatrix_BT2020_12
+if (fmt_info->VideoTransferFunction==12)// 
MFVideoTransFunc_2020_const
+ret = AVCOL_SPC_BT2020_CL;
+else
+ret = AVCOL_SPC_BT2020_NCL;
+break;
+}
+
+if (ret == AVCOL_SPC_UNSPECIFIED)
+{
+// if color space not known from transfer matrix,
+// fall back to using primaries to guess color space
+switch (fmt_info->VideoPrimaries)
+{
+case DXVA2_VideoPrimaries_BT709:
+ret = AVCOL_SPC_BT709;
+break;
+case DXVA2_VideoPrimaries_BT470_2_SysM:
+ret = AVCOL_SPC_FCC;
+break;
+case DXVA2_VideoPrimaries_BT470_2_SysBG:
+case DXVA2_VideoPrimaries_EBU3213:   // this is PAL
+ret = AVCOL_SPC_BT470BG;
+break;
+case DXVA2_VideoPrimaries_SMPTE170M:
+case DXVA2_VideoPrimaries_SMPTE_C:
+ret = AVCOL_SPC_SMPTE170M;
+break;
+case DXVA2_VideoPrimaries_SMPTE240M:
+ret = AVCOL_SPC_SMPTE240M;
+break;
+}
+}
+
+return ret;
+}
+
+static enum AVColorPrimaries dshow_color_prim

[FFmpeg-devel] [PATCH v3 18/34] avdevice/dshow: select format with extended color info

2021-07-06 Thread Diederick Niehorster
Some DirectShow devices (Logitech C920 webcam) expose each DirectShow
format they support twice, once without and once with extended color
information. During format selection, both match, this patch ensures
that the format with extended color information is selected if it is
available, else it falls back to a matching format without such
information. This also necessitated a new code path taken for default
formats of a device (when user didn't request any specific video size,
etc), because the default format may be one without extended color
information when a twin with extended color information is also
available. Getting the extended color information when available is
important as it allows setting the color space, range, primaries,
transfer characteristics and chroma location of the stream provided by
dshow, enabling users to get more correct color automatically out of
their device.

Closes: #9271

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 457 +++-
 1 file changed, 329 insertions(+), 128 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index d941107197..5b9f61926b 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -23,6 +23,7 @@
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/opt.h"
+#include "libavutil/mem.h"
 #include "libavformat/internal.h"
 #include "libavformat/riff.h"
 #include "avdevice.h"
@@ -695,9 +696,111 @@ error:
 return ret;
 }
 
+static int dshow_should_set_format(AVFormatContext *avctx, enum 
dshowDeviceType devtype)
+{
+struct dshow_ctx *ctx = avctx->priv_data;
+
+return (devtype == VideoDevice && (ctx->framerate ||
+  (ctx->requested_width && 
ctx->requested_height) ||
+   ctx->pixel_format != AV_PIX_FMT_NONE ||
+   ctx->video_codec_id != 
AV_CODEC_ID_RAWVIDEO))
+|| (devtype == AudioDevice && (ctx->channels || ctx->sample_size || 
ctx->sample_rate));
+}
+
+
+struct dshow_format_info {
+enum dshowDeviceType devtype;
+// video
+int64_t framerate;
+enum AVPixelFormat pix_fmt;
+enum AVCodecID codec_id;
+enum AVColorRange col_range;
+enum AVColorSpace col_space;
+enum AVColorPrimaries col_prim;
+enum AVColorTransferCharacteristic col_trc;
+enum AVChromaLocation chroma_loc;
+int width;
+int height;
+// audio
+int sample_rate;
+int sample_size;
+int channels;
+};
+
+// user must av_free the returned pointer
+static struct dshow_format_info *dshow_get_format_info(AM_MEDIA_TYPE *type)
+{
+struct dshow_format_info *fmt_info = NULL;
+BITMAPINFOHEADER *bih;
+DXVA2_ExtendedFormat *extended_format_info = NULL;
+WAVEFORMATEX *fx;
+enum dshowDeviceType devtype;
+int64_t framerate;
+
+if (!type)
+return NULL;
+
+if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
+VIDEOINFOHEADER *v = (void *) type->pbFormat;
+framerate = v->AvgTimePerFrame;
+bih   = &v->bmiHeader;
+devtype   = VideoDevice;
+} else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
+VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
+devtype   = VideoDevice;
+framerate = v->AvgTimePerFrame;
+bih   = &v->bmiHeader;
+if (v->dwControlFlags & AMCONTROL_COLORINFO_PRESENT)
+extended_format_info = (DXVA2_ExtendedFormat *) &v->dwControlFlags;
+} else if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
+fx = (void *) type->pbFormat;
+devtype = AudioDevice;
+} else {
+return NULL;
+}
+
+fmt_info = av_mallocz(sizeof(struct dshow_format_info));
+if (!fmt_info)
+return NULL;
+// initialize fields where unset is not zero
+fmt_info->pix_fmt = AV_PIX_FMT_NONE;
+fmt_info->col_space = AVCOL_SPC_UNSPECIFIED;
+fmt_info->col_prim = AVCOL_PRI_UNSPECIFIED;
+fmt_info->col_trc = AVCOL_TRC_UNSPECIFIED;
+// now get info about format
+fmt_info->devtype = devtype;
+if (devtype == VideoDevice) {
+fmt_info->width = bih->biWidth;
+fmt_info->height = bih->biHeight;
+fmt_info->framerate = framerate;
+fmt_info->pix_fmt = dshow_pixfmt(bih->biCompression, bih->biBitCount);
+if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
+const AVCodecTag *const tags[] = { avformat_get_riff_video_tags(), 
NULL };
+fmt_info->codec_id = av_codec_get_id(tags, bih->biCompression);
+}
+else
+fmt_info->codec_id = AV_CODEC_ID_RAWVIDEO;
+
+if (extended_format_info) {
+fmt_info->col_range = dshow_color_range(extended_format_info);
+fmt_info->col_space = dshow_color_space(extended_format_info);
+fmt_info->col_prim = dshow_color_primaries(extended_format_info);
+fmt_info->col_trc = dshow_color_trc(extended

[FFmpeg-devel] [PATCH v3 19/34] avdevice/avdevice: Revert "Deprecate AVDevice Capabilities API"

2021-07-06 Thread Diederick Niehorster
This reverts commit 4f49ca7bbc75a9db4cdf93f27f95a668c751f160. The next
few patches clean up the API and implement this capability for
avdevice/dshow.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 71 ++
 libavdevice/avdevice.h |  5 ---
 libavformat/avformat.h | 21 +
 3 files changed, 86 insertions(+), 11 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index e339cebf2d..695b9143af 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -27,11 +27,39 @@
 #include "libavutil/ffversion.h"
 const char av_device_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
 
-#if FF_API_DEVICE_CAPABILITIES
+#define E AV_OPT_FLAG_ENCODING_PARAM
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define V AV_OPT_FLAG_VIDEO_PARAM
+#define OFFSET(x) offsetof(AVDeviceCapabilitiesQuery, x)
+
 const AVOption av_device_capabilities[] = {
+{ "codec", "codec", OFFSET(codec), AV_OPT_TYPE_INT,
+{.i64 = AV_CODEC_ID_NONE}, AV_CODEC_ID_NONE, INT_MAX, E|D|A|V },
+{ "sample_format", "sample format", OFFSET(sample_format), 
AV_OPT_TYPE_SAMPLE_FMT,
+{.i64 = AV_SAMPLE_FMT_NONE}, AV_SAMPLE_FMT_NONE, INT_MAX, E|D|A },
+{ "sample_rate", "sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT,
+{.i64 = -1}, -1, INT_MAX, E|D|A },
+{ "channels", "channels", OFFSET(channels), AV_OPT_TYPE_INT,
+{.i64 = -1}, -1, INT_MAX, E|D|A },
+{ "channel_layout", "channel layout", OFFSET(channel_layout), 
AV_OPT_TYPE_CHANNEL_LAYOUT,
+{.i64 = -1}, -1, INT_MAX, E|D|A },
+{ "pixel_format", "pixel format", OFFSET(pixel_format), 
AV_OPT_TYPE_PIXEL_FMT,
+{.i64 = AV_PIX_FMT_NONE}, AV_PIX_FMT_NONE, INT_MAX, E|D|V },
+{ "window_size", "window size", OFFSET(window_width), 
AV_OPT_TYPE_IMAGE_SIZE,
+{.str = NULL}, -1, INT_MAX, E|D|V },
+{ "frame_size", "frame size", OFFSET(frame_width), AV_OPT_TYPE_IMAGE_SIZE,
+{.str = NULL}, -1, INT_MAX, E|D|V },
+{ "fps", "fps", OFFSET(fps), AV_OPT_TYPE_RATIONAL,
+{.dbl = -1}, -1, INT_MAX, E|D|V },
 { NULL }
 };
-#endif
+
+#undef E
+#undef D
+#undef A
+#undef V
+#undef OFFSET
 
 unsigned avdevice_version(void)
 {
@@ -68,18 +96,49 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s, enum AVDevToA
 return s->control_message_cb(s, type, data, data_size);
 }
 
-#if FF_API_DEVICE_CAPABILITIES
 int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, 
AVFormatContext *s,
  AVDictionary **device_options)
 {
-return AVERROR(ENOSYS);
+int ret;
+av_assert0(s && caps);
+av_assert0(s->iformat || s->oformat);
+if ((s->oformat && !s->oformat->create_device_capabilities) ||
+(s->iformat && !s->iformat->create_device_capabilities))
+return AVERROR(ENOSYS);
+*caps = av_mallocz(sizeof(**caps));
+if (!(*caps))
+return AVERROR(ENOMEM);
+(*caps)->device_context = s;
+if (((ret = av_opt_set_dict(s->priv_data, device_options)) < 0))
+goto fail;
+if (s->iformat) {
+if ((ret = s->iformat->create_device_capabilities(s, *caps)) < 0)
+goto fail;
+} else {
+if ((ret = s->oformat->create_device_capabilities(s, *caps)) < 0)
+goto fail;
+}
+av_opt_set_defaults(*caps);
+return 0;
+  fail:
+av_freep(caps);
+return ret;
 }
 
 void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, 
AVFormatContext *s)
 {
-return;
+if (!s || !caps || !(*caps))
+return;
+av_assert0(s->iformat || s->oformat);
+if (s->iformat) {
+if (s->iformat->free_device_capabilities)
+s->iformat->free_device_capabilities(s, *caps);
+} else {
+if (s->oformat->free_device_capabilities)
+s->oformat->free_device_capabilities(s, *caps);
+}
+av_freep(caps);
 }
-#endif
 
 int avdevice_list_devices(AVFormatContext *s, AVDeviceInfoList **device_list)
 {
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index bbeb1ae21b..6443f865d5 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -331,7 +331,6 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
 enum AVDevToAppMessageType type,
 void *data, size_t data_size);
 
-#if FF_API_DEVICE_CAPABILITIES
 /**
  * Following API allows user to probe device capabilities (supported codecs,
  * pixel formats, sample formats, resolutions, channel counts, etc).
@@ -427,7 +426,6 @@ typedef struct AVDeviceCapabilitiesQuery {
 /**
  * AVOption table used by devices to implement device capabilities API. Should 
not be used by a user.
  */
-attribute_deprecated
 extern const AVOption av_device_capabilities[];
 
 /**
@@ -447,7 +445,6 @@ extern const AVOption av_device_capabilities[];
  *
  * @return >= 0 on success, negative otherwise.
  */
-attribut

[FFmpeg-devel] [PATCH v3 20/34] avdevice/avdevice: clean up avdevice_capabilities_create

2021-07-06 Thread Diederick Niehorster
Draw implementation in line with that of avdevice_list_devices

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 695b9143af..e66906e91b 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -100,11 +100,14 @@ int 
avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatConte
  AVDictionary **device_options)
 {
 int ret;
-av_assert0(s && caps);
+av_assert0(s);
+av_assert0(caps);
 av_assert0(s->iformat || s->oformat);
 if ((s->oformat && !s->oformat->create_device_capabilities) ||
-(s->iformat && !s->iformat->create_device_capabilities))
+(s->iformat && !s->iformat->create_device_capabilities)) {
+*caps = NULL;
 return AVERROR(ENOSYS);
+}
 *caps = av_mallocz(sizeof(**caps));
 if (!(*caps))
 return AVERROR(ENOMEM);
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 21/34] avdevice: capabilities API details no longer public

2021-07-06 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c |  2 +-
 libavdevice/avdevice.h | 28 +---
 libavdevice/internal.h | 33 +
 libavdevice/version.h  |  2 +-
 4 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index e66906e91b..cb139e6d4a 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -33,7 +33,7 @@ const char av_device_ffversion[] = "FFmpeg version " 
FFMPEG_VERSION;
 #define V AV_OPT_FLAG_VIDEO_PARAM
 #define OFFSET(x) offsetof(AVDeviceCapabilitiesQuery, x)
 
-const AVOption av_device_capabilities[] = {
+const AVOption ff_device_capabilities[] = {
 { "codec", "codec", OFFSET(codec), AV_OPT_TYPE_INT,
 {.i64 = AV_CODEC_ID_NONE}, AV_CODEC_ID_NONE, INT_MAX, E|D|A|V },
 { "sample_format", "sample format", OFFSET(sample_format), 
AV_OPT_TYPE_SAMPLE_FMT,
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 6443f865d5..44c4f185a2 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -400,33 +400,7 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  *  avformat_free_context(oc);
  * @endcode
  */
-
-/**
- * Structure describes device capabilities.
- *
- * It is used by devices in conjunction with av_device_capabilities AVOption 
table
- * to implement capabilities probing API based on AVOption API. Should not be 
used directly.
- */
-typedef struct AVDeviceCapabilitiesQuery {
-const AVClass *av_class;
-AVFormatContext *device_context;
-enum AVCodecID codec;
-enum AVSampleFormat sample_format;
-enum AVPixelFormat pixel_format;
-int sample_rate;
-int channels;
-int64_t channel_layout;
-int window_width;
-int window_height;
-int frame_width;
-int frame_height;
-AVRational fps;
-} AVDeviceCapabilitiesQuery;
-
-/**
- * AVOption table used by devices to implement device capabilities API. Should 
not be used by a user.
- */
-extern const AVOption av_device_capabilities[];
+typedef struct AVDeviceCapabilitiesQuery AVDeviceCapabilitiesQuery;
 
 /**
  * Initialize capabilities probing API based on AVOption API.
diff --git a/libavdevice/internal.h b/libavdevice/internal.h
index 67c90e1f87..bef3a4bd2d 100644
--- a/libavdevice/internal.h
+++ b/libavdevice/internal.h
@@ -19,10 +19,43 @@
 #ifndef AVDEVICE_INTERNAL_H
 #define AVDEVICE_INTERNAL_H
 
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+#include "libavutil/samplefmt.h"
+#include "libavcodec/codec_id.h"
 #include "libavformat/avformat.h"
 
 av_warn_unused_result
 int ff_alloc_input_device_context(struct AVFormatContext **avctx, const 
AVInputFormat *iformat,
   const char *format);
 
+/**
+ * Structure describes device capabilities.
+ *
+ * It is used by devices in conjunction with ff_device_capabilities AVOption 
table
+ * to implement capabilities probing API based on AVOption API.
+ */
+struct AVDeviceCapabilitiesQuery {
+const AVClass *av_class;
+AVFormatContext *device_context;
+enum AVCodecID codec;
+enum AVSampleFormat sample_format;
+enum AVPixelFormat pixel_format;
+int sample_rate;
+int channels;
+int64_t channel_layout;
+int window_width;
+int window_height;
+int frame_width;
+int frame_height;
+AVRational fps;
+};
+
+/**
+ * AVOption table used by devices to implement device capabilities API.
+ */
+extern const AVOption ff_device_capabilities[];
+
 #endif
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 0381d6cd0d..53af6fa0d0 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -28,7 +28,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVDEVICE_VERSION_MAJOR  59
-#define LIBAVDEVICE_VERSION_MINOR   2
+#define LIBAVDEVICE_VERSION_MINOR   3
 #define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 22/34] avutil/opt: document AVOptionRange min_value > max_value

2021-07-06 Thread Diederick Niehorster
AVOptionRange needs a way to encode that an option is not set. Here i
provide a documentation solution. When a range is invalid (value_min >
value_max), it should be considered unset/value not available.

When querying a range of formats of an avdevice, sometimes for a given
format the queried option is not available. This is not an error as the
user is asking for a valid capability, it just doesn't always apply to
all the matching formats of the device. This cannot be communicated
through a single special value (like 0 or -1) as that has the same
problem asany special value solution. Documenting that an invalid range
means value not available allows communicating this situation without
adding a field to the AVOptionRange struct.

This further documents that an AVOptionRange denotes a single value when
value_min == value_max, and a range only when value_max > value_min.
This makes the is_range field superfluous.

Signed-off-by: Diederick Niehorster 
---
 libavutil/opt.c | 2 +-
 libavutil/opt.h | 5 +
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libavutil/opt.c b/libavutil/opt.c
index 41284d4ecd..edb2c2ca41 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -1865,9 +1865,9 @@ int av_opt_query_ranges_default(AVOptionRanges 
**ranges_arg, void *obj, const ch
 ranges->range[0] = range;
 ranges->nb_ranges = 1;
 ranges->nb_components = 1;
-range->is_range = 1;
 range->value_min = field->min;
 range->value_max = field->max;
+range->is_range = field->max > field->min;
 
 switch (field->type) {
 case AV_OPT_TYPE_BOOL:
diff --git a/libavutil/opt.h b/libavutil/opt.h
index c2329e5589..3c64e8d3a5 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -313,6 +313,11 @@ typedef struct AVOptionRange {
  * Value range.
  * For string ranges this represents the min/max length.
  * For dimensions this represents the min/max pixel count or width/height 
in multi-component case.
+ * If value_min  < value_max, the struct encodes a range.
+ * If value_min == value_max, the struct encodes a single value.
+ * If value_min  > value_max, the range is empty (a value is not 
available).
+ *Good sentinel values to use when a range is 
empty
+ *are value_min=0, value_max=-1, but this is 
not required.
  */
 double value_min, value_max;
 /**
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 23/34] avdevice: Add internal helpers for querying device capabilities

2021-07-06 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 libavdevice/internal.h | 31 +++
 libavdevice/utils.c| 48 ++
 libavdevice/version.h  |  2 +-
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/libavdevice/internal.h b/libavdevice/internal.h
index bef3a4bd2d..eee493a4c7 100644
--- a/libavdevice/internal.h
+++ b/libavdevice/internal.h
@@ -58,4 +58,35 @@ struct AVDeviceCapabilitiesQuery {
  */
 extern const AVOption ff_device_capabilities[];
 
+/**
+ * Enumeration indicating which device capability is being queried.
+ */
+enum AVDeviceCapabilitiesQueryType {
+AV_DEV_CAP_QUERY_NONE = 0,
+// both audio and video
+AV_DEV_CAP_QUERY_CODEC,
+// audio
+AV_DEV_CAP_QUERY_SAMPLE_FORMAT,
+AV_DEV_CAP_QUERY_SAMPLE_RATE,
+AV_DEV_CAP_QUERY_CHANNELS,
+AV_DEV_CAP_QUERY_CHANNEL_LAYOUT,
+// video
+AV_DEV_CAP_QUERY_PIXEL_FORMAT,
+AV_DEV_CAP_QUERY_WINDOW_SIZE,
+AV_DEV_CAP_QUERY_FRAME_SIZE,
+AV_DEV_CAP_QUERY_FPS
+};
+
+/**
+ * Find AVDeviceCapabilitiesQueryType enumeration by means of options name.
+ * Returns AV_DEV_CAP_QUERY_NONE if not found.
+ */
+enum AVDeviceCapabilitiesQueryType ff_device_get_query_type(const char* 
option_name);
+
+/**
+ * Get component name from AVDeviceCapabilitiesQueryType enumeration and 
component index.
+ * (Some options have multiple components, e.g. AV_DEV_CAP_QUERY_FRAME_SIZE).
+ */
+const char* ff_device_get_query_component_name(enum 
AVDeviceCapabilitiesQueryType query_type, int component);
+
 #endif
diff --git a/libavdevice/utils.c b/libavdevice/utils.c
index d9a52c53ab..de9023f215 100644
--- a/libavdevice/utils.c
+++ b/libavdevice/utils.c
@@ -19,6 +19,7 @@
 #include "internal.h"
 #include "libavutil/opt.h"
 #include "libavformat/avformat.h"
+#include "libavutil/avassert.h"
 
 int ff_alloc_input_device_context(AVFormatContext **avctx, const AVInputFormat 
*iformat, const char *format)
 {
@@ -57,3 +58,50 @@ int ff_alloc_input_device_context(AVFormatContext **avctx, 
const AVInputFormat *
 avformat_free_context(s);
 return ret;
 }
+
+typedef struct AVDeviceCapabilitiesQueryTypeEntry {
+const char* name;
+enum AVDeviceCapabilitiesQueryType  query_type;
+} AVDeviceCapabilitiesQueryTypeEntry;
+
+static const AVDeviceCapabilitiesQueryTypeEntry query_table[] = {
+// both audio and video
+{ "codec",  AV_DEV_CAP_QUERY_CODEC },
+// audio
+{ "sample_format",  AV_DEV_CAP_QUERY_SAMPLE_FORMAT },
+{ "sample_rate",AV_DEV_CAP_QUERY_SAMPLE_RATE },
+{ "channels",   AV_DEV_CAP_QUERY_CHANNELS },
+{ "channel_layout", AV_DEV_CAP_QUERY_CHANNEL_LAYOUT },
+// video
+{ "pixel_format",   AV_DEV_CAP_QUERY_PIXEL_FORMAT },
+{ "frame_size", AV_DEV_CAP_QUERY_FRAME_SIZE },
+{ "window_size",AV_DEV_CAP_QUERY_WINDOW_SIZE },
+{ "fps",AV_DEV_CAP_QUERY_FPS },
+};
+
+enum AVDeviceCapabilitiesQueryType ff_device_get_query_type(const char* 
option_name)
+{
+for (int i = 0; i < FF_ARRAY_ELEMS(query_table); ++i) {
+if (!strcmp(query_table[i].name, option_name))
+return query_table[i].query_type;
+}
+// not found
+return AV_DEV_CAP_QUERY_NONE;
+}
+
+const char* ff_device_get_query_component_name(enum 
AVDeviceCapabilitiesQueryType query_type, int component)
+{
+if (query_type == AV_DEV_CAP_QUERY_WINDOW_SIZE || query_type == 
AV_DEV_CAP_QUERY_FRAME_SIZE) {
+// special case: different name for each component
+return component == 0 ? "pixel_count" : (component == 1 ? "width" : 
(component == 2 ? "height" : ""));
+}
+else {
+av_assert0(component == 0);
+for (int i = 0; i < FF_ARRAY_ELEMS(query_table); ++i) {
+if (query_table[i].query_type == query_type)
+return query_table[i].name;
+}
+}
+// not found
+return NULL;
+}
\ No newline at end of file
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 53af6fa0d0..e0361aebc1 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVDEVICE_VERSION_MAJOR  59
 #define LIBAVDEVICE_VERSION_MINOR   3
-#define LIBAVDEVICE_VERSION_MICRO 100
+#define LIBAVDEVICE_VERSION_MICRO 101
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 24/34] avdevice: change device capabilities option type

2021-07-06 Thread Diederick Niehorster
Changes fps option from AVRational to double. This since any device
capability query results are returned in AVOptionRanges, which hold the
value as doubles, which can't contain AVRationals.

Also updated documentation of other capabilities, some had the wrong
option type listed.

micro version bump as this capabilities API is unused for now.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 4 ++--
 libavdevice/avdevice.h | 6 +++---
 libavdevice/internal.h | 4 +++-
 libavdevice/version.h  | 2 +-
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index cb139e6d4a..73c6738383 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -50,8 +50,8 @@ const AVOption ff_device_capabilities[] = {
 {.str = NULL}, -1, INT_MAX, E|D|V },
 { "frame_size", "frame size", OFFSET(frame_width), AV_OPT_TYPE_IMAGE_SIZE,
 {.str = NULL}, -1, INT_MAX, E|D|V },
-{ "fps", "fps", OFFSET(fps), AV_OPT_TYPE_RATIONAL,
-{.dbl = -1}, -1, INT_MAX, E|D|V },
+{ "fps", "fps", OFFSET(fps), AV_OPT_TYPE_DOUBLE,
+{.dbl = NAN}, 0, INT_MAX, E|D|V },
 { NULL }
 };
 
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 44c4f185a2..758c650636 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -344,7 +344,7 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  *  type: AV_OPT_TYPE_INT (AVCodecID value)
  *  - Capabilities valid for audio devices:
  *- sample_format:  supported sample formats.
- *  type: AV_OPT_TYPE_INT (AVSampleFormat value)
+ *  type: AV_OPT_TYPE_SAMPLE_FMT
  *- sample_rate:supported sample rates.
  *  type: AV_OPT_TYPE_INT
  *- channels:   supported number of channels.
@@ -353,13 +353,13 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  *  type: AV_OPT_TYPE_INT64
  *  - Capabilities valid for video devices:
  *- pixel_format:   supported pixel formats.
- *  type: AV_OPT_TYPE_INT (AVPixelFormat value)
+ *  type: AV_OPT_TYPE_PIXEL_FMT
  *- window_size:supported window sizes (describes size of the window 
size presented to the user).
  *  type: AV_OPT_TYPE_IMAGE_SIZE
  *- frame_size: supported frame sizes (describes size of provided 
video frames).
  *  type: AV_OPT_TYPE_IMAGE_SIZE
  *- fps:supported fps values
- *  type: AV_OPT_TYPE_RATIONAL
+ *  type: AV_OPT_TYPE_DOUBLE
  *
  * Value of the capability may be set by user using av_opt_set() function
  * and AVDeviceCapabilitiesQuery object. Following queries will
diff --git a/libavdevice/internal.h b/libavdevice/internal.h
index eee493a4c7..5f0bd403dd 100644
--- a/libavdevice/internal.h
+++ b/libavdevice/internal.h
@@ -50,7 +50,9 @@ struct AVDeviceCapabilitiesQuery {
 int window_height;
 int frame_width;
 int frame_height;
-AVRational fps;
+// NB: an AVRational cannot be represented in the AVOptionRange
+// output of av_opt_query_ranges, so we store fps as double instead
+double fps;
 };
 
 /**
diff --git a/libavdevice/version.h b/libavdevice/version.h
index e0361aebc1..0df40ef4c7 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVDEVICE_VERSION_MAJOR  59
 #define LIBAVDEVICE_VERSION_MINOR   3
-#define LIBAVDEVICE_VERSION_MICRO 101
+#define LIBAVDEVICE_VERSION_MICRO 102
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 25/34] avdevice: improve capabilities' option API

2021-07-06 Thread Diederick Niehorster
This adds avdevice_capabilities_get_class() to allow examining the
capabilities that can be queried/set through the capabilities API, and
avdevice_capabilities_bprint_num() which allows printing the value
returned when querying a capability. These values (min_value and
max_value of an AVOptionRange) are doubles and this function formats
them properly, e.g. 1. for a AV_OPT_TYPE_PIXEL_FMT -> yuyv422.

bump minor version.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/avdevice.c | 79 ++
 libavdevice/avdevice.h | 27 +++
 libavdevice/version.h  |  4 +--
 3 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 73c6738383..181ce04188 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -19,6 +19,8 @@
 #include "libavutil/avassert.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/pixfmt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/avutil.h"
 #include "libavcodec/avcodec.h"
 #include "avdevice.h"
 #include "internal.h"
@@ -128,6 +130,83 @@ int avdevice_capabilities_create(AVDeviceCapabilitiesQuery 
**caps, AVFormatConte
 return ret;
 }
 
+static const AVClass avdevice_capabilities_context_class = {
+.class_name = "AVDeviceCapabilitiesQuery",
+.item_name = av_default_item_name,
+.option = ff_device_capabilities,
+.version = LIBAVUTIL_VERSION_INT
+};
+
+const AVClass *avdevice_capabilities_get_class(void)
+{
+return &avdevice_capabilities_context_class;
+}
+
+int avdevice_capabilities_bprint_num(AVBPrint *bp, const char *name, double 
val)
+{
+int opt_type_set = 0, is_codec = 0;
+enum AVOptionType type;  // will be set below, opt_type_set tracks if has 
been set
+const AVClass *cap_class = avdevice_capabilities_get_class();
+
+// may fail, e.g. if name of a component of a multi-component option was 
provided as input
+const AVOption *field = av_opt_find(&cap_class, name, NULL, 0, 
AV_OPT_SEARCH_FAKE_OBJ);
+if (field) {
+type = field->type;
+opt_type_set = 1;
+}
+
+// based on name, a type override or other extra info may be needed
+if (opt_type_set && type==AV_OPT_TYPE_INT && strcmp(name, "codec")==0)
+is_codec = 1;
+// next three are for the three components of a AV_OPT_TYPE_IMAGE_SIZE
+// NB: these wont be found by av_opt_find above
+else if (
+strcmp(name, 
ff_device_get_query_component_name(AV_DEV_CAP_QUERY_WINDOW_SIZE, 0))==0 ||
+strcmp(name, 
ff_device_get_query_component_name(AV_DEV_CAP_QUERY_WINDOW_SIZE, 1))==0 ||
+strcmp(name, 
ff_device_get_query_component_name(AV_DEV_CAP_QUERY_WINDOW_SIZE, 2))==0
+) {
+type = AV_OPT_TYPE_INT;
+opt_type_set = 1;
+}
+
+// now, format if type set, else error
+if (!opt_type_set) {
+av_log(NULL, AV_LOG_ERROR, "A device capability with the name '%s' is 
not known\n", name);
+return AVERROR_OPTION_NOT_FOUND;
+}
+
+switch (type)
+{
+case AV_OPT_TYPE_INT:
+{
+int temp = lrint(val);
+if (is_codec)
+av_bprintf(bp, "%s", (char *)avcodec_get_name((enum 
AVCodecID)lrint(val)));
+else
+av_bprintf(bp, "%d", temp);
+break;
+}
+case AV_OPT_TYPE_PIXEL_FMT:
+av_bprintf(bp, "%s", (char *)av_x_if_null(av_get_pix_fmt_name((enum 
AVPixelFormat)lrint(val)), "none"));
+break;
+case AV_OPT_TYPE_SAMPLE_FMT:
+av_bprintf(bp, "%s", (char *)av_x_if_null(av_get_sample_fmt_name((enum 
AVSampleFormat)lrint(val)), "none"));
+break;
+case AV_OPT_TYPE_DOUBLE:
+av_bprintf(bp, "%f", val);
+break;
+case AV_OPT_TYPE_CHANNEL_LAYOUT:
+av_bprintf(bp, "0x%"PRIx64, llrint(val));
+break;
+
+default:
+av_log(NULL, AV_LOG_ERROR, "avdevice_capabilities_bprint_num is not 
implemented for this option type\n", name);
+return AVERROR_PATCHWELCOME;
+}
+
+return 0;
+}
+
 void avdevice_capabilities_free(AVDeviceCapabilitiesQuery **caps, 
AVFormatContext *s)
 {
 if (!s || !caps || !(*caps))
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 758c650636..11d1a6ae12 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -48,6 +48,7 @@
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
+#include "libavutil/bprint.h"
 #include "libavformat/avformat.h"
 
 /**
@@ -402,6 +403,16 @@ int avdevice_dev_to_app_control_message(struct 
AVFormatContext *s,
  */
 typedef struct AVDeviceCapabilitiesQuery AVDeviceCapabilitiesQuery;
 
+/**
+ * Get the AVClass for AVDeviceCapabilitiesQuery. It can be used
+ * in combination with AV_OPT_SEARCH_FAKE_OBJ for examining
+ * which capabilities can be queried through the
+ * AVDeviceCapabilitiesQuery API.
+ *
+ * @see av_opt_find(), av_opt_next().
+ */
+const AVClass *avdevice_capabilities_get_class(void);
+
 /**
  * Initialize capabil

[FFmpeg-devel] [PATCH v3 26/34] avdevice/dshow: move audio format helpers

2021-07-06 Thread Diederick Niehorster
Needs to be moved up in file for upcoming implementation of
avdevice_capabilities_create.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 40 
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 5b9f61926b..bc3cc2caa2 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -80,6 +80,26 @@ static enum AVPixelFormat dshow_pixfmt(DWORD biCompression, 
WORD biBitCount)
 return avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), biCompression); 
// all others
 }
 
+static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
+{
+switch (sample_fmt) {
+case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
+case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
+case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
+default:return AV_CODEC_ID_NONE; /* Should never happen. */
+}
+}
+
+static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
+{
+switch (bits) {
+case 8:  return AV_SAMPLE_FMT_U8;
+case 16: return AV_SAMPLE_FMT_S16;
+case 32: return AV_SAMPLE_FMT_S32;
+default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
+}
+}
+
 static enum AVColorRange dshow_color_range(DXVA2_ExtendedFormat *fmt_info)
 {
 switch (fmt_info->NominalRange)
@@ -1632,26 +1652,6 @@ static int dshow_control_message(AVFormatContext *avctx, 
int type, void *data, s
 return ret;
 }
 
-static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
-{
-switch (sample_fmt) {
-case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
-case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
-case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
-default:return AV_CODEC_ID_NONE; /* Should never happen. */
-}
-}
-
-static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
-{
-switch (bits) {
-case 8:  return AV_SAMPLE_FMT_U8;
-case 16: return AV_SAMPLE_FMT_S16;
-case 32: return AV_SAMPLE_FMT_S32;
-default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
-}
-}
-
 static int
 dshow_add_device(AVFormatContext *avctx,
  enum dshowDeviceType devtype)
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 27/34] avdevice/dshow: when closing, set context fields back to zero

2021-07-06 Thread Diederick Niehorster
After the avdevice capabilities API is implemented, the format context
may be reused after querying device capabilities in a later
avformat_open_input call. To enable this reuse, after releasing
resources, make sure to also set the corresponding pointers back to
NULL. This correctly indicates their state after cleanup.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index bc3cc2caa2..046c39cc24 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -296,14 +296,18 @@ dshow_read_close(AVFormatContext *s)
 ICaptureGraphBuilder2_Release(ctx->graph_builder2[VideoDevice]);
 if (ctx->graph_builder2[AudioDevice])
 ICaptureGraphBuilder2_Release(ctx->graph_builder2[AudioDevice]);
+ctx->graph_builder2[0] = NULL;
+ctx->graph_builder2[1] = NULL;
 
 if (ctx->control) {
 IMediaControl_Stop(ctx->control);
 IMediaControl_Release(ctx->control);
 }
+ctx->control = NULL;
 
 if (ctx->media_event)
 IMediaEvent_Release(ctx->media_event);
+ctx->media_event = NULL;
 
 if (ctx->graph) {
 IEnumFilters *fenum;
@@ -321,25 +325,34 @@ dshow_read_close(AVFormatContext *s)
 IEnumFilters_Release(fenum);
 }
 IGraphBuilder_Release(ctx->graph);
+ctx->graph = NULL;
 }
 
 if (ctx->capture_pin[VideoDevice])
 ff_dshow_pin_Release(ctx->capture_pin[VideoDevice]);
 if (ctx->capture_pin[AudioDevice])
 ff_dshow_pin_Release(ctx->capture_pin[AudioDevice]);
+ctx->capture_pin[0] = NULL;
+ctx->capture_pin[1] = NULL;
 if (ctx->capture_filter[VideoDevice])
 ff_dshow_filter_Release(ctx->capture_filter[VideoDevice]);
 if (ctx->capture_filter[AudioDevice])
 ff_dshow_filter_Release(ctx->capture_filter[AudioDevice]);
+ctx->capture_filter[0] = NULL;
+ctx->capture_filter[1] = NULL;
 
 if (ctx->device_pin[VideoDevice])
 IPin_Release(ctx->device_pin[VideoDevice]);
 if (ctx->device_pin[AudioDevice])
 IPin_Release(ctx->device_pin[AudioDevice]);
+ctx->device_pin[0] = NULL;
+ctx->device_pin[1] = NULL;
 if (ctx->device_filter[VideoDevice])
 IBaseFilter_Release(ctx->device_filter[VideoDevice]);
 if (ctx->device_filter[AudioDevice])
 IBaseFilter_Release(ctx->device_filter[AudioDevice]);
+ctx->device_filter[0] = NULL;
+ctx->device_filter[1] = NULL;
 
 av_freep(&ctx->device_name[0]);
 av_freep(&ctx->device_name[1]);
@@ -348,10 +361,13 @@ dshow_read_close(AVFormatContext *s)
 
 if(ctx->mutex)
 CloseHandle(ctx->mutex);
+ctx->mutex = NULL;
 if(ctx->event[0])
 CloseHandle(ctx->event[0]);
 if(ctx->event[1])
 CloseHandle(ctx->event[1]);
+ctx->event[0] = NULL;
+ctx->event[1] = NULL;
 
 pktl = ctx->pktl;
 while (pktl) {
@@ -360,6 +376,7 @@ dshow_read_close(AVFormatContext *s)
 av_free(pktl);
 pktl = next;
 }
+ctx->pktl = NULL;
 
 CoUninitialize();
 
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 01/34] avdevice/dshow: implement option to use device video timestamps

2021-07-06 Thread Diederick Niehorster
The dshow avdevice ignores timestamps for video frames provided by the
DirectShow device, instead using wallclock time, apparently because the
implementer of this code had a device that provided unreliable
timestamps. Me (and others) would like to use the device's timestamps.
The new use_video_device_timestamps option for dshow device enables them
to do so. Since the majority of video devices out there probably provide
fine timestamps, this patch sets the default to using the device
timestamps, which means best fidelity timestamps are used by default.
Using the new option, the user can switch this off and revert to the old
behavior, so a fall back remains available in case the device provides
broken timestamps.

Closes: #8620

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c |  1 +
 libavdevice/dshow_capture.h |  1 +
 libavdevice/dshow_pin.c | 11 ++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 8d0a6fcc09..2e9f9ddf3f 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1317,6 +1317,7 @@ static const AVOption options[] = {
 { "audio_device_save", "save audio capture filter device (and properties) 
to file", OFFSET(audio_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 
0, DEC },
 { "video_device_load", "load video capture filter device (and properties) 
from file", OFFSET(video_filter_load_file), AV_OPT_TYPE_STRING, {.str = NULL}, 
0, 0, DEC },
 { "video_device_save", "save video capture filter device (and properties) 
to file", OFFSET(video_filter_save_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 
0, DEC },
+{ "use_video_device_timestamps", "use device instead of wallclock 
timestamps for video frames", OFFSET(use_video_device_timestamps), 
AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, DEC },
 { NULL },
 };
 
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
index 06ded2ba96..5a2691518c 100644
--- a/libavdevice/dshow_capture.h
+++ b/libavdevice/dshow_capture.h
@@ -312,6 +312,7 @@ struct dshow_ctx {
 char *audio_filter_save_file;
 char *video_filter_load_file;
 char *video_filter_save_file;
+int   use_video_device_timestamps;
 
 IBaseFilter *device_filter[2];
 IPin*device_pin[2];
diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c
index 3dae405e65..8e56dccbfe 100644
--- a/libavdevice/dshow_pin.c
+++ b/libavdevice/dshow_pin.c
@@ -309,10 +309,14 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 if (!sample)
 return E_POINTER;
 
+priv_data = pin->filter->priv_data;
+s = priv_data;
+ctx = s->priv_data;
+
 IMediaSample_GetTime(sample, &orig_curtime, &dummy);
 orig_curtime += pin->filter->start_time;
 IReferenceClock_GetTime(clock, &graphtime);
-if (devtype == VideoDevice) {
+if (devtype == VideoDevice && !ctx->use_video_device_timestamps) {
 /* PTS from video devices is unreliable. */
 IReferenceClock_GetTime(clock, &curtime);
 } else {
@@ -322,7 +326,7 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
like 437650244077016960 which FFmpeg doesn't like.
TODO figure out math. For now just drop them. */
 av_log(NULL, AV_LOG_DEBUG,
-"dshow dropping initial (or ending) audio frame with odd PTS 
too high %"PRId64"\n", curtime);
+"dshow dropping initial (or ending) frame with odd PTS too 
high %"PRId64"\n", curtime);
 return S_OK;
 }
 curtime += pin->filter->start_time;
@@ -330,9 +334,6 @@ long ff_dshow_meminputpin_Receive(DShowMemInputPin *this, 
IMediaSample *sample)
 
 buf_size = IMediaSample_GetActualDataLength(sample);
 IMediaSample_GetPointer(sample, &buf);
-priv_data = pin->filter->priv_data;
-s = priv_data;
-ctx = s->priv_data;
 index = pin->filter->stream_index;
 
 av_log(NULL, AV_LOG_VERBOSE, "dshow passing through packet of type %s size 
%8d "
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 28/34] avdevice/dshow: implement capabilities API

2021-07-06 Thread Diederick Niehorster
This implements avdevice_capabilities_create and
avdevice_capabilities_free for the dshow device.

This enables configuration discovery of DirectShow devices through the
API, which is important for my use case. It enables making proper GUIs
presenting users with options, instead of asking them to discover a
dshow device's capabilities through the list_options option with an
FFmpeg tool, and listing what they want to configure in dumb text boxes.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 430 ++--
 1 file changed, 411 insertions(+), 19 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 046c39cc24..590a007073 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -27,6 +27,7 @@
 #include "libavformat/internal.h"
 #include "libavformat/riff.h"
 #include "avdevice.h"
+#include "internal.h"
 #include "libavcodec/raw.h"
 #include "objidl.h"
 #include "shlwapi.h"
@@ -839,11 +840,15 @@ static struct dshow_format_info 
*dshow_get_format_info(AM_MEDIA_TYPE *type)
  * try to set parameters specified through AVOptions, or the pin's
  * default format if no such parameters were set. If successful,
  * return 1 in *pformat_set.
- * If pformat_set is NULL, list all pin capabilities.
+ * If pformat_set is NULL or the ranges input is not NULL, list all
+ * pin capabilities.
+ * When listing pin capabilities, if ranges is NULL, output to log,
+ * else store capabilities in ranges.
  */
 static void
 dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
-IPin *pin, int *pformat_set)
+IPin *pin, int *pformat_set,
+AVOptionRanges *ranges, enum AVDeviceCapabilitiesQueryType 
query_type)
 {
 struct dshow_ctx *ctx = avctx->priv_data;
 IAMStreamConfig *config = NULL;
@@ -887,7 +892,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
  *one, with most info exposed (see comment below).
  */
 use_default = !dshow_should_set_format(avctx, devtype);
-if (use_default && pformat_set)
+if (use_default && pformat_set && !ranges)
 {
 HRESULT hr;
 
@@ -954,7 +959,9 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 // exposes contains a VIDEOINFOHEADER2. Fall back to the VIDEOINFOHEADER
 // format if no corresponding VIDEOINFOHEADER2 is found when we finish
 // iterating.
-for (i = 0; i < n && !format_set; i++) {
+for (i = 0; i < n && (!format_set || ranges); i++) {
+AVOptionRange *new_range[3] = { NULL };
+int nb_range = 0;
 struct dshow_format_info *fmt_info = NULL;
 r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
 if (r != S_OK)
@@ -990,7 +997,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 wait_for_better = 0;
 }
 
-if (!pformat_set) {
+if (!pformat_set && !ranges) {
 if (fmt_info->pix_fmt == AV_PIX_FMT_NONE) {
 const AVCodec *codec = 
avcodec_find_decoder(fmt_info->codec_id);
 if (fmt_info->codec_id == AV_CODEC_ID_NONE || !codec) {
@@ -1054,6 +1061,60 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 bih->biWidth  = requested_width;
 bih->biHeight = requested_height;
 }
+
+if (ranges) {
+for (int j = 0; j < ranges->nb_components; j++) {
+new_range[j] = av_mallocz(sizeof(**new_range));
+if (!new_range[j])
+goto next;
+new_range[j]->value_max = -1.;  // init (min:0, max:-1 
means value not set)
+++nb_range;
+
+switch (query_type)
+{
+case AV_DEV_CAP_QUERY_CODEC:
+if (dshow_pixfmt(bih->biCompression, bih->biBitCount) 
== AV_PIX_FMT_NONE) {
+const AVCodecTag *const tags[] = { 
avformat_get_riff_video_tags(), NULL };
+new_range[j]->value_min = av_codec_get_id(tags, 
bih->biCompression);
+}
+else
+new_range[j]->value_min = AV_CODEC_ID_RAWVIDEO;
+new_range[j]->value_max = new_range[j]->value_min;
+break;
+case AV_DEV_CAP_QUERY_PIXEL_FORMAT:
+new_range[j]->value_min = new_range[j]->value_max = 
dshow_pixfmt(bih->biCompression, bih->biBitCount);
+new_range[j]->value_min;
+break;
+case AV_DEV_CAP_QUERY_FRAME_SIZE:
+{
+switch (j)
+{
+case 0:
+new_range[j]->value_min = vcaps->

[FFmpeg-devel] [PATCH v3 29/34] avdevice/dshow: cosmetics

2021-07-06 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index 590a007073..f900e89988 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -963,6 +963,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 AVOptionRange *new_range[3] = { NULL };
 int nb_range = 0;
 struct dshow_format_info *fmt_info = NULL;
+
 r = IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
 if (r != S_OK)
 goto next;
@@ -1580,7 +1581,8 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum 
*devenum,
 goto error;
 }
 }
-if (ctx->device_filter[otherDevType]) {
+
+if (ctx->device_filter[otherDevType]) {
 // avoid adding add two instances of the same device to the graph, one 
for video, one for audio
 // a few devices don't support this (could also do this check earlier 
to avoid double crossbars, etc. but they seem OK)
 if (strcmp(device_filter_unique_name, 
ctx->device_unique_name[otherDevType]) == 0) {
@@ -2465,16 +2467,16 @@ static const AVClass dshow_class = {
 };
 
 const AVInputFormat ff_dshow_demuxer = {
-.name   = "dshow",
-.long_name  = NULL_IF_CONFIG_SMALL("DirectShow capture"),
-.priv_data_size = sizeof(struct dshow_ctx),
-.read_header= dshow_read_header,
-.read_packet= dshow_read_packet,
-.read_close = dshow_read_close,
-.control_message = dshow_control_message,
-.get_device_list= dshow_get_device_list,
+.name   = "dshow",
+.long_name  = NULL_IF_CONFIG_SMALL("DirectShow capture"),
+.priv_data_size = sizeof(struct dshow_ctx),
+.read_header= dshow_read_header,
+.read_packet= dshow_read_packet,
+.read_close = dshow_read_close,
+.control_message= dshow_control_message,
+.get_device_list= dshow_get_device_list,
 .create_device_capabilities = dshow_create_device_capabilities,
-.free_device_capabilities = dshow_free_device_capabilities,
-.flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | 
AVFMT_NO_BYTE_SEEK,
-.priv_class = &dshow_class,
+.free_device_capabilities   = dshow_free_device_capabilities,
+.flags  = AVFMT_NOFILE | AVFMT_NOBINSEARCH | 
AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK,
+.priv_class = &dshow_class,
 };
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 30/34] avformat: add avformat_alloc_input_context()

2021-07-06 Thread Diederick Niehorster
avformat_alloc_input_context function analogous to
avformat_alloc_output_context2, except that it does not take a filename
argument as guessing the format by just the filename does not make sense.
avformat_alloc_input_context can be used e.g. with the avdevice
capabilities API, which needs an allocated input format with priv_data
(and default options) set, but device should not be opened.

Added some checks to avformat_open_input, for the case that a
AVFormatContext* allocated by avformat_alloc_input_context is provided:
1.  if avformat_open_input's AVInputFormat *fmt argument is not NULL,
clean up any already set s->iformat
2.  if s->url is already set and avformat_open_input's filename argument
is not NULL, free current url and replace by provided filename
3.  if s->url is already set and avformat_open_input's filename argument
is NULL, do not set s->url to "", but keep current url
4.  if s->priv_data has already been allocated, do not do so again.
4b. do reset options to default and apply provided options (if any)
5.  add 4b to docs of avformat_open_input

Bumping avformat version.

Signed-off-by: Diederick Niehorster 
---
 libavformat/avformat.h | 29 +++--
 libavformat/utils.c| 74 ++
 2 files changed, 94 insertions(+), 9 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index a276aad64a..a0a20b9045 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1889,6 +1889,26 @@ AVProgram *av_new_program(AVFormatContext *s, int id);
  * @}
  */
 
+ /**
+  * Allocate an AVFormatContext for an input format.
+  * avformat_free_context() can be used to free the context and
+  * everything allocated by the framework within it. NB: in general
+  * the correct format cannot be known (unless the user has extra
+  * information) until the file is opened. If forcing a format by
+  * this method, but it turns out not to match the file's format
+  * upon avformat_open_input(), the latter will throw an error.
+  *
+  * @param *ctx is set to the created format context, or to NULL in
+  * case of failure
+  * @param iformat format to use for allocating the context, if NULL
+  * format_name is used instead
+  * @param format_name the name of input format to use for allocating the
+  * context
+  * @return >= 0 in case of success, a negative AVERROR code in case of
+  * failure
+  */
+int avformat_alloc_input_context(AVFormatContext **ctx, const AVInputFormat 
*iformat,
+ const char *format_name);
 
 /**
  * Allocate an AVFormatContext for an output format.
@@ -1984,9 +2004,9 @@ int av_probe_input_buffer(AVIOContext *pb, const 
AVInputFormat **fmt,
  * Open an input stream and read the header. The codecs are not opened.
  * The stream must be closed with avformat_close_input().
  *
- * @param ps Pointer to user-supplied AVFormatContext (allocated by 
avformat_alloc_context).
- *   May be a pointer to NULL, in which case an AVFormatContext is 
allocated by this
- *   function and written into ps.
+ * @param ps Pointer to user-supplied AVFormatContext (allocated by 
avformat_alloc_context, or
+ *   avformat_alloc_input_context). May be a pointer to NULL, in which 
case an
+ *   AVFormatContext is allocated by this function and written into ps.
  *   Note that a user-supplied AVFormatContext will be freed on 
failure.
  * @param url URL of the stream to open.
  * @param fmt If non-NULL, this parameter forces a specific input format.
@@ -1994,6 +2014,9 @@ int av_probe_input_buffer(AVIOContext *pb, const 
AVInputFormat **fmt,
  * @param options  A dictionary filled with AVFormatContext and 
demuxer-private options.
  * On return this parameter will be destroyed and replaced 
with a dict containing
  * options that were not found. May be NULL.
+ * Note that if a AVFormatContext allocated by 
avformat_alloc_input_context
+ * is provided, any demuxer-private options will be 
overwritten by their defaults
+ * before applying this new set of demuxer-private options, if 
any. 
  *
  * @return 0 on success, a negative AVERROR on failure.
  *
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 0df14682a4..34e21d6450 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -478,6 +478,56 @@ static int update_stream_avctx(AVFormatContext *s)
 }
 
 
+int avformat_alloc_input_context(AVFormatContext **avctx, const AVInputFormat 
*iformat,
+ const char *format)
+{
+AVFormatContext *s = avformat_alloc_context();
+int ret = 0;
+
+*avctx = NULL;
+if (!s)
+goto nomem;
+
+if (!iformat) {
+if (format) {
+iformat = av_find_input_format(format);
+if (!iformat) {
+av_log(s, AV_LOG_ERROR, "Requested input format '%s' not 
found\n", format);
+ret = AVERROR(EINVAL);

[FFmpeg-devel] [PATCH v3 31/34] doc/examples: adding device_get_capabilities example

2021-07-06 Thread Diederick Niehorster
This example also shows use of get_device_list API.

Also improve capability API doc in avdevice.h: now point to this example
instead of rough example code given in the header.

Signed-off-by: Diederick Niehorster 
---
 configure  |   2 +
 doc/examples/.gitignore|   1 +
 doc/examples/Makefile  |   1 +
 doc/examples/Makefile.example  |   1 +
 doc/examples/device_get_capabilities.c | 243 +
 libavdevice/avdevice.h |  33 +---
 6 files changed, 249 insertions(+), 32 deletions(-)
 create mode 100644 doc/examples/device_get_capabilities.c

diff --git a/configure b/configure
index b124411609..ab5d6fee30 100755
--- a/configure
+++ b/configure
@@ -1706,6 +1706,7 @@ EXAMPLE_LIST="
 decode_audio_example
 decode_video_example
 demuxing_decoding_example
+device_get_capabilities_example
 encode_audio_example
 encode_video_example
 extract_mvs_example
@@ -3716,6 +3717,7 @@ avio_reading_deps="avformat avcodec avutil"
 decode_audio_example_deps="avcodec avutil"
 decode_video_example_deps="avcodec avutil"
 demuxing_decoding_example_deps="avcodec avformat avutil"
+device_get_capabilities_example_deps="avdevice avformat avutil"
 encode_audio_example_deps="avcodec avutil"
 encode_video_example_deps="avcodec avutil"
 extract_mvs_example_deps="avcodec avformat avutil"
diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore
index 44960e1de7..256f33a600 100644
--- a/doc/examples/.gitignore
+++ b/doc/examples/.gitignore
@@ -3,6 +3,7 @@
 /decode_audio
 /decode_video
 /demuxing_decoding
+/device_get_capabilities
 /encode_audio
 /encode_video
 /extract_mvs
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 81bfd34d5d..de707bb3ca 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -3,6 +3,7 @@ EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE)  += avio_reading
 EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE)  += decode_audio
 EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE)  += decode_video
 EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
+EXAMPLES-$(CONFIG_DEVICE_GET_CAPABILITIES_EXAMPLE) += device_get_capabilities
 EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)  += encode_audio
 EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE)  += encode_video
 EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)   += extract_mvs
diff --git a/doc/examples/Makefile.example b/doc/examples/Makefile.example
index a232d97f98..b861b9cc74 100644
--- a/doc/examples/Makefile.example
+++ b/doc/examples/Makefile.example
@@ -16,6 +16,7 @@ EXAMPLES=   avio_list_dir  \
 decode_audio   \
 decode_video   \
 demuxing_decoding  \
+device_get_capabilities\
 encode_audio   \
 encode_video   \
 extract_mvs\
diff --git a/doc/examples/device_get_capabilities.c 
b/doc/examples/device_get_capabilities.c
new file mode 100644
index 00..45eb2eadf4
--- /dev/null
+++ b/doc/examples/device_get_capabilities.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2021 Diederick Niehorster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * avdevice getting capabilities example.
+ *
+ * Shows how to use the avdevice capabilities API to probe
+ * device capabilities (supported codecs, pixel formats, sample
+ * formats, resolutions, channel counts, etc)
+ * @example device_get_capabilities.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+int print_option_ranges(enum AVOptionType type, AVOptionRanges *ranges)
+{
+for (int range_index = 0; range_index < ranges->nb_ranges; range_index++) {
+int ret;
+char *out_val = NULL;
+AVBPrint bp;
+av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIM

[FFmpeg-devel] [PATCH v3 32/34] Makefile/examples: cosmetics

2021-07-06 Thread Diederick Niehorster
Signed-off-by: Diederick Niehorster 
---
 doc/examples/Makefile | 48 +--
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index de707bb3ca..7988ed4226 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -1,27 +1,27 @@
-EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
-EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE)  += avio_reading
-EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE)  += decode_audio
-EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE)  += decode_video
-EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
-EXAMPLES-$(CONFIG_DEVICE_GET_CAPABILITIES_EXAMPLE) += device_get_capabilities
-EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)  += encode_audio
-EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE)  += encode_video
-EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)   += extract_mvs
-EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE)  += filter_audio
-EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE)   += filtering_audio
-EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE)   += filtering_video
-EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE)  += http_multiclient
-EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
-EXAMPLES-$(CONFIG_METADATA_EXAMPLE)  += metadata
-EXAMPLES-$(CONFIG_MUXING_EXAMPLE)+= muxing
-EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)+= qsvdec
-EXAMPLES-$(CONFIG_REMUXING_EXAMPLE)  += remuxing
-EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE)  += resampling_audio
-EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
-EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
-EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE)   += transcoding
-EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE)  += vaapi_encode
-EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE)   += vaapi_transcode
+EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
+EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE)  += avio_reading
+EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE)  += decode_audio
+EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE)  += decode_video
+EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
+EXAMPLES-$(CONFIG_DEVICE_GET_CAPABILITIES_EXAMPLE)   += device_get_capabilities
+EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)  += encode_audio
+EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE)  += encode_video
+EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)   += extract_mvs
+EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE)  += filter_audio
+EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE)   += filtering_audio
+EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE)   += filtering_video
+EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE)  += http_multiclient
+EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
+EXAMPLES-$(CONFIG_METADATA_EXAMPLE)  += metadata
+EXAMPLES-$(CONFIG_MUXING_EXAMPLE)+= muxing
+EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)+= qsvdec
+EXAMPLES-$(CONFIG_REMUXING_EXAMPLE)  += remuxing
+EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE)  += resampling_audio
+EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
+EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
+EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE)   += transcoding
+EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE)  += vaapi_encode
+EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE)   += vaapi_transcode
 
 EXAMPLES   := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
 EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 33/34] avdevice/dshow: prevent NULL access

2021-07-06 Thread Diederick Niehorster
list_options true would crash when both a video and an audio device were
specified as input. Crash would occur on line 1588 (in this new rev)
because ctx->device_unique_name[otherDevType] would be NULL

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index f900e89988..a66f7b81fd 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -1519,9 +1519,9 @@ dshow_list_device_options(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name, NULL)) < 0)
 return r;
 ctx->device_filter[devtype] = device_filter;
+ctx->device_unique_name[devtype] = device_unique_name;
 if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, 
ranges ? &device_pin : NULL, ranges, query_type)) < 0)
 return r;
-av_freep(&device_unique_name);
 return 0;
 }
 
@@ -2043,6 +2043,7 @@ static int dshow_read_header(AVFormatContext *avctx)
 }
 }
 }
+// don't exit yet, allow it to list crossbar options in 
dshow_open_device
 }
 ctx->is_running = 0;
 if (ctx->device_name[VideoDevice]) {
-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] [PATCH v3 34/34] avdevice/dshow: capabilities query also works on opened device

2021-07-06 Thread Diederick Niehorster
While the capabilities API is in principle meant to be used with an
allocated format context belonging to an unopened device, small changes
make it work for an opened dshow device as well. So hereby done.

Signed-off-by: Diederick Niehorster 
---
 libavdevice/dshow.c | 110 +---
 libavdevice/dshow_capture.h |   3 +
 2 files changed, 66 insertions(+), 47 deletions(-)

diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
index a66f7b81fd..5c1fadc23d 100644
--- a/libavdevice/dshow.c
+++ b/libavdevice/dshow.c
@@ -858,7 +858,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 void *caps = NULL;
 int i, n, size, r;
 int wait_for_better = 0;
-int use_default;
+int use_default, already_opened;
 
 // format parameters requested by user
 // if none are requested by user, the values will below be set to
@@ -884,6 +884,9 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 if (!caps)
 goto end;
 
+// get if device is already opened
+already_opened = ctx->device_name[0] || ctx->device_name[1];
+
 /** 
  * If we should open the device with the default format,
  * then:
@@ -1191,7 +1194,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum 
dshowDeviceType devtype,
 // in ranges, try to apply in all cases, and store
 // caps if successfully applied
 if (!wait_for_better || ranges) {
-if (IAMStreamConfig_SetFormat(config, type) != S_OK)
+if (!already_opened && IAMStreamConfig_SetFormat(config, type) != 
S_OK) // skip if device already opened
 goto next;
 else if (ranges) {
 // format matched and could be set successfully.
@@ -1516,12 +1519,19 @@ dshow_list_device_options(AVFormatContext *avctx, 
ICreateDevEnum *devenum,
 char *device_unique_name = NULL;
 int r;
 
-if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name, NULL)) < 0)
-return r;
-ctx->device_filter[devtype] = device_filter;
-ctx->device_unique_name[devtype] = device_unique_name;
+if (!ctx->device_filter[devtype]) {
+if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, 
&device_filter, &device_unique_name, NULL)) < 0)
+return r;
+
+// put them in context so they'll be cleaned up again
+ctx->device_filter[devtype] = device_filter;
+ctx->device_unique_name[devtype] = device_unique_name;
+} else
+device_filter = ctx->device_filter[devtype];
+
 if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, 
ranges ? &device_pin : NULL, ranges, query_type)) < 0)
 return r;
+
 return 0;
 }
 
@@ -2344,7 +2354,8 @@ fail1:
 return ret;
 }
 
-// fake class to point av_opt_query_ranges to our query_ranges function
+// fake class to point av_opt functions to capabilities that can be queried,
+// and av_opt_query_ranges to our query_ranges function
 static const AVClass dshow_dev_caps_class = {
 .class_name   = "",
 .item_name= av_default_item_name,
@@ -2362,49 +2373,51 @@ static int dshow_create_device_capabilities(struct 
AVFormatContext *avctx, AVDev
 // set class so queries work
 caps->av_class = &dshow_dev_caps_class;
 
-if (ctx->device_name[0] || ctx->device_name[1]) {
-av_log(avctx, AV_LOG_ERROR, "You cannot query device capabilities on 
an opened device\n");
-ret = AVERROR(EIO);
-goto fail;
-}
+// check if device setup is needed or we will be querying capabilities of 
an already opened device
+ctx->cap_query_already_opened = ctx->device_name[0] || ctx->device_name[1];
+if (ctx->cap_query_already_opened)
+av_log(avctx, AV_LOG_WARNING, "Querying device capabilities on an 
opened device: may yield false positives\n");
 
-if (!parse_device_name(avctx)) {
-av_log(avctx, AV_LOG_ERROR, "You must set a device name 
(AVFormatContext url) to specify which device to query capabilities from\n");
-ret = AVERROR(EINVAL);
-goto fail;
-}
-
-CoInitialize(0);
-if (CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- &IID_ICreateDevEnum, (void **) &devenum)) {
-av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
-ret = AVERROR(EIO);
-goto fail;
-}
+// if device not already opened, check that what user specified can be 
opened
+if (!ctx->cap_query_already_opened) {
+if (!parse_device_name(avctx)) {
+av_log(avctx, AV_LOG_ERROR, "You must set a device name 
(AVFormatContext url) to specify which device to query capabilities from\n");
+ret = AVERROR(EINVAL);
+goto fail;
+}
 
-// check devices can be found
-if (ctx->device_name[VideoDevice]) {
-IBaseFilter *device_filter = NULL;
-char *device_u

[FFmpeg-devel] [PATCH v3 00/34] avdevice (mostly dshow) enhancements

2021-07-06 Thread Diederick Niehorster
This patch series implements a series of features, mostly enhancing the
dshow avdevice, but also adding new functionality to avformat.
This whole patchset enabled users of the FFmpeg API to fully
query and control a dshow device, making FFmpeg a nice backend for any
program that needs access to, e.g., a webcam.

Different from v2, a print helper function for return values from the
avdevice capabilities API is now in avdevice instead of avutil, as
making it specific to avdevice allows for better output.

Querying the capabilities of a dshow device is also possible on a
device that is already opened. I expect/guess however that it may not be
possible to achieve that for all of the avdevices, so in principle it is
important that this patchset adds the ability to create an allocated but
unopened AVFormatContext+AVInputFormat with the new function
avformat_alloc_input_context().

Diederick Niehorster (34):
  avdevice/dshow: implement option to use device video timestamps
  avdevice/dshow: add use_video_device_timestamps to docs
  avdevice/dshow: query graph and sample time only once
  avdevice/dshow: handle unknown sample time
  avdevice/dshow: set no-seek flags
  avdevice/dshow: implement get_device_list
  avdevice/dshow: list_devices: show media type(s) per device
  avdevice: add info about media types(s) to AVDeviceInfo
  avdevice/dshow: add media type info to get_device_list
  fftools: provide media type info for devices
  avformat: add control_message function to AVInputFormat
  avdevice/dshow: implement control_message interface
  avdevice: adding control message requesting to show config dialog
  avdevice/dshow: accept show config dialog control message
  avdevice/dshow: tv_tuner_audio_dialog cleanup missing
  avdevice/dshow: add config dialog command for crossbar and tv tuner
  avdevice/dshow: discover source color range/space/etc
  avdevice/dshow: select format with extended color info
  avdevice/avdevice: Revert "Deprecate AVDevice Capabilities API"
  avdevice/avdevice: clean up avdevice_capabilities_create
  avdevice: capabilities API details no longer public
  avutil/opt: document AVOptionRange min_value > max_value
  avdevice: Add internal helpers for querying device capabilities
  avdevice: change device capabilities option type
  avdevice: improve capabilities' option API
  avdevice/dshow: move audio format helpers
  avdevice/dshow: when closing, set context fields back to zero
  avdevice/dshow: implement capabilities API
  avdevice/dshow: cosmetics
  avformat: add avformat_alloc_input_context()
  doc/examples: adding device_get_capabilities example
  Makefile/examples: cosmetics
  avdevice/dshow: prevent NULL access
  avdevice/dshow: capabilities query also works on opened device

 configure  |2 +
 doc/examples/.gitignore|1 +
 doc/examples/Makefile  |   47 +-
 doc/examples/Makefile.example  |1 +
 doc/examples/device_get_capabilities.c |  243 
 doc/indevs.texi|   40 +
 fftools/cmdutils.c |   34 +-
 libavdevice/avdevice.c |  165 ++-
 libavdevice/avdevice.h |  103 +-
 libavdevice/dshow.c| 1445 +---
 libavdevice/dshow_capture.h|   15 +
 libavdevice/dshow_crossbar.c   |   95 +-
 libavdevice/dshow_pin.c|   46 +-
 libavdevice/internal.h |   66 ++
 libavdevice/utils.c|   48 +
 libavdevice/version.h  |2 +-
 libavformat/avformat.h |   56 +-
 libavformat/utils.c|   74 +-
 libavutil/opt.c|2 +-
 libavutil/opt.h|5 +
 20 files changed, 2179 insertions(+), 311 deletions(-)
 create mode 100644 doc/examples/device_get_capabilities.c

-- 
2.28.0.windows.1

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

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


[FFmpeg-devel] Consulting Enquiry

2021-07-06 Thread Michael Scott
Hello

I am emailing this mailing as per the instructions on
https://ffmpeg.org/consulting.html.

I am looking for a rough quote to provide the following functionality and
advice in the context of short (10-120 second) videos.

   1. The ability to overlay audio waveforms at a given position with basic
   styling.
   2. The ability to overlay gifs at a given position.
   3. The ability to overlay subtitles at a given position from srt files
   with basic styling.
   4. How to optimise for any combination of the above processes being used
   on one video.


Kind regards
Michael
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


[FFmpeg-devel] [PATCH] tools/target_dec_fuzzer: move maximum variables into function

2021-07-06 Thread Michael Niedermayer
This fixes an issue when multiple cases are fuzzed in a single run and
the limits are adjusted by more than the iteration limit. In that case
the adjusted limit leaked back into the global limit causing the
fuzzer to become ineffective after several iterations, MSS2 was
affected by this for example.

Signed-off-by: Michael Niedermayer 
---
 tools/target_dec_fuzzer.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/target_dec_fuzzer.c b/tools/target_dec_fuzzer.c
index 6092f6775d..96b8f81958 100644
--- a/tools/target_dec_fuzzer.c
+++ b/tools/target_dec_fuzzer.c
@@ -98,15 +98,15 @@ static int audio_video_handler(AVCodecContext *avctx, 
AVFrame *frame,
 
 // Ensure we don't loop forever
 const uint32_t maxiteration = 8096;
-uint64_t maxpixels_per_frame = 4096 * 4096;
-uint64_t maxpixels;
-
-uint64_t maxsamples_per_frame = 256*1024*32;
-uint64_t maxsamples;
 
 static const uint64_t FUZZ_TAG = 0x4741542D5A5A5546ULL;
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+uint64_t maxpixels_per_frame = 4096 * 4096;
+uint64_t maxpixels;
+
+uint64_t maxsamples_per_frame = 256*1024*32;
+uint64_t maxsamples;
 const uint64_t fuzz_tag = FUZZ_TAG;
 const uint8_t *last = data;
 const uint8_t *end = data + size;
-- 
2.17.1

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

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


Re: [FFmpeg-devel] [PATCH] tools/target_dec_fuzzer: move maximum variables into function

2021-07-06 Thread Michael Niedermayer
On Tue, Jul 06, 2021 at 06:08:01PM +0200, Michael Niedermayer wrote:
> This fixes an issue when multiple cases are fuzzed in a single run and
> the limits are adjusted by more than the iteration limit. In that case
> the adjusted limit leaked back into the global limit causing the
> fuzzer to become ineffective after several iterations, MSS2 was
> affected by this for example.
> 
> Signed-off-by: Michael Niedermayer 
> ---
>  tools/target_dec_fuzzer.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)

i intend to apply this today so we can see if it resolves some coverage
issues with the fuzzer

thx

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

"I am not trying to be anyone's saviour, I'm trying to think about the
 future and not be sad" - Elon Musk



signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] avformat/oggparsevorbis: Update end_trimming for the last packet

2021-07-06 Thread Guangyu Sun
On Tue, Jul 6, 2021 at 1:15 AM Lynne  wrote:
>
> 6 Jul 2021, 08:02 by sunguangy...@gmail.com:
>
> > On Mon, Jun 21, 2021 at 9:06 AM Guangyu Sun  wrote:
> >
> >>
> >> From: Guangyu Sun 
> >>
> >> Without end_trimming, the last packet will contain unexpected samples used
> >> for padding.
> >>
> >> This commit partially fixes #6367 when the audio length is long enough.
> >>
> >> dd if=/dev/zero of=./silence.raw count=20 bs=500
> >> oggenc --raw silence.raw --output=silence.ogg
> >> oggdec --raw --output silence.oggdec.raw silence.ogg
> >> ffmpeg -codec:a libvorbis -i silence.ogg -f s16le -codec:a pcm_s16le 
> >> silence.libvorbis.ffmpeg.raw
> >> ffmpeg -i silence.ogg -f s16le -codec:a pcm_s16le silence.native.ffmpeg.raw
> >> ls -l *.raw
> >>
> >> The original test case in #6367 is still not fixed due to a remaining 
> >> issue.
> >>
> >> The remaining issue is that ogg_stream->private is not kept during
> >> ogg_save()/ogg_restore(). Field final_duration in the private data is
> >> important to calculate end_trimming.
> >>
> >> Some common operations such as avformat_open_input() and
> >> avformat_find_stream_info() before reading packet will trigger ogg_save()
> >> and ogg_restore().
> >>
> >> Luckily, final_duration will not get updated until the last ogg page. The
> >> save/restore mentioned above will not change final_duration most of the
> >> time. But if the audio length is short, those reads may be performed on
> >> the last ogg page, causing trouble keeping the correct value of
> >> final_duration. We probably need a more complicated patch to address this
> >> issue.
> >>
> >> Signed-off-by: Guangyu Sun 
> >> ---
> >>  libavformat/oggparsevorbis.c | 6 +-
> >>  1 file changed, 5 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
> >> index 0e8c25c030..c48658ceda 100644
> >> --- a/libavformat/oggparsevorbis.c
> >> +++ b/libavformat/oggparsevorbis.c
> >> @@ -492,8 +492,12 @@ static int vorbis_packet(AVFormatContext *s, int idx)
> >>  priv->final_pts  = os->lastpts;
> >>  priv->final_duration = 0;
> >>  }
> >> -if (os->segp == os->nsegs)
> >> +if (os->segp == os->nsegs) {
> >> +int64_t skip = priv->final_pts + priv->final_duration + 
> >> os->pduration - os->granule;
> >> +if (skip > 0)
> >> +os->end_trimming = skip;
> >>  os->pduration = os->granule - priv->final_pts - priv->final_duration;
> >> +}
> >>  priv->final_duration += os->pduration;
> >>  }
> >>
> >> --
> >> 2.30.1
> >>
> >
> > After fixing AV_PKT_DATA_SKIP_SAMPLES for reading vorbis packets from
> > ogg, the actual decoded samples become fewer. As a result, three fate
> > tests are failing:
> >
> > fate-vorbis-encode:
> > This exposes another bug in the vorbis encoder that initial_padding is
> > not set. I will fix that in a separate patch.
> >
> > fate-webm-dash-chapters:
> > The original vorbis_chapter_extension_demo.ogg is transmuxed to
> > dash-webm. The ref file webm-dash-chapters needs to be updated.
> >
> > fate-vorbis-20:
> > The samples in 6.ogg are not frame aligned. 6.pcm file was generated
> > by ffmpeg before the fix. After the fix, the decoded pcm file does not
> > match anymore. The ref file 6.pcm needs to be updated.
> >
> > My question is that to fix fate-vorbis-20, a new file 6_v2.pcm needs
> > to be uploaded to the fate suite server. How should I do that? The doc
> > says it should be sent to samples-request but I am not sure if it is
> > an email or something else.
> >
>
> Just put a link to it here and someone will upload it. Then a day will have
> to pass to let all fate clients pull it before pushing the patch.
> Patch looks good to me as-is, since it's just a copy of what Opus does.

Great! Here is the link:
https://tinyurl.com/hkmwdk78

I would like it to be uploaded to:
fate-suite/vorbis/6_v2.pcm

Thanks in advance!

Best,
Guangyu

> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH v2 3/9] avcodec/av1dec: support setup shear process

2021-07-06 Thread Henrik Gramner
On Mon, Jul 5, 2021 at 4:32 AM Fei Wang  wrote:
> +int64_t v, w;
> +int32_t *param = &s->cur_frame.gm_params[idx][0];
...
> +v = param[4] * (1 << AV1_WARPEDMODEL_PREC_BITS);
> +w = param[3] * param[4];

Possible integer overflow? Might need some int64_t casting before the
multiplies.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] avformat/matroskadec: Fix handling of huge default durations

2021-07-06 Thread Michael Niedermayer
On Mon, Jul 05, 2021 at 08:32:30PM +0200, Michael Niedermayer wrote:
> Fixes: negation of -9223372036854775808 cannot be represented in type 
> 'int64_t' (aka 'long'); cast to an unsigned type to negate this value to 
> itself
> Fixes: 
> 33997/clusterfuzz-testcase-minimized-ffmpeg_dem_WEBM_DASH_MANIFEST_fuzzer-6752039691485184
> 
> Found-by: continuous fuzzing process 
> https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> Signed-off-by: Michael Niedermayer 
> ---
>  libavformat/matroskadec.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

will apply

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

"You are 36 times more likely to die in a bathtub than at the hands of a
terrorist. Also, you are 2.5 times more likely to become a president and
2 times more likely to become an astronaut, than to die in a terrorist
attack." -- Thoughty2



signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] avpacket: ABI bump additions

2021-07-06 Thread Marton Balint




On Tue, 6 Jul 2021, Lynne wrote:


3 Jun 2021, 06:58 by d...@lynne.ee:


Apr 26, 2021, 03:27 by andreas.rheinha...@outlook.com:


Lynne:


From 097aed2ac33dda0bb2052d8b0402711ce95079ba Mon Sep 17 00:00:00 2001
From: Lynne 
Date: Sat, 23 Jan 2021 19:56:18 +0100
Subject: [PATCH] avpacket: ABI bump additions

---
 libavcodec/avpacket.c |  5 +
 libavcodec/packet.h   | 21 +
 2 files changed, 26 insertions(+)

diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index e32c467586..03b73b3b53 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -382,6 +382,10 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket 
*src)
 dst->flags= src->flags;
 dst->stream_index = src->stream_index;

+i = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
+if (i < 0)
+return i;



1. Don't use i here; add a new variable.
2. Up until now, av_packet_ref() and av_packet_copy_props() treat the
destination packet as uninitialized and make no attempt at unreferencing
its content; yet you try to reuse opaque_ref. Even worse, you might
return potentially dangerous packets: If the properties were
uninitialized and av_packet_copy_props() failed, then the caller were
not allowed to unreference the packet even when the non-properties were
set to sane values. The easiest way to fix this is to move setting
opaque ref to the place after initializing side_data below and either
set dst->opaque_ref to NULL before av_buffer_replace() or to not use
av_buffer_replace(). It may also be best to unref it again if copying
side data fails.


+
 dst->side_data= NULL;
 dst->side_data_elems  = 0;
 for (i = 0; i < src->side_data_elems; i++) {
@@ -403,6 +407,7 @@ int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
 void av_packet_unref(AVPacket *pkt)
 {
 av_packet_free_side_data(pkt);
+av_buffer_unref(&pkt->opaque_ref);
 av_buffer_unref(&pkt->buf);
 get_packet_defaults(pkt);
 }
diff --git a/libavcodec/packet.h b/libavcodec/packet.h
index fad8341c12..c29ad18a2b 100644
--- a/libavcodec/packet.h
+++ b/libavcodec/packet.h
@@ -383,6 +383,27 @@ typedef struct AVPacket {
 int64_t duration;

 int64_t pos;///< byte position in stream, -1 if 
unknown
+
+/**
+ * for some private data of the user
+ */
+void *opaque;



The corresponding AVFrame field is copied when copying props.



Fixed both, thanks. Also copied the time_base field and made av_init_packet()
initialize all fields.
Patch attached. Sorry it's taking me so long to work on this and the Vulkan ABI 
changes.



Since no one yet has objected, will push this in 3 days unless someone does.


Can you reply this this please?

http://ffmpeg.org/pipermail/ffmpeg-devel/2021-May/279855.html

Thanks,
Marton
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

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


Re: [FFmpeg-devel] [PATCH] avpacket: ABI bump additions

2021-07-06 Thread Lynne
6 Jul 2021, 21:57 by c...@passwd.hu:

>
>
> On Tue, 6 Jul 2021, Lynne wrote:
>
>> 3 Jun 2021, 06:58 by d...@lynne.ee:
>>
>>> Apr 26, 2021, 03:27 by andreas.rheinha...@outlook.com:
>>>
 Lynne:

> From 097aed2ac33dda0bb2052d8b0402711ce95079ba Mon Sep 17 00:00:00 2001
> From: Lynne 
> Date: Sat, 23 Jan 2021 19:56:18 +0100
> Subject: [PATCH] avpacket: ABI bump additions
>
> ---
>  libavcodec/avpacket.c |  5 +
>  libavcodec/packet.h   | 21 +
>  2 files changed, 26 insertions(+)
>
> diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
> index e32c467586..03b73b3b53 100644
> --- a/libavcodec/avpacket.c
> +++ b/libavcodec/avpacket.c
> @@ -382,6 +382,10 @@ int av_packet_copy_props(AVPacket *dst, const 
> AVPacket *src)
>  dst->flags= src->flags;
>  dst->stream_index = src->stream_index;
>
> +i = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
> +if (i < 0)
> +return i;
>

 1. Don't use i here; add a new variable.
 2. Up until now, av_packet_ref() and av_packet_copy_props() treat the
 destination packet as uninitialized and make no attempt at unreferencing
 its content; yet you try to reuse opaque_ref. Even worse, you might
 return potentially dangerous packets: If the properties were
 uninitialized and av_packet_copy_props() failed, then the caller were
 not allowed to unreference the packet even when the non-properties were
 set to sane values. The easiest way to fix this is to move setting
 opaque ref to the place after initializing side_data below and either
 set dst->opaque_ref to NULL before av_buffer_replace() or to not use
 av_buffer_replace(). It may also be best to unref it again if copying
 side data fails.

> +
>  dst->side_data= NULL;
>  dst->side_data_elems  = 0;
>  for (i = 0; i < src->side_data_elems; i++) {
> @@ -403,6 +407,7 @@ int av_packet_copy_props(AVPacket *dst, const 
> AVPacket *src)
>  void av_packet_unref(AVPacket *pkt)
>  {
>  av_packet_free_side_data(pkt);
> +av_buffer_unref(&pkt->opaque_ref);
>  av_buffer_unref(&pkt->buf);
>  get_packet_defaults(pkt);
>  }
> diff --git a/libavcodec/packet.h b/libavcodec/packet.h
> index fad8341c12..c29ad18a2b 100644
> --- a/libavcodec/packet.h
> +++ b/libavcodec/packet.h
> @@ -383,6 +383,27 @@ typedef struct AVPacket {
>  int64_t duration;
>
>  int64_t pos;///< byte position in stream, -1 
> if unknown
> +
> +/**
> + * for some private data of the user
> + */
> +void *opaque;
>

 The corresponding AVFrame field is copied when copying props.

>>>
>>> Fixed both, thanks. Also copied the time_base field and made 
>>> av_init_packet()
>>> initialize all fields.
>>> Patch attached. Sorry it's taking me so long to work on this and the Vulkan 
>>> ABI changes.
>>>
>>
>> Since no one yet has objected, will push this in 3 days unless someone does.
>>
>
> Can you reply this this please?
>
> http://ffmpeg.org/pipermail/ffmpeg-devel/2021-May/279855.html
>

> You wrote earlier that you don't like that you have to pass packets to the
> muxer in a timebase as set by the muxer's init function. Solving this by
> adding a muxer open flag which saves the preferred time base of the user
> and rescales all packets from the user's preferred time base to the real
> time base before processing seems much more managable than introducing the
> AVPacket->time_base support everywhere and as far as I see it solves this
> problem just the same.

I'm mainly introducing the field for myself. I have some (de)muxer code that's
timestamp dependent, and timestamps don't make sense without knowing the
time base. Since multiple streams go into that code, having a sideband way
to plumb the timebases made the code very messy. The fact that they can
also be used to save on an awkward and complicated mechanism to
negotiate just comes as a bonus. Honestly, I had to read the mpv source
code to realize that this is the correct sequence that has to happen,
when none of this is even necessary. I'm sure other API users will find the
field useful.

I don't mind having a way to set the preferred time base, but I do think it'll
be even more confusing if it converts time bases as well. We need a way
to give a hint to muxers what time base you'd like, but I'd rather have it
just remain a hint rather than also do the conversion, since it'll limit the
usability to just your stream's input timebase. And if you have to specify your
stream input timebase somewhere, then this would be better, where it's
relevant.

> Are there similar problems elsewhere? If there are, then is it not more
> managable to allow the user to specify a preferred input or output
> timebase during init instead of allowing pe

Re: [FFmpeg-devel] [PATCH v2] fftools/ffmpeg: accelerate seeking while reading input at native frame rate

2021-07-06 Thread Linjie Fu
On Sun, Jul 4, 2021 at 10:50 PM Linjie Fu  wrote:
>
> From: Linjie Fu 
>
> Skip the logic of frame rate emulation until the input reaches the
> specified start time.
>
> Test CMD:
>$ffmpeg -re -ss 30 -i input.mp4 -pix_fmt yuv420p -f sdl2 -
>
> Before the patch:
> first time to got frame, it takes 257305 us
> After this patch:
> first time to got frame, it takes 48879 us
>
> Signed-off-by: Linjie Fu 
> ---
> [v2]: fixed the mixed declaration and code warning
> Calculate the time to get the first frame:
> https://github.com/fulinjie/ffmpeg/commit/2aa4762e1e65709997b1ab9dd596332244db80ed
>  fftools/ffmpeg.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index e97d879cb3..c8849e4250 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -4221,10 +4221,14 @@ static int get_input_packet(InputFile *f, AVPacket 
> **pkt)
>  {
>  if (f->rate_emu) {
>  int i;
> +int64_t pts;
> +int64_t now;
>  for (i = 0; i < f->nb_streams; i++) {
>  InputStream *ist = input_streams[f->ist_index + i];
> -int64_t pts = av_rescale(ist->dts, 100, AV_TIME_BASE);
> -int64_t now = av_gettime_relative() - ist->start;
> +if (!ist->got_output)
> +continue;
> +pts = av_rescale(ist->dts, 100, AV_TIME_BASE);
> +now = av_gettime_relative() - ist->start;
>  if (pts > now)
>  return AVERROR(EAGAIN);
>  }
> --
> 2.31.1
ping, thx.

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

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