[FFmpeg-devel] [PATCH v2 1/6] avformat/argo_asf: check sample count in demuxer
Signed-off-by: Zane van Iperen --- libavformat/argo_asf.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index 3339425244..9de64dfab4 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -27,6 +27,7 @@ #define ASF_TAG MKTAG('A', 'S', 'F', '\0') #define ASF_FILE_HEADER_SIZE24 #define ASF_CHUNK_HEADER_SIZE 20 +#define ASF_SAMPLE_COUNT32 typedef struct ArgoASFFileHeader { uint32_tmagic; /*< Magic Number, {'A', 'S', 'F', '\0'} */ @@ -39,7 +40,7 @@ typedef struct ArgoASFFileHeader { typedef struct ArgoASFChunkHeader { uint32_tnum_blocks; /*< No. blocks in the chunk. */ -uint32_tnum_samples;/*< No. samples per channel in a block. */ +uint32_tnum_samples;/*< No. samples per channel in a block. Always 32. */ uint32_tunk1; /*< Unknown */ uint16_tsample_rate;/*< Sample rate. */ uint16_tunk2; /*< Unknown. */ @@ -158,6 +159,12 @@ static int argo_asf_read_header(AVFormatContext *s) argo_asf_parse_chunk_header(&asf->ckhdr, buf); +if (asf->ckhdr.num_samples != ASF_SAMPLE_COUNT) { +av_log(s, AV_LOG_ERROR, "Invalid sample count. Got %u, expected %d\n", + asf->ckhdr.num_samples, ASF_SAMPLE_COUNT); +return AVERROR_INVALIDDATA; +} + if ((asf->ckhdr.flags & ASF_CF_ALWAYS1) != ASF_CF_ALWAYS1 || (asf->ckhdr.flags & ASF_CF_ALWAYS0) != 0) { avpriv_request_sample(s, "Nonstandard flags (0x%08X)", asf->ckhdr.flags); return AVERROR_PATCHWELCOME; -- 2.25.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 v2 0/6] add adpcm_argo encoder and argo_asf muxer
v2: [1] * enforce the samples-per-block value in the demuxer * remove unnecessary initialisers * add missing return when stream isn't seekable * change a sequence of avio_wl8()s to an avio_write() * add write_packet() and check packet sizes * use AVStream::nb_frames instead of calculating the value * fix Makefile dependencies Zane van Iperen (6): avformat/argo_asf: check sample count in demuxer avcodec/adpcm_argo: add ff_adpcm_argo_expand_nibble() and cleanup parameters avcodec: add adpcm_argo encoder avformat: add argo_asf muxer fate: add adpcm_argo test fate: cosmetics Changelog | 2 + doc/general.texi| 2 +- libavcodec/Makefile | 1 + libavcodec/adpcm.c | 10 +-- libavcodec/adpcm.h | 2 + libavcodec/adpcmenc.c | 86 ++- libavcodec/allcodecs.c | 1 + libavcodec/utils.c | 1 + libavcodec/version.h| 2 +- libavformat/Makefile| 1 + libavformat/allformats.c| 1 + libavformat/argo_asf.c | 133 +++- libavformat/version.h | 2 +- tests/fate/acodec.mak | 18 ++--- tests/ref/acodec/adpcm-argo | 4 ++ 15 files changed, 247 insertions(+), 19 deletions(-) create mode 100644 tests/ref/acodec/adpcm-argo -- 2.25.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 v2 2/6] avcodec/adpcm_argo: add ff_adpcm_argo_expand_nibble() and cleanup parameters
Replaces adpcm_argo_expand_nibble(). Preparation for the encoder. Signed-off-by: Zane van Iperen --- libavcodec/adpcm.c | 10 +- libavcodec/adpcm.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index b77f4b8ef6..1366932352 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -689,11 +689,11 @@ static void adpcm_swf_decode(AVCodecContext *avctx, const uint8_t *buf, int buf_ } } -static inline int16_t adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int control, int shift) +int16_t ff_adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int shift, int flag) { -int sample = nibble * (1 << shift); +int sample = sign_extend(nibble, 4) * (1 << shift); -if (control & 0x04) +if (flag) sample += (8 * cs->sample1) - (4 * cs->sample2); else sample += 4 * cs->sample1; @@ -2007,8 +2007,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, for (n = 0; n < nb_samples / 2; n++) { int sample = bytestream2_get_byteu(&gb); -*samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 4, 4), control, shift); -*samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 0, 4), control, shift); +*samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 4, shift, control & 0x04); +*samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 0, shift, control & 0x04); } } break; diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h index 580db7df8b..dc0d49ac61 100644 --- a/libavcodec/adpcm.h +++ b/libavcodec/adpcm.h @@ -45,4 +45,6 @@ typedef struct ADPCMChannelStatus { int idelta; } ADPCMChannelStatus; +int16_t ff_adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int shift, int flag); + #endif /* AVCODEC_ADPCM_H */ -- 2.25.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 v2 3/6] avcodec: add adpcm_argo encoder
Signed-off-by: Zane van Iperen --- Changelog | 1 + doc/general.texi | 2 +- libavcodec/Makefile| 1 + libavcodec/adpcmenc.c | 86 +- libavcodec/allcodecs.c | 1 + libavcodec/utils.c | 1 + libavcodec/version.h | 2 +- 7 files changed, 91 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index 959a2289ff..0f0fbf2abb 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,7 @@ version : - Rayman 2 APM muxer - AV1 encoding support SVT-AV1 - Cineform HD encoder +- ADPCM Argonaut Games encoder version 4.3: diff --git a/doc/general.texi b/doc/general.texi index dfcfd394e6..bfe2e98416 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -1098,7 +1098,7 @@ following image formats are supported: @item ACELP.KELVIN @tab @tab X @item ADPCM 4X Movie @tab @tab X @item APDCM Yamaha AICA @tab @tab X -@item ADPCM Argonaut Games @tab @tab X +@item ADPCM Argonaut Games @tab X @tab X @item ADPCM CDROM XA @tab @tab X @item ADPCM Creative Technology @tab @tab X @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 1417aeef98..fc4294816e 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -837,6 +837,7 @@ OBJS-$(CONFIG_ADPCM_AFC_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_ARGO_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_ARGO_ENCODER) += adpcm.o adpcmenc.o OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index adb7bf0bbf..24bd31c4a9 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -78,7 +78,8 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) } if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI || -avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM) { +avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM || +avctx->codec->id == AV_CODEC_ID_ADPCM_ARGO) { /* * The current trellis implementation doesn't work for extended * runs of samples without periodic resets. Disallow it. @@ -156,6 +157,10 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); avctx->extradata_size = 28; break; +case AV_CODEC_ID_ADPCM_ARGO: +avctx->frame_size = 32; +avctx->block_align = 17 * avctx->channels; +break; default: return AVERROR(EINVAL); } @@ -481,6 +486,46 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, c->idelta = nodes[0]->step; } +static inline int adpcm_argo_compress_nibble(const ADPCMChannelStatus *cs, int16_t s, + int shift, int flag) +{ +int nibble; + +if (flag) +nibble = 4 * s - 8 * cs->sample1 + 4 * cs->sample2; +else +nibble = 4 * s - 4 * cs->sample1; + +return (nibble >> shift) & 0x0F; +} + +static int64_t adpcm_argo_compress_block(ADPCMChannelStatus *cs, PutBitContext *pb, + const int16_t *samples, int nsamples, + int shift, int flag) +{ +int64_t error = 0; + +if (pb) { +put_bits(pb, 4, shift - 2); +put_bits(pb, 1, 0); +put_bits(pb, 1, !!flag); +put_bits(pb, 2, 0); +} + +for (int n = 0; n < nsamples; n++) { +/* Compress the nibble, then expand it to see how much precision we've lost. */ +int nibble = adpcm_argo_compress_nibble(cs, samples[n], shift, flag); +int16_t sample = ff_adpcm_argo_expand_nibble(cs, nibble, shift, flag); + +error += abs(samples[n] - sample); + +if (pb) +put_bits(pb, 4, nibble); +} + +return error; +} + static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { @@ -741,6 +786,44 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, flush_put_bits(&pb); break; } +case AV_CODEC_ID_ADPCM_ARGO: +{ +PutBitContext pb; +init_put_bits(&pb, dst, pkt_size); + +av_assert0(frame->nb_samples == 32); + +for (ch = 0; ch < avctx->channels; ch++) { +int64_t error = INT64_MAX, tmperr = INT64_MAX; +int shift = 2, flag = 0; +int saved1 = c->status[ch].sample1; +int saved2 = c->status[ch].sample2; + +/* Find the optimal coefficients, bail early if we find a perfect result. */
[FFmpeg-devel] [PATCH v2 4/6] avformat: add argo_asf muxer
Signed-off-by: Zane van Iperen --- Changelog| 1 + libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/argo_asf.c | 124 ++- libavformat/version.h| 2 +- 5 files changed, 127 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index 0f0fbf2abb..0108f8f1a8 100644 --- a/Changelog +++ b/Changelog @@ -12,6 +12,7 @@ version : - AV1 encoding support SVT-AV1 - Cineform HD encoder - ADPCM Argonaut Games encoder +- Argonaut Games ASF muxer version 4.3: diff --git a/libavformat/Makefile b/libavformat/Makefile index 62d8cbb54e..610d43ca99 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -103,6 +103,7 @@ OBJS-$(CONFIG_APTX_HD_DEMUXER) += aptxdec.o rawdec.o OBJS-$(CONFIG_APTX_HD_MUXER) += rawenc.o OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o OBJS-$(CONFIG_ARGO_ASF_DEMUXER) += argo_asf.o +OBJS-$(CONFIG_ARGO_ASF_MUXER)+= argo_asf.o OBJS-$(CONFIG_ASF_DEMUXER) += asfdec_f.o asf.o asfcrypt.o \ avlanguage.o OBJS-$(CONFIG_ASF_O_DEMUXER) += asfdec_o.o asf.o asfcrypt.o \ diff --git a/libavformat/allformats.c b/libavformat/allformats.c index fd9e46e233..b7e59ae170 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -64,6 +64,7 @@ extern AVInputFormat ff_aptx_hd_demuxer; extern AVOutputFormat ff_aptx_hd_muxer; extern AVInputFormat ff_aqtitle_demuxer; extern AVInputFormat ff_argo_asf_demuxer; +extern AVOutputFormat ff_argo_asf_muxer; extern AVInputFormat ff_asf_demuxer; extern AVOutputFormat ff_asf_muxer; extern AVInputFormat ff_asf_o_demuxer; diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index 9de64dfab4..6239d8eebb 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -1,5 +1,5 @@ /* - * Argonaut Games ASF demuxer + * Argonaut Games ASF (de)muxer * * Copyright (C) 2020 Zane van Iperen (z...@zanevaniperen.com) * @@ -63,6 +63,7 @@ typedef struct ArgoASFDemuxContext { uint32_tblocks_read; } ArgoASFDemuxContext; +#if CONFIG_ARGO_ASF_DEMUXER static void argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf) { hdr->magic = AV_RL32(buf + 0); @@ -254,3 +255,124 @@ AVInputFormat ff_argo_asf_demuxer = { .read_header= argo_asf_read_header, .read_packet= argo_asf_read_packet }; +#endif + +#if CONFIG_ARGO_ASF_MUXER +static int argo_asf_write_init(AVFormatContext *s) +{ +AVCodecParameters *par; + +if (s->nb_streams != 1) { +av_log(s, AV_LOG_ERROR, "ASF files have exactly one stream\n"); +return AVERROR(EINVAL); +} + +par = s->streams[0]->codecpar; + +if (par->codec_id != AV_CODEC_ID_ADPCM_ARGO) { +av_log(s, AV_LOG_ERROR, "%s codec not supported\n", + avcodec_get_name(par->codec_id)); +return AVERROR(EINVAL); +} + +if (par->channels > 2) { +av_log(s, AV_LOG_ERROR, "ASF files only support up to 2 channels\n"); +return AVERROR(EINVAL); +} + +if (par->sample_rate > UINT16_MAX) { +av_log(s, AV_LOG_ERROR, "Sample rate too large\n"); +return AVERROR(EINVAL); +} + +if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { +av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n"); +return AVERROR(EINVAL); +} + +return 0; +} + +static void argo_asf_write_file_header(const ArgoASFFileHeader *fhdr, AVIOContext *pb) +{ +avio_wl32( pb, fhdr->magic); +avio_wl16( pb, fhdr->version_major); +avio_wl16( pb, fhdr->version_minor); +avio_wl32( pb, fhdr->num_chunks); +avio_wl32( pb, fhdr->chunk_offset); +avio_write(pb, fhdr->name, sizeof(fhdr->name)); +} + +static void argo_asf_write_chunk_header(const ArgoASFChunkHeader *ckhdr, AVIOContext *pb) +{ +avio_wl32(pb, ckhdr->num_blocks); +avio_wl32(pb, ckhdr->num_samples); +avio_wl32(pb, ckhdr->unk1); +avio_wl16(pb, ckhdr->sample_rate); +avio_wl16(pb, ckhdr->unk2); +avio_wl32(pb, ckhdr->flags); +} + +static int argo_asf_write_header(AVFormatContext *s) +{ +AVCodecParameters *par = s->streams[0]->codecpar; +ArgoASFFileHeader fhdr; +ArgoASFChunkHeader chdr; + +fhdr.magic = ASF_TAG; +fhdr.version_major = 2; +fhdr.version_minor = 1; +fhdr.num_chunks= 1; +fhdr.chunk_offset = ASF_FILE_HEADER_SIZE; +strncpy(fhdr.name, av_basename(s->url), FF_ARRAY_ELEMS(fhdr.name)); + +chdr.num_blocks= 0; +chdr.num_samples = ASF_SAMPLE_COUNT; +chdr.unk1 = 0; +chdr.sample_rate = par->sample_rate; +chdr.unk2 = ~0; +chdr.flags = ASF_CF_BITS_PER_SAMPLE | ASF_CF_ALWAYS1; + +if (par->channels == 2) +chdr.flags |= ASF_CF_STEREO; + +argo_asf_write_file_header(&fhdr, s->pb); +argo_asf_write_chunk_header(&chdr, s->pb)
[FFmpeg-devel] [PATCH v2 6/6] fate: cosmetics
Signed-off-by: Zane van Iperen --- tests/fate/acodec.mak | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index 96ab0e587e..3e2a18435f 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -44,15 +44,15 @@ fate-acodec-pcm-u%be: FMT = nut fate-acodec-pcm-u%le: FMT = nut fate-acodec-pcm-f%be: FMT = au -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ARGO,ARGO_ASF) += argo -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_MS, WAV) += ms -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_SWF, FLV) += swf -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_YAMAHA, WAV) += yamaha +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_MS, WAV) += ms +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_SWF, FLV) += swf +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_YAMAHA, WAV) += yamaha FATE_ACODEC_ADPCM := $(FATE_ACODEC_ADPCM-yes:%=fate-acodec-adpcm-%) FATE_ACODEC += $(FATE_ACODEC_ADPCM) -- 2.25.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 v2 5/6] fate: add adpcm_argo test
Signed-off-by: Zane van Iperen --- tests/fate/acodec.mak | 2 ++ tests/ref/acodec/adpcm-argo | 4 2 files changed, 6 insertions(+) create mode 100644 tests/ref/acodec/adpcm-argo diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index 197b6ed7c0..96ab0e587e 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -45,6 +45,7 @@ fate-acodec-pcm-u%le: FMT = nut fate-acodec-pcm-f%be: FMT = au FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ARGO,ARGO_ASF) += argo FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi @@ -60,6 +61,7 @@ fate-acodec-adpcm: $(FATE_ACODEC_ADPCM) fate-acodec-adpcm-%: CODEC = adpcm_$(@:fate-acodec-adpcm-%=%) fate-acodec-adpcm-adx: FMT = adx +fate-acodec-adpcm-argo:FMT = argo_asf fate-acodec-adpcm-ima_apm: FMT = apm fate-acodec-adpcm-ima_qt: FMT = aiff fate-acodec-adpcm-ima_ssi: FMT = kvag diff --git a/tests/ref/acodec/adpcm-argo b/tests/ref/acodec/adpcm-argo new file mode 100644 index 00..127153c081 --- /dev/null +++ b/tests/ref/acodec/adpcm-argo @@ -0,0 +1,4 @@ +14b2507d14e95c20bb7ae49b4fcbcbf1 *tests/data/fate/acodec-adpcm-argo.argo_asf +281190 tests/data/fate/acodec-adpcm-argo.argo_asf +cc5e5c695adeaebaa2b1f0df5ebd59ee *tests/data/fate/acodec-adpcm-argo.out.wav +stddev: 1542.05 PSNR: 32.57 MAXDIFF:59667 bytes: 1058400/ 1058432 -- 2.25.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] AVWriter again (was: v2 1/2] avformat/url: check double dot is not to parent directory)
Zhao Zhili (12020-07-31): > So we can get a writer with AVIO context as backend, with custom stream > filters. > It do sound interesting, as long as it doesn't go too far like io in Java and > C++. The maze of twisty little APIs all alike is one of the reasons I try to minimize my interactions with C++ and Java. In particular, I do not plan on any kind of built-in inheritance, which is the doorway to this nightmare world. > It's valuable to support user allocated memory, however, I'm afraid string is > only > a small part of the use cases. I can reassure you: I wrote string, but everything is designed to be completely 8-bit clean, and can be used for any kind of binary data. Regards, -- Nicolas George 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 1/2] lavf/url: add ff_url_decompose().
Marton Balint (12020-08-04): > So you are returning NULL pointers here and success at the same time. This > does not look like a good idea, e.g. checking fields later on involves > arithmetic on NULL pointers, no? I don't really see it useful that we handle > NULL url here, we are better off with an assert IMHO. It only involves NULL+0 and NULL-NULL. But I see your concern. I removed this hunk and added instead: if (!base) base = ""; just before the call in the second patch. > This is the only place where we might return failure. Maybe we could convert > this to void() function to simplify usage a bit, and either > - assume no port, if it is not paraseable or > - not split host and port, so we don't have to parse IPv6 mess here, > therefore the error can't happen. I think catching invalid input as early and as often as possible is best. We need to update callers of ff_make_absolute_url() to handle truncated output anyway. Regards, -- Nicolas George 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 v2 4/6] avformat: add argo_asf muxer
On Tue, 04 Aug 2020 08:46:41 + "Zane van Iperen" wrote: Disregard, this breaks FATE. Will post a follow-up later. ___ 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 4/6] avformat: add argo_asf muxer
On Tue, 04 Aug 2020 09:27:35 + "Zane van Iperen" wrote: > > On Tue, 04 Aug 2020 08:46:41 + > "Zane van Iperen" wrote: > > Disregard, this breaks FATE. Will post a follow-up later. > Right, so there's two ways I can fix this, which would be the preferred option? 1. Explicitly tell FATE to use ASF: diff --git a/tests/fate/lavf-container.mak b/tests/fate/lavf-container.mak index 9e0eed4851..87dda63579 100644 --- a/tests/fate/lavf-container.mak +++ b/tests/fate/lavf-container.mak @@ -24,7 +24,7 @@ $(FATE_LAVF_CONTAINER): CMD = lavf_container $(FATE_LAVF_CONTAINER): REF = $(SRC_PATH)/tests/ref/lavf/$(@:fate-lavf-%=%) $(FATE_LAVF_CONTAINER): $(AREF) $(VREF) -fate-lavf-asf: CMD = lavf_container "" "-c:a mp2 -ar 44100" "-r 25" +fate-lavf-asf: CMD = lavf_container "" "-f asf -c:a mp2 -ar 44100" "-r 25" fate-lavf-avi fate-lavf-nut: CMD = lavf_container "" "-c:a mp2 -ar 44100 -threads 1" fate-lavf-dv: CMD = lavf_container "-ar 48000 -channel_layout stereo" "-r 25 -s pal" fate-lavf-dv_pal: CMD = lavf_container_timecode_nodrop "-ar 48000 -r 25 -s pal -ac 2 -f dv" 2. NULL'ify the extensions field of ff_argo_asf_muxer. Would require the user to specify "-f argo_asf" on the command line. This seems the nicer solution. diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index 6239d8eebb..01f8fc4dc7 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -367,7 +367,10 @@ static int argo_asf_write_trailer(AVFormatContext *s) AVOutputFormat ff_argo_asf_muxer = { .name = "argo_asf", .long_name = NULL_IF_CONFIG_SMALL("Argonaut Games ASF"), -.extensions = "asf", +/* + * Can't have this as it conflicts with the actual ASF format. + * .extensions = "asf", + */ .audio_codec= AV_CODEC_ID_ADPCM_ARGO, .video_codec= AV_CODEC_ID_NONE, .init = argo_asf_write_init, Zane ___ 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 4/4] lavc, doc: add libuavs3d video decoder wrapper
? On Mon, Jun 22, 2020 at 9:59 PM wrote: > > From: hwren > > Signed-off-by: hbj > Signed-off-by: hwren > --- > Changelog | 1 + > configure | 4 + > doc/decoders.texi | 21 +++ > doc/general.texi | 8 ++ > libavcodec/Makefile| 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/libuavs3d.c | 283 + > 7 files changed, 319 insertions(+) > create mode 100644 libavcodec/libuavs3d.c > > diff --git a/Changelog b/Changelog > index a60e7d2eb8..dfd56b3fc6 100644 > --- a/Changelog > +++ b/Changelog > @@ -4,6 +4,7 @@ releases are sorted from youngest to oldest. > version : > - AudioToolbox output device > - MacCaption demuxer > +- AVS3 video decoder via libuavs3d > > > version 4.3: > diff --git a/configure b/configure > index 7495f35faa..7340bc4a35 100755 > --- a/configure > +++ b/configure > @@ -274,6 +274,7 @@ External library support: >--enable-libtls enable LibreSSL (via libtls), needed for https > support > if openssl, gnutls or mbedtls is not used [no] >--enable-libtwolame enable MP2 encoding via libtwolame [no] > + --enable-libuavs3d enable AVS3 decoding via libuavs3d [no] >--enable-libv4l2 enable libv4l2/v4l-utils [no] >--enable-libvidstab enable video stabilization using vid.stab [no] >--enable-libvmaf enable vmaf filter via libvmaf [no] > @@ -1807,6 +1808,7 @@ EXTERNAL_LIBRARY_LIST=" > libtesseract > libtheora > libtwolame > +libuavs3d > libv4l2 > libvorbis > libvpx > @@ -3242,6 +3244,7 @@ libspeex_encoder_deps="libspeex" > libspeex_encoder_select="audio_frame_queue" > libtheora_encoder_deps="libtheora" > libtwolame_encoder_deps="libtwolame" > +libuavs3d_decoder_deps="libuavs3d" > libvo_amrwbenc_encoder_deps="libvo_amrwbenc" > libvorbis_decoder_deps="libvorbis" > libvorbis_encoder_deps="libvorbis libvorbisenc" > @@ -6379,6 +6382,7 @@ enabled libtls&& require_pkg_config libtls > libtls tls.h tls_configur > enabled libtwolame&& require libtwolame twolame.h twolame_init > -ltwolame && > { check_lib libtwolame twolame.h > twolame_encode_buffer_float32_interleaved -ltwolame || > die "ERROR: libtwolame must be installed and > version must be >= 0.3.10"; } > +enabled libuavs3d && require_pkg_config libuavs3d uavs3d uavs3d.h > uavs3d_decode > enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h > v4l2_ioctl > enabled libvidstab&& require_pkg_config libvidstab "vidstab >= 0.98" > vid.stab/libvidstab.h vsMotionDetectInit > enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.3.9" > libvmaf.h compute_vmaf > diff --git a/doc/decoders.texi b/doc/decoders.texi > index 9005714e3c..f1a0b3c36e 100644 > --- a/doc/decoders.texi > +++ b/doc/decoders.texi > @@ -86,6 +86,27 @@ AVS2-P2/IEEE1857.4 video decoder wrapper. > > This decoder allows libavcodec to decode AVS2 streams with davs2 library. > > +@c man end VIDEO DECODERS > + > +@section libuavs3d > + > +AVS3-P2/IEEE1857.10 video decoder. > + > +libuavs3d allows libavcodec to decode AVS3 streams. > +Requires the presence of the libuavs3d headers and library during > configuration. > +You need to explicitly configure the build with @code{--enable-libuavs3d}. > + > +@subsection Options > + > +The following option is supported by the libuavs3d wrapper. > + > +@table @option > + > +@item frame_threads > +Set amount of frame threads to use during decoding. The default value is 0 > (autodetect). > + > +@end table > + > @c man end VIDEO DECODERS > > @chapter Audio Decoders > diff --git a/doc/general.texi b/doc/general.texi > index 9b0ee96752..6d673b74e1 100644 > --- a/doc/general.texi > +++ b/doc/general.texi > @@ -125,6 +125,14 @@ Go to @url{https://github.com/pkuvcl/davs2} and follow > the instructions for > installing the library. Then pass @code{--enable-libdavs2} to configure to > enable it. > > +@section uavs3d > + > +FFmpeg can make use of the uavs3d library for AVS3-P2/IEEE1857.10 video > decoding. > + > +Go to @url{https://github.com/uavs3/uavs3d} and follow the instructions for > +installing the library. Then pass @code{--enable-libuavs3d} to configure to > +enable it. > + > @float NOTE > libdavs2 is under the GNU Public License Version 2 or later > (see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index f1512779be..491485f3c0 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -1026,6 +1026,7 @@ OBJS-$(CONFIG_LIBSPEEX_DECODER) += > libspeexdec.o > OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o > OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o > OBJS-$(CONFIG_LIBTWOLAME_ENCODER) += libtwolame.o > +OBJS-$(CONFIG_LIBUAVS3D_DECODER) += libuavs3
[FFmpeg-devel] [PATCH] avcodec: deprecate thread_safe_callbacks
They add considerable complexity to frame-threading implementation, which includes an unavoidably leaking error path, while the advantages of this option to the users are highly dubious. It should be always possible and desirable for the callers to make their get_buffer2() implementation thread-safe, so deprecate this option. --- doc/APIchanges | 4 +++ doc/multithreading.txt | 3 +- fftools/ffmpeg.c | 2 ++ libavcodec/avcodec.h | 7 libavcodec/pthread_frame.c | 69 +++--- libavcodec/thread.h| 4 +++ libavcodec/utils.c | 13 +++ libavcodec/version.h | 3 ++ 8 files changed, 99 insertions(+), 6 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 208258be05..44167a602b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2017-10-21 API changes, most recent first: +2020-xx-xx - xx - lavc 58.87.100 - avcodec.h + Deprecate AVCodecContext.thread_safe_callbacks. After the next major bump, + user callbacks must always be thread-safe when frame threading is used. + 2020-xx-xx - xx - lavc 58.87.100 - avcodec.h codec_par.h Move AVBitstreamFilter-related public API to new header bsf.h. Move AVCodecParameters-related public API to new header codec_par.h. diff --git a/doc/multithreading.txt b/doc/multithreading.txt index 4f645dc147..470194ff85 100644 --- a/doc/multithreading.txt +++ b/doc/multithreading.txt @@ -20,8 +20,7 @@ Slice threading - Frame threading - * Restrictions with slice threading also apply. -* For best performance, the client should set thread_safe_callbacks if it - provides a thread-safe get_buffer() callback. +* Custom get_buffer2() and get_format() callbacks must be thread-safe. * There is one frame of delay added for every thread beyond the first one. Clients must be able to handle this; the pkt_dts and pkt_pts fields in AVFrame will work as usual. diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index ad95a0e417..eed72b67f1 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -2883,7 +2883,9 @@ static int init_input_stream(int ist_index, char *error, int error_len) ist->dec_ctx->opaque= ist; ist->dec_ctx->get_format= get_format; ist->dec_ctx->get_buffer2 = get_buffer; +#if LIBAVCODEC_VERSION_MAJOR < 59 ist->dec_ctx->thread_safe_callbacks = 1; +#endif av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index f10b7a06ec..2dec0d8ca0 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1934,6 +1934,7 @@ typedef struct AVCodecContext { */ int active_thread_type; +#if FF_API_THREAD_SAFE_CALLBACKS /** * Set by the client if its custom get_buffer() callback can be called * synchronously from another thread, which allows faster multithreaded decoding. @@ -1941,8 +1942,14 @@ typedef struct AVCodecContext { * Ignored if the default get_buffer() is used. * - encoding: Set by user. * - decoding: Set by user. + * + * @deprecated the custom get_buffer2() callback should always be + * thread-safe. Thread-unsafe get_buffer2() implementations will be + * invalid once this field is removed. */ +attribute_deprecated int thread_safe_callbacks; +#endif /** * The codec may call this to execute several independent things. diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 64121f5a9a..75722e359e 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -89,6 +89,7 @@ typedef struct PerThreadContext { atomic_int state; +#if FF_API_THREAD_SAFE_CALLBACKS /** * Array of frames passed to ff_thread_release_buffer(). * Frames are released after all threads referencing them are finished. @@ -102,6 +103,7 @@ typedef struct PerThreadContext { const enum AVPixelFormat *available_formats; ///< Format array for get_format() enum AVPixelFormat result_format;///< get_format() result +#endif int die;///< Set when the thread should exit. @@ -137,8 +139,10 @@ typedef struct FrameThreadContext { */ } FrameThreadContext; +#if FF_API_THREAD_SAFE_CALLBACKS #define THREAD_SAFE_CALLBACKS(avctx) \ ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == avcodec_default_get_buffer2) +#endif static void async_lock(FrameThreadContext *fctx) { @@ -178,8 +182,14 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (p->die) break; -if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx)) +FF_DISABLE_DEPRECATION_WARNINGS +if (!codec->update_thread_context +#if FF_API_THREAD_SAFE_CALLBACKS +&& THREAD_SAFE_CALLB
Re: [FFmpeg-devel] [v5] dnn_backend_native_layer_mathunary: add ceil support
> -Original Message- > From: ffmpeg-devel On Behalf Of Mingyu > Yin > Sent: 2020年8月3日 19:17 > To: ffmpeg-devel@ffmpeg.org > Subject: [FFmpeg-devel] [v5] dnn_backend_native_layer_mathunary: add ceil > support > > It can be tested with the model generated with below python script: > > import tensorflow as tf > import os > import numpy as np > import imageio > from tensorflow.python.framework import graph_util name = 'ceil' > > pb_file_path = os.getcwd() > if not os.path.exists(pb_file_path+'/{}_savemodel/'.format(name)): > os.mkdir(pb_file_path+'/{}_savemodel/'.format(name)) > > with tf.Session(graph=tf.Graph()) as sess: > in_img = imageio.imread('detection.jpg') > in_img = in_img.astype(np.float32) > in_data = in_img[np.newaxis, :] > input_x = tf.placeholder(tf.float32, shape=[1, None, None, 3], > name='dnn_in') > y_ = tf.math.ceil(input_x*255)/255 > y = tf.identity(y_, name='dnn_out') > sess.run(tf.global_variables_initializer()) > constant_graph = graph_util.convert_variables_to_constants(sess, > sess.graph_def, ['dnn_out']) > > with > tf.gfile.FastGFile(pb_file_path+'/{}_savemodel/model.pb'.format(name), > mode='wb') as f: > f.write(constant_graph.SerializeToString()) > > print("model.pb generated, please in ffmpeg path use\n \n \ > python tools/python/convert.py ceil_savemodel/model.pb > --outdir=ceil_savemodel/ \n \nto generate model.model\n") > > output = sess.run(y, feed_dict={ input_x: in_data}) > imageio.imsave("out.jpg", np.squeeze(output)) > > print("To verify, please ffmpeg path use\n \n \ > ./ffmpeg -i detection.jpg -vf > format=rgb24,dnn_processing=model=ceil_savemodel/model.pb:input=dnn_in: > output=dnn_out:dnn_backend=tensorflow -f framemd5 > ceil_savemodel/tensorflow_out.md5\n \ > or\n \ > ./ffmpeg -i detection.jpg -vf > format=rgb24,dnn_processing=model=ceil_savemodel/model.pb:input=dnn_in: > output=dnn_out:dnn_backend=tensorflow ceil_savemodel/out_tensorflow.jpg\n > \nto generate output result of tensorflow model\n") > > print("To verify, please ffmpeg path use\n \n \ > ./ffmpeg -i detection.jpg -vf > format=rgb24,dnn_processing=model=ceil_savemodel/model.model:input=dnn > _in:output=dnn_out:dnn_backend=native -f framemd5 > ceil_savemodel/native_out.md5\n \ > or \n \ > ./ffmpeg -i detection.jpg -vf > format=rgb24,dnn_processing=model=ceil_savemodel/model.model:input=dnn > _in:output=dnn_out:dnn_backend=native ceil_savemodel/out_native.jpg\n \nto > generate output result of native model\n") > > Signed-off-by: Mingyu Yin > --- > libavfilter/dnn/dnn_backend_native_layer_mathunary.c | 4 > libavfilter/dnn/dnn_backend_native_layer_mathunary.h | 1 + > tests/dnn/dnn-layer-mathunary-test.c | 4 > tools/python/convert_from_tensorflow.py | 4 +++- > tools/python/convert_header.py | 2 +- > 5 files changed, 13 insertions(+), 2 deletions(-) LGTM, will push soon, thanks. ___ 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] avutil/opt: Restore NULL input handling to set_string_video_rate()
I think we're talking past each other. You're asking me to demonstrate a current way in which NULL might be passed to this function. I don't think it's necessary to do that in order for this patch to be a good idea. > Is this about something iam missing or a lib user passing invalidly > setup AVOptions ? (he should fix his code) Absolutely, he should fix his code. But let's say some code gets by code review that has a corner case whereby NULL can be passed. Isn't it better for that condition to be handled cleanly (as it was before a500b975) rather than causing undefined behaviour? Then the error will be reported to the user with a clear error message and can be diagnosed and fixed quickly. Currently, what happens in this case will be implementation-dependent, making it much more difficult to diagnose. To be clear, I do not have a specific case in mind that will currently pass NULL to this function. The point of this patch is to stop relying on all current and future callers to this function always being completely bug-free, but instead to handle any error condition properly, as it is at most of the other av_parse_video_rate callsites. Could you explain why you would not want to do that? Thanks Jack On Mon, Aug 3, 2020 at 11:27 PM Michael Niedermayer wrote: > On Mon, Aug 03, 2020 at 02:07:36PM +0100, Jack Haughton wrote: > > A NULL check in av_parse_video_rate() would certainly not be a bad idea. > It > > wouldn't (on its own) restore the NULL input robustness to > > set_string_video_rate() though, as any error value returned from > > av_parse_video_rate() would result in val being logged using %s, which is > > the whole problem that a500b975 was aiming to solve. > > > > av_parse_video_rate() is also called from a lot more places (most of > which > > already have an explicit NULL check immediately before the call), so > > changing the behaviour of that function by adding a NULL check > potentially > > has a lot more knock-on effects than simply restoring the previously > > existing robustness to set_string_video_rate(), which is also in keeping > > with the other av_parse_video_rate() callsites. > > > > You say that the caller 'should not' pass NULL to > set_string_video_rate(). > > Absolutely, agreed, but the point of checks is to handle unexpected > > situations. > > > If someone does pass NULL, as of a500b975 the response will be > > who is passing NULL in which way ? > this is not a public function > > You can achieve such a NULL input by seting up an invalid AVOption > but you dont seem to speak about that. > > please explain what sort of robustness you want to achieve here > Is this about something iam missing or a lib user passing invalidly > setup AVOptions ? (he should fix his code) or some FFmpeg internal > robustness or what else ? > > > > undefined behaviour, where previously it would have been cleanly handled > > with an explicit error code. I'd contend that this is a bad response. > > > thx > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > If a bugfix only changes things apparently unrelated to the bug with no > further explanation, that is a good sign that the bugfix is wrong. > ___ > 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". -- Argon Design Ltd., Registration No. 06977690, a Broadcom Inc. company Registered in England with registered office at St John's Innovation Centre, Cowley Road, Cambridge, CB4 0WS ___ 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] avutil/opt: Restore NULL input handling to set_string_video_rate()
Jack Haughton (12020-08-04): > Absolutely, he should fix his code. But let's say some code gets by code > review that has a corner case whereby NULL can be passed. Isn't it better > for that condition to be handled cleanly (as it was before a500b975) rather > than causing undefined behaviour? Then the error will be reported to the > user with a clear error message and can be diagnosed and fixed quickly. > Currently, what happens in this case will be implementation-dependent, > making it much more difficult to diagnose. It depends on what kind of undefined behavior we are talking about. Here, it is about dereferencing NULL, which always result in a segmentation fault, and if we really want to make sure, we can force it with an assert. What you are advocating is a typical example of what is called "defensive programming". When there is some invariant that the code is supposed to enforce (here: a pointer that should not be NULL), defensive programming involves making provisions so that the programs continues even if that invariant is broken. The thing is: defensive programming is almost always wrong. If an invariant is broken, that means there is a bug. We do not know which bug, but there is a bug. And since we do not know what it is, we have to assume the worst is possible: exploitable security issue, silent data corruption. And even if the worst does not happen, defensive programming makes debugging harder: it hides the bugs, let the program seems to work, or it delays the manifestation of the bug, and therefore requires more work to track it. Also note that people will (irrationally) be in more hurry to fix a crash than to fix an error message that looks clean. In this kind of cases, we have to ask ourselves a series of questions: 1. Is it convenient to let the caller pass NULL and have a sane result? → For free(), yes. → For av_parse_video_rate(), no, so we go to the next question. 2. Is it easy for the caller to check the validity of the parameter? → For == NULL, yes. Then the correct way of dealing with it is (1) document "the parameter must not be NULL", (2) make sure it crashes early if the parameter is NULL. Regards, -- Nicolas George 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] swscale: do not drop half of bits from 16bit bayer formats
On Sun, Aug 02, 2020 at 03:58:10PM +0200, Paul B Mahol wrote: > Hi, > > patch attached. > bayer_template.c | 102 > + > swscale_internal.h |7 +++ > swscale_unscaled.c | 51 ++ > utils.c|5 +- > 4 files changed, 163 insertions(+), 2 deletions(-) > 6fb8bd615c38a7dcdb72a6bdfa6a92b6642c82e9 > 0001-swscale-do-not-drop-half-of-bits-from-16bit-bayer-fo.patch > From 2bab34d069edea75e9f6c5fc31e50d40cd1ab8f0 Mon Sep 17 00:00:00 2001 > From: Paul B Mahol > Date: Sun, 2 Aug 2020 15:55:38 +0200 > Subject: [PATCH] swscale: do not drop half of bits from 16bit bayer formats LGTM if tested thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I have never wished to cater to the crowd; for what I know they do not approve, and what they approve I do not know. -- Epicurus 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] avcodec/mpegaudiodec_template: Check CRCs for layer1 and layer2
On Mon, Aug 03, 2020 at 08:53:41PM +0200, Lynne wrote: > Aug 3, 2020, 18:31 by mich...@niedermayer.cc: > > > This differs from the MPEG specification as the actual real world > > files do compute their CRC over variable areas and not the fixed > > ones listed in the specification. This is also the reason for > > the complexity of this code and the need to perform the CRC > > check for layer2 in the middle of layer2 decoding. > > > > Signed-off-by: Michael Niedermayer > > --- > > libavcodec/mpegaudiodec_template.c | 61 +- > > 1 file changed, 44 insertions(+), 17 deletions(-) > > > > diff --git a/libavcodec/mpegaudiodec_template.c > > b/libavcodec/mpegaudiodec_template.c > > index 3d7e3ba4f2..d84e4f1cb6 100644 > > --- a/libavcodec/mpegaudiodec_template.c > > +++ b/libavcodec/mpegaudiodec_template.c > > @@ -89,6 +89,7 @@ typedef struct MPADecodeContext { > > MPADSPContext mpadsp; > > AVFloatDSPContext *fdsp; > > AVFrame *frame; > > +int crc; > > > > Make this a uint32_t, its what we always store CRCs as even if they're 8 bits. > Thought it was a flag on first read. > > > > > } MPADecodeContext; > > > > #define HEADER_SIZE 4 > > @@ -500,12 +501,43 @@ static void imdct12(INTFLOAT *out, SUINTFLOAT *in) > > out[11] = in0 + in5; > > } > > > > +static int handle_crc(MPADecodeContext *s, int sec_len) > > +{ > > +if (s->error_protection && (s->err_recognition & AV_EF_CRCCHECK)) { > > +const uint8_t *buf = s->gb.buffer - HEADER_SIZE; > > +int sec_byte_len = sec_len >> 3; > > +int sec_rem_bits = sec_len & 7; > > +const AVCRC *crc_tab = av_crc_get_table(AV_CRC_16_ANSI); > > +uint8_t tmp_buf[4]; > > +uint32_t crc_val = av_crc(crc_tab, UINT16_MAX, &buf[2], 2); > > +crc_val = av_crc(crc_tab, crc_val, &buf[6], sec_byte_len); > > + > > +AV_WB32(tmp_buf, > > +((buf[6 + sec_byte_len] & (0xFF00>>sec_rem_bits))<<24) + > > +((unsigned)(s->crc<<16) >> sec_rem_bits)); > > > > If s->crc is a uint32_t then you don't need to cast it here. > Also argument alignment seems wrong, we align each new line of a function > call/macro with the starting bracket rather than just 4 spaces. > And some spaces in between the shift operators would be nice. > > > > +crc_val = av_crc(crc_tab, crc_val, tmp_buf, 3); > > + > > +if (crc_val) { > > +av_log(s->avctx, AV_LOG_ERROR, "CRC mismatch %X!\n", crc_val); > > > > Good idea, printing the difference was very useful when I was debugging, > we should do that everywhere. > > > How this works was a little confusing at first but makes sense for me, > so apart from those comments patch LGTM, thanks. ok, will apply with the suggested changes thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Rewriting code that is poorly written but fully understood is good. Rewriting code that one doesnt understand is a sign that one is less smart then the original author, trying to rewrite it will not make it better. 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".
[FFmpeg-devel] [PATCH] libavcodec/j2kenc: Allow Encoder to use SOP and EPH markers
From: Gautam Ramakrishnan This patch allows the encoder to use SOP and EPH markers. This would be useful as these markers provide better error detection mechanisms. --- libavcodec/j2kenc.c | 28 ++-- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 5ebc1f3a99..fad013521b 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -129,6 +129,8 @@ typedef struct { int format; int pred; +int sop; +int eph; } Jpeg2000EncoderContext; @@ -308,13 +310,18 @@ static int put_siz(Jpeg2000EncoderContext *s) static int put_cod(Jpeg2000EncoderContext *s) { Jpeg2000CodingStyle *codsty = &s->codsty; +uint8_t scod = 0; if (s->buf_end - s->buf < 14) return -1; bytestream_put_be16(&s->buf, JPEG2000_COD); bytestream_put_be16(&s->buf, 12); // Lcod -bytestream_put_byte(&s->buf, 0); // Scod +if (s->sop) +scod |= JPEG2000_CSTY_SOP; +if (s->eph) +scod |= JPEG2000_CSTY_EPH; +bytestream_put_byte(&s->buf, scod); // Scod // SGcod bytestream_put_byte(&s->buf, 0); // progression level bytestream_put_be16(&s->buf, 1); // num of layers @@ -719,14 +726,18 @@ static void putnumpasses(Jpeg2000EncoderContext *s, int n) static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, int precno, - uint8_t *expn, int numgbits) + uint8_t *expn, int numgbits, int packetno) { int bandno, empty = 1; - // init bitstream *s->buf = 0; s->bit_index = 0; +if (s->sop) { +bytestream_put_be16(&s->buf, JPEG2000_SOP); +bytestream_put_be16(&s->buf, 4); +bytestream_put_be16(&s->buf, packetno); +} // header // is the packet empty? @@ -794,6 +805,10 @@ static int encode_packet(Jpeg2000EncoderContext *s, Jpeg2000ResLevel *rlevel, in } } j2k_flush(s); +if (s->eph) { +bytestream_put_be16(&s->buf, JPEG2000_EPH); +} + for (bandno = 0; bandno < rlevel->nbands; bandno++){ Jpeg2000Band *band = rlevel->band + bandno; Jpeg2000Prec *prec = band->prec + precno; @@ -821,7 +836,7 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til int compno, reslevelno, ret; Jpeg2000CodingStyle *codsty = &s->codsty; Jpeg2000QuantStyle *qntsty = &s->qntsty; - +int packetno = 0; av_log(s->avctx, AV_LOG_DEBUG, "tier2\n"); // lay-rlevel-comp-pos progression for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ @@ -830,7 +845,7 @@ static int encode_packets(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int til Jpeg2000ResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ if ((ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), - qntsty->nguardbits)) < 0) + qntsty->nguardbits, packetno++)) < 0) return ret; } } @@ -1244,7 +1259,8 @@ static const AVOption options[] = { { "pred", "DWT Type", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "pred" }, { "dwt97int", NULL,0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, { "dwt53", NULL,0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, - +{ "sop", "SOP marker",OFFSET(sop), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, +{ "eph", "EPH marker",OFFSET(eph), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, { NULL } }; -- 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 1/2] avformat/mov: Check comp_brand_size
On Sun, Aug 02, 2020 at 01:23:22AM +0200, Michael Niedermayer wrote: > Fixes: signed integer overflow: 2147483647 + 1 cannot be represented in type > 'int' > Fixes: > 24457/clusterfuzz-testcase-minimized-ffmpeg_DEMUXER_fuzzer-5760093644390400 > > Found-by: continuous fuzzing process > https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > Signed-off-by: Michael Niedermayer > --- > libavformat/mov.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) will apply [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The educated differ from the uneducated as much as the living from the dead. -- Aristotle 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] avcodec: deprecate thread_safe_callbacks
On 8/4/2020 8:59 AM, Anton Khirnov wrote: > They add considerable complexity to frame-threading implementation, > which includes an unavoidably leaking error path, while the advantages > of this option to the users are highly dubious. > > It should be always possible and desirable for the callers to make their > get_buffer2() implementation thread-safe, so deprecate this option. > --- > doc/APIchanges | 4 +++ > doc/multithreading.txt | 3 +- > fftools/ffmpeg.c | 2 ++ > libavcodec/avcodec.h | 7 > libavcodec/pthread_frame.c | 69 +++--- > libavcodec/thread.h| 4 +++ > libavcodec/utils.c | 13 +++ > libavcodec/version.h | 3 ++ > 8 files changed, 99 insertions(+), 6 deletions(-) > > diff --git a/doc/APIchanges b/doc/APIchanges > index 208258be05..44167a602b 100644 > --- a/doc/APIchanges > +++ b/doc/APIchanges > @@ -15,6 +15,10 @@ libavutil: 2017-10-21 > > API changes, most recent first: > > +2020-xx-xx - xx - lavc 58.87.100 - avcodec.h > + Deprecate AVCodecContext.thread_safe_callbacks. After the next major bump, Maybe "Once removed" or similar instead, like you added to the field's doxy. > + user callbacks must always be thread-safe when frame threading is used. > + > 2020-xx-xx - xx - lavc 58.87.100 - avcodec.h codec_par.h >Move AVBitstreamFilter-related public API to new header bsf.h. >Move AVCodecParameters-related public API to new header codec_par.h. > diff --git a/doc/multithreading.txt b/doc/multithreading.txt > index 4f645dc147..470194ff85 100644 > --- a/doc/multithreading.txt > +++ b/doc/multithreading.txt > @@ -20,8 +20,7 @@ Slice threading - > > Frame threading - > * Restrictions with slice threading also apply. > -* For best performance, the client should set thread_safe_callbacks if it > - provides a thread-safe get_buffer() callback. > +* Custom get_buffer2() and get_format() callbacks must be thread-safe. > * There is one frame of delay added for every thread beyond the first one. >Clients must be able to handle this; the pkt_dts and pkt_pts fields in >AVFrame will work as usual. > diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c > index ad95a0e417..eed72b67f1 100644 > --- a/fftools/ffmpeg.c > +++ b/fftools/ffmpeg.c > @@ -2883,7 +2883,9 @@ static int init_input_stream(int ist_index, char > *error, int error_len) > ist->dec_ctx->opaque= ist; > ist->dec_ctx->get_format= get_format; > ist->dec_ctx->get_buffer2 = get_buffer; > +#if LIBAVCODEC_VERSION_MAJOR < 59 > ist->dec_ctx->thread_safe_callbacks = 1; > +#endif > > av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); > if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h > index f10b7a06ec..2dec0d8ca0 100644 > --- a/libavcodec/avcodec.h > +++ b/libavcodec/avcodec.h > @@ -1934,6 +1934,7 @@ typedef struct AVCodecContext { > */ > int active_thread_type; > > +#if FF_API_THREAD_SAFE_CALLBACKS > /** > * Set by the client if its custom get_buffer() callback can be called > * synchronously from another thread, which allows faster multithreaded > decoding. > @@ -1941,8 +1942,14 @@ typedef struct AVCodecContext { > * Ignored if the default get_buffer() is used. > * - encoding: Set by user. > * - decoding: Set by user. > + * > + * @deprecated the custom get_buffer2() callback should always be > + * thread-safe. Thread-unsafe get_buffer2() implementations will be > + * invalid once this field is removed. > */ > +attribute_deprecated > int thread_safe_callbacks; > +#endif > > /** > * The codec may call this to execute several independent things. > diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c > index 64121f5a9a..75722e359e 100644 > --- a/libavcodec/pthread_frame.c > +++ b/libavcodec/pthread_frame.c > @@ -89,6 +89,7 @@ typedef struct PerThreadContext { > > atomic_int state; > > +#if FF_API_THREAD_SAFE_CALLBACKS > /** > * Array of frames passed to ff_thread_release_buffer(). > * Frames are released after all threads referencing them are finished. > @@ -102,6 +103,7 @@ typedef struct PerThreadContext { > > const enum AVPixelFormat *available_formats; ///< Format array for > get_format() > enum AVPixelFormat result_format;///< get_format() result > +#endif > > int die;///< Set when the thread should exit. > > @@ -137,8 +139,10 @@ typedef struct FrameThreadContext { > */ > } FrameThreadContext; > > +#if FF_API_THREAD_SAFE_CALLBACKS > #define THREAD_SAFE_CALLBACKS(avctx) \ > ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == > avcodec_default_get_buffer2) > +#endif > > static void async_lock(Fra
Re: [FFmpeg-devel] [PATCH] libavcodec/libx264.c: Fix chromaoffset of libx264 doesn't work
On Tue, Jul 28, 2020 at 3:30 PM Takio Yamaoka wrote: > > An initial value of `AVCodecContext::chromaoffset` is zero, > then it causes to block `-chromaoffset` setting as result. > In addition, even though a negative number of `chromaoffset` > is meaningful, `X264Context::chroma_offset` is initialized > with `-1` as no setting and ignored if it is negative number. > > To fix above, it changes ... > - a value of `X264Context::chroma_offset` to 0 as no setting > - due to x264's default value > - conditional statement to import `-chromaoffset` > > Signed-off-by: Takio Yamaoka > --- > libavcodec/libx264.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c > index 7bbeab7d4c..347d29df27 100644 > --- a/libavcodec/libx264.c > +++ b/libavcodec/libx264.c > @@ -681,11 +681,11 @@ static av_cold int X264_init(AVCodecContext *avctx) > > #if FF_API_PRIVATE_OPT > FF_DISABLE_DEPRECATION_WARNINGS > -if (avctx->chromaoffset >= 0) > +if (avctx->chromaoffset) > x4->chroma_offset = avctx->chromaoffset; > FF_ENABLE_DEPRECATION_WARNINGS > #endif > -if (x4->chroma_offset >= 0) > +if (x4->chroma_offset) > x4->params.analyse.i_chroma_qp_offset = x4->chroma_offset; > > if (avctx->gop_size >= 0) > @@ -1140,7 +1140,7 @@ static const AVOption options[] = { > { "vlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, > INT_MIN, INT_MAX, VE, "coder" }, > { "ac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, > INT_MIN, INT_MAX, VE, "coder" }, > { "b_strategy", "Strategy to choose between I/P/B-frames", > OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2, VE }, > -{ "chromaoffset", "QP difference between chroma and luma", > OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE }, > +{ "chromaoffset", "QP difference between chroma and luma", > OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE }, > { "sc_threshold", "Scene change threshold", > OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, > INT_MAX, VE }, > { "noise_reduction", "Noise reduction", > OFFSET(noise_reduction), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE > }, > General change looks alright to me, after checking the following points. - AVCodecContext's chromaoffset indeed defaults to 0 through the DEFAULT define (#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C) - x264 default is 0 (thus we thankfully haven't overwritten this before, and the patch doesn't lead to a change in that behavior, either) - value in x264 can be between -12 and 12, thus both positive and negative values indeed can be set (x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12) can be found in x264's code) Best regards, Jan ___ 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 0/6] add adpcm_argo encoder and argo_asf muxer
v3: * fix FATE failure (lavf-asf) caused by "asf" extension conflict v2: [1] * enforce the samples-per-block value in the demuxer * remove unnecessary initialisers * add missing return when stream isn't seekable * change a sequence of avio_wl8()s to an avio_write() * add write_packet() and check packet sizes * use AVStream::nb_frames instead of calculating the value * fix Makefile dependencies Zane van Iperen (6): avformat/argo_asf: check sample count in demuxer avcodec/adpcm_argo: add ff_adpcm_argo_expand_nibble() and cleanup parameters avcodec: add adpcm_argo encoder avformat: add argo_asf muxer fate: add adpcm_argo test fate: cosmetics Changelog | 2 + doc/general.texi| 2 +- libavcodec/Makefile | 1 + libavcodec/adpcm.c | 10 +-- libavcodec/adpcm.h | 2 + libavcodec/adpcmenc.c | 86 ++- libavcodec/allcodecs.c | 1 + libavcodec/utils.c | 1 + libavcodec/version.h| 2 +- libavformat/Makefile| 1 + libavformat/allformats.c| 1 + libavformat/argo_asf.c | 136 +++- libavformat/version.h | 2 +- tests/fate/acodec.mak | 18 ++--- tests/ref/acodec/adpcm-argo | 4 ++ 15 files changed, 250 insertions(+), 19 deletions(-) create mode 100644 tests/ref/acodec/adpcm-argo -- 2.25.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 5/6] fate: add adpcm_argo test
Signed-off-by: Zane van Iperen --- tests/fate/acodec.mak | 2 ++ tests/ref/acodec/adpcm-argo | 4 2 files changed, 6 insertions(+) create mode 100644 tests/ref/acodec/adpcm-argo diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index 197b6ed7c0..96ab0e587e 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -45,6 +45,7 @@ fate-acodec-pcm-u%le: FMT = nut fate-acodec-pcm-f%be: FMT = au FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ARGO,ARGO_ASF) += argo FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi @@ -60,6 +61,7 @@ fate-acodec-adpcm: $(FATE_ACODEC_ADPCM) fate-acodec-adpcm-%: CODEC = adpcm_$(@:fate-acodec-adpcm-%=%) fate-acodec-adpcm-adx: FMT = adx +fate-acodec-adpcm-argo:FMT = argo_asf fate-acodec-adpcm-ima_apm: FMT = apm fate-acodec-adpcm-ima_qt: FMT = aiff fate-acodec-adpcm-ima_ssi: FMT = kvag diff --git a/tests/ref/acodec/adpcm-argo b/tests/ref/acodec/adpcm-argo new file mode 100644 index 00..127153c081 --- /dev/null +++ b/tests/ref/acodec/adpcm-argo @@ -0,0 +1,4 @@ +14b2507d14e95c20bb7ae49b4fcbcbf1 *tests/data/fate/acodec-adpcm-argo.argo_asf +281190 tests/data/fate/acodec-adpcm-argo.argo_asf +cc5e5c695adeaebaa2b1f0df5ebd59ee *tests/data/fate/acodec-adpcm-argo.out.wav +stddev: 1542.05 PSNR: 32.57 MAXDIFF:59667 bytes: 1058400/ 1058432 -- 2.25.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 4/6] avformat: add argo_asf muxer
Signed-off-by: Zane van Iperen --- Changelog| 1 + libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/argo_asf.c | 127 ++- libavformat/version.h| 2 +- 5 files changed, 130 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index 0f0fbf2abb..0108f8f1a8 100644 --- a/Changelog +++ b/Changelog @@ -12,6 +12,7 @@ version : - AV1 encoding support SVT-AV1 - Cineform HD encoder - ADPCM Argonaut Games encoder +- Argonaut Games ASF muxer version 4.3: diff --git a/libavformat/Makefile b/libavformat/Makefile index 62d8cbb54e..610d43ca99 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -103,6 +103,7 @@ OBJS-$(CONFIG_APTX_HD_DEMUXER) += aptxdec.o rawdec.o OBJS-$(CONFIG_APTX_HD_MUXER) += rawenc.o OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o OBJS-$(CONFIG_ARGO_ASF_DEMUXER) += argo_asf.o +OBJS-$(CONFIG_ARGO_ASF_MUXER)+= argo_asf.o OBJS-$(CONFIG_ASF_DEMUXER) += asfdec_f.o asf.o asfcrypt.o \ avlanguage.o OBJS-$(CONFIG_ASF_O_DEMUXER) += asfdec_o.o asf.o asfcrypt.o \ diff --git a/libavformat/allformats.c b/libavformat/allformats.c index fd9e46e233..b7e59ae170 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -64,6 +64,7 @@ extern AVInputFormat ff_aptx_hd_demuxer; extern AVOutputFormat ff_aptx_hd_muxer; extern AVInputFormat ff_aqtitle_demuxer; extern AVInputFormat ff_argo_asf_demuxer; +extern AVOutputFormat ff_argo_asf_muxer; extern AVInputFormat ff_asf_demuxer; extern AVOutputFormat ff_asf_muxer; extern AVInputFormat ff_asf_o_demuxer; diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index 9de64dfab4..8e6b312521 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -1,5 +1,5 @@ /* - * Argonaut Games ASF demuxer + * Argonaut Games ASF (de)muxer * * Copyright (C) 2020 Zane van Iperen (z...@zanevaniperen.com) * @@ -63,6 +63,7 @@ typedef struct ArgoASFDemuxContext { uint32_tblocks_read; } ArgoASFDemuxContext; +#if CONFIG_ARGO_ASF_DEMUXER static void argo_asf_parse_file_header(ArgoASFFileHeader *hdr, const uint8_t *buf) { hdr->magic = AV_RL32(buf + 0); @@ -254,3 +255,127 @@ AVInputFormat ff_argo_asf_demuxer = { .read_header= argo_asf_read_header, .read_packet= argo_asf_read_packet }; +#endif + +#if CONFIG_ARGO_ASF_MUXER +static int argo_asf_write_init(AVFormatContext *s) +{ +AVCodecParameters *par; + +if (s->nb_streams != 1) { +av_log(s, AV_LOG_ERROR, "ASF files have exactly one stream\n"); +return AVERROR(EINVAL); +} + +par = s->streams[0]->codecpar; + +if (par->codec_id != AV_CODEC_ID_ADPCM_ARGO) { +av_log(s, AV_LOG_ERROR, "%s codec not supported\n", + avcodec_get_name(par->codec_id)); +return AVERROR(EINVAL); +} + +if (par->channels > 2) { +av_log(s, AV_LOG_ERROR, "ASF files only support up to 2 channels\n"); +return AVERROR(EINVAL); +} + +if (par->sample_rate > UINT16_MAX) { +av_log(s, AV_LOG_ERROR, "Sample rate too large\n"); +return AVERROR(EINVAL); +} + +if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { +av_log(s, AV_LOG_ERROR, "Stream not seekable, unable to write output file\n"); +return AVERROR(EINVAL); +} + +return 0; +} + +static void argo_asf_write_file_header(const ArgoASFFileHeader *fhdr, AVIOContext *pb) +{ +avio_wl32( pb, fhdr->magic); +avio_wl16( pb, fhdr->version_major); +avio_wl16( pb, fhdr->version_minor); +avio_wl32( pb, fhdr->num_chunks); +avio_wl32( pb, fhdr->chunk_offset); +avio_write(pb, fhdr->name, sizeof(fhdr->name)); +} + +static void argo_asf_write_chunk_header(const ArgoASFChunkHeader *ckhdr, AVIOContext *pb) +{ +avio_wl32(pb, ckhdr->num_blocks); +avio_wl32(pb, ckhdr->num_samples); +avio_wl32(pb, ckhdr->unk1); +avio_wl16(pb, ckhdr->sample_rate); +avio_wl16(pb, ckhdr->unk2); +avio_wl32(pb, ckhdr->flags); +} + +static int argo_asf_write_header(AVFormatContext *s) +{ +AVCodecParameters *par = s->streams[0]->codecpar; +ArgoASFFileHeader fhdr; +ArgoASFChunkHeader chdr; + +fhdr.magic = ASF_TAG; +fhdr.version_major = 2; +fhdr.version_minor = 1; +fhdr.num_chunks= 1; +fhdr.chunk_offset = ASF_FILE_HEADER_SIZE; +strncpy(fhdr.name, av_basename(s->url), FF_ARRAY_ELEMS(fhdr.name)); + +chdr.num_blocks= 0; +chdr.num_samples = ASF_SAMPLE_COUNT; +chdr.unk1 = 0; +chdr.sample_rate = par->sample_rate; +chdr.unk2 = ~0; +chdr.flags = ASF_CF_BITS_PER_SAMPLE | ASF_CF_ALWAYS1; + +if (par->channels == 2) +chdr.flags |= ASF_CF_STEREO; + +argo_asf_write_file_header(&fhdr, s->pb); +argo_asf_write_chunk_header(&chdr, s->pb)
[FFmpeg-devel] [PATCH v3 1/6] avformat/argo_asf: check sample count in demuxer
Signed-off-by: Zane van Iperen --- libavformat/argo_asf.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index 3339425244..9de64dfab4 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -27,6 +27,7 @@ #define ASF_TAG MKTAG('A', 'S', 'F', '\0') #define ASF_FILE_HEADER_SIZE24 #define ASF_CHUNK_HEADER_SIZE 20 +#define ASF_SAMPLE_COUNT32 typedef struct ArgoASFFileHeader { uint32_tmagic; /*< Magic Number, {'A', 'S', 'F', '\0'} */ @@ -39,7 +40,7 @@ typedef struct ArgoASFFileHeader { typedef struct ArgoASFChunkHeader { uint32_tnum_blocks; /*< No. blocks in the chunk. */ -uint32_tnum_samples;/*< No. samples per channel in a block. */ +uint32_tnum_samples;/*< No. samples per channel in a block. Always 32. */ uint32_tunk1; /*< Unknown */ uint16_tsample_rate;/*< Sample rate. */ uint16_tunk2; /*< Unknown. */ @@ -158,6 +159,12 @@ static int argo_asf_read_header(AVFormatContext *s) argo_asf_parse_chunk_header(&asf->ckhdr, buf); +if (asf->ckhdr.num_samples != ASF_SAMPLE_COUNT) { +av_log(s, AV_LOG_ERROR, "Invalid sample count. Got %u, expected %d\n", + asf->ckhdr.num_samples, ASF_SAMPLE_COUNT); +return AVERROR_INVALIDDATA; +} + if ((asf->ckhdr.flags & ASF_CF_ALWAYS1) != ASF_CF_ALWAYS1 || (asf->ckhdr.flags & ASF_CF_ALWAYS0) != 0) { avpriv_request_sample(s, "Nonstandard flags (0x%08X)", asf->ckhdr.flags); return AVERROR_PATCHWELCOME; -- 2.25.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 2/6] avcodec/adpcm_argo: add ff_adpcm_argo_expand_nibble() and cleanup parameters
Replaces adpcm_argo_expand_nibble(). Preparation for the encoder. Signed-off-by: Zane van Iperen --- libavcodec/adpcm.c | 10 +- libavcodec/adpcm.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index b77f4b8ef6..1366932352 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -689,11 +689,11 @@ static void adpcm_swf_decode(AVCodecContext *avctx, const uint8_t *buf, int buf_ } } -static inline int16_t adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int control, int shift) +int16_t ff_adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int shift, int flag) { -int sample = nibble * (1 << shift); +int sample = sign_extend(nibble, 4) * (1 << shift); -if (control & 0x04) +if (flag) sample += (8 * cs->sample1) - (4 * cs->sample2); else sample += 4 * cs->sample1; @@ -2007,8 +2007,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, for (n = 0; n < nb_samples / 2; n++) { int sample = bytestream2_get_byteu(&gb); -*samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 4, 4), control, shift); -*samples++ = adpcm_argo_expand_nibble(cs, sign_extend(sample >> 0, 4), control, shift); +*samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 4, shift, control & 0x04); +*samples++ = ff_adpcm_argo_expand_nibble(cs, sample >> 0, shift, control & 0x04); } } break; diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h index 580db7df8b..dc0d49ac61 100644 --- a/libavcodec/adpcm.h +++ b/libavcodec/adpcm.h @@ -45,4 +45,6 @@ typedef struct ADPCMChannelStatus { int idelta; } ADPCMChannelStatus; +int16_t ff_adpcm_argo_expand_nibble(ADPCMChannelStatus *cs, int nibble, int shift, int flag); + #endif /* AVCODEC_ADPCM_H */ -- 2.25.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 3/6] avcodec: add adpcm_argo encoder
Signed-off-by: Zane van Iperen --- Changelog | 1 + doc/general.texi | 2 +- libavcodec/Makefile| 1 + libavcodec/adpcmenc.c | 86 +- libavcodec/allcodecs.c | 1 + libavcodec/utils.c | 1 + libavcodec/version.h | 2 +- 7 files changed, 91 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index 959a2289ff..0f0fbf2abb 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,7 @@ version : - Rayman 2 APM muxer - AV1 encoding support SVT-AV1 - Cineform HD encoder +- ADPCM Argonaut Games encoder version 4.3: diff --git a/doc/general.texi b/doc/general.texi index dfcfd394e6..bfe2e98416 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -1098,7 +1098,7 @@ following image formats are supported: @item ACELP.KELVIN @tab @tab X @item ADPCM 4X Movie @tab @tab X @item APDCM Yamaha AICA @tab @tab X -@item ADPCM Argonaut Games @tab @tab X +@item ADPCM Argonaut Games @tab X @tab X @item ADPCM CDROM XA @tab @tab X @item ADPCM Creative Technology @tab @tab X @tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 1417aeef98..fc4294816e 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -837,6 +837,7 @@ OBJS-$(CONFIG_ADPCM_AFC_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_AGM_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_AICA_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_ARGO_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_ARGO_ENCODER) += adpcm.o adpcmenc.o OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_DTK_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o adpcm_data.o diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index adb7bf0bbf..24bd31c4a9 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -78,7 +78,8 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) } if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI || -avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM) { +avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM || +avctx->codec->id == AV_CODEC_ID_ADPCM_ARGO) { /* * The current trellis implementation doesn't work for extended * runs of samples without periodic resets. Disallow it. @@ -156,6 +157,10 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); avctx->extradata_size = 28; break; +case AV_CODEC_ID_ADPCM_ARGO: +avctx->frame_size = 32; +avctx->block_align = 17 * avctx->channels; +break; default: return AVERROR(EINVAL); } @@ -481,6 +486,46 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, c->idelta = nodes[0]->step; } +static inline int adpcm_argo_compress_nibble(const ADPCMChannelStatus *cs, int16_t s, + int shift, int flag) +{ +int nibble; + +if (flag) +nibble = 4 * s - 8 * cs->sample1 + 4 * cs->sample2; +else +nibble = 4 * s - 4 * cs->sample1; + +return (nibble >> shift) & 0x0F; +} + +static int64_t adpcm_argo_compress_block(ADPCMChannelStatus *cs, PutBitContext *pb, + const int16_t *samples, int nsamples, + int shift, int flag) +{ +int64_t error = 0; + +if (pb) { +put_bits(pb, 4, shift - 2); +put_bits(pb, 1, 0); +put_bits(pb, 1, !!flag); +put_bits(pb, 2, 0); +} + +for (int n = 0; n < nsamples; n++) { +/* Compress the nibble, then expand it to see how much precision we've lost. */ +int nibble = adpcm_argo_compress_nibble(cs, samples[n], shift, flag); +int16_t sample = ff_adpcm_argo_expand_nibble(cs, nibble, shift, flag); + +error += abs(samples[n] - sample); + +if (pb) +put_bits(pb, 4, nibble); +} + +return error; +} + static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { @@ -741,6 +786,44 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, flush_put_bits(&pb); break; } +case AV_CODEC_ID_ADPCM_ARGO: +{ +PutBitContext pb; +init_put_bits(&pb, dst, pkt_size); + +av_assert0(frame->nb_samples == 32); + +for (ch = 0; ch < avctx->channels; ch++) { +int64_t error = INT64_MAX, tmperr = INT64_MAX; +int shift = 2, flag = 0; +int saved1 = c->status[ch].sample1; +int saved2 = c->status[ch].sample2; + +/* Find the optimal coefficients, bail early if we find a perfect result. */
[FFmpeg-devel] [PATCH v3 6/6] fate: cosmetics
Signed-off-by: Zane van Iperen --- tests/fate/acodec.mak | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index 96ab0e587e..3e2a18435f 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -44,15 +44,15 @@ fate-acodec-pcm-u%be: FMT = nut fate-acodec-pcm-u%le: FMT = nut fate-acodec-pcm-f%be: FMT = au -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ARGO,ARGO_ASF) += argo -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_MS, WAV) += ms -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_SWF, FLV) += swf -FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_YAMAHA, WAV) += yamaha +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_SSI, KVAG) += ima_ssi +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_MS, WAV) += ms +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_SWF, FLV) += swf +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_YAMAHA, WAV) += yamaha FATE_ACODEC_ADPCM := $(FATE_ACODEC_ADPCM-yes:%=fate-acodec-adpcm-%) FATE_ACODEC += $(FATE_ACODEC_ADPCM) -- 2.25.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] libavcodec/libx264.c: Fix chromaoffset of libx264 doesn't work
Thank you for the review! It is my first time to send a patch. So I was relieved to hear that. Is it OK to wait to merge? Best Regards, Takio 2020年8月5日(水) 6:00 Jan Ekström : > > On Tue, Jul 28, 2020 at 3:30 PM Takio Yamaoka wrote: > > > > An initial value of `AVCodecContext::chromaoffset` is zero, > > then it causes to block `-chromaoffset` setting as result. > > In addition, even though a negative number of `chromaoffset` > > is meaningful, `X264Context::chroma_offset` is initialized > > with `-1` as no setting and ignored if it is negative number. > > > > To fix above, it changes ... > > - a value of `X264Context::chroma_offset` to 0 as no setting > > - due to x264's default value > > - conditional statement to import `-chromaoffset` > > > > Signed-off-by: Takio Yamaoka > > --- > > libavcodec/libx264.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c > > index 7bbeab7d4c..347d29df27 100644 > > --- a/libavcodec/libx264.c > > +++ b/libavcodec/libx264.c > > @@ -681,11 +681,11 @@ static av_cold int X264_init(AVCodecContext *avctx) > > > > #if FF_API_PRIVATE_OPT > > FF_DISABLE_DEPRECATION_WARNINGS > > -if (avctx->chromaoffset >= 0) > > +if (avctx->chromaoffset) > > x4->chroma_offset = avctx->chromaoffset; > > FF_ENABLE_DEPRECATION_WARNINGS > > #endif > > -if (x4->chroma_offset >= 0) > > +if (x4->chroma_offset) > > x4->params.analyse.i_chroma_qp_offset = x4->chroma_offset; > > > > if (avctx->gop_size >= 0) > > @@ -1140,7 +1140,7 @@ static const AVOption options[] = { > > { "vlc", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, > > INT_MIN, INT_MAX, VE, "coder" }, > > { "ac", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, > > INT_MIN, INT_MAX, VE, "coder" }, > > { "b_strategy", "Strategy to choose between I/P/B-frames", > > OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2, VE }, > > -{ "chromaoffset", "QP difference between chroma and luma", > > OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, VE > > }, > > +{ "chromaoffset", "QP difference between chroma and luma", > > OFFSET(chroma_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, VE > > }, > > { "sc_threshold", "Scene change threshold", > > OFFSET(scenechange_threshold), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, > > INT_MAX, VE }, > > { "noise_reduction", "Noise reduction", > > OFFSET(noise_reduction), AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX, > > VE }, > > > > General change looks alright to me, after checking the following points. > - AVCodecContext's chromaoffset indeed defaults to 0 through the > DEFAULT define (#define DEFAULT 0 //should be NAN but it does not work > as it is not a constant in glibc as required by ANSI/ISO C) > - x264 default is 0 (thus we thankfully haven't overwritten this > before, and the patch doesn't lead to a change in that behavior, > either) > - value in x264 can be between -12 and 12, thus both positive and > negative values indeed can be set > (x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12) can be found > in x264's code) > > Best regards, > Jan > ___ > 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".
[FFmpeg-devel] [PATCH V4 1/2] dnn/native: add native support for avg_pool
Not support pooling strides in channel dimension now. It can be tested with the model generated with below python script: import tensorflow as tf import numpy as np import imageio in_img = imageio.imread('input_odd.jpg') in_img = in_img.astype(np.float32)/255.0 in_data = in_img[np.newaxis, :] x = tf.placeholder(tf.float32, shape=[1, None, None, 3], name='dnn_in') x_pool = tf.nn.avg_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME') #please alter the params as needed y = tf.identity(x_pool, name='dnn_out') sess=tf.Session() sess.run(tf.global_variables_initializer()) graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, ['dnn_out']) tf.train.write_graph(graph_def, '.', 'image_process.pb', as_text=False) print("image_process.pb generated, please use \ path_to_ffmpeg/tools/python/convert.py to generate image_process.model\n") output = sess.run(y, feed_dict={x: in_data}) imageio.imsave("out.jpg", np.squeeze(output)) Signed-off-by: Ting Fu --- libavfilter/dnn/Makefile | 1 + libavfilter/dnn/dnn_backend_native.h | 2 + .../dnn/dnn_backend_native_layer_avgpool.c| 141 ++ .../dnn/dnn_backend_native_layer_avgpool.h| 40 + .../dnn/dnn_backend_native_layer_conv2d.h | 3 +- libavfilter/dnn/dnn_backend_native_layers.c | 2 + tools/python/convert_from_tensorflow.py | 37 - 7 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.c create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.h diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile index d90137ec42..e0957073ee 100644 --- a/libavfilter/dnn/Makefile +++ b/libavfilter/dnn/Makefile @@ -1,6 +1,7 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_interface.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layers.o +OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_avgpool.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_pad.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_conv2d.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_depth2space.o diff --git a/libavfilter/dnn/dnn_backend_native.h b/libavfilter/dnn/dnn_backend_native.h index 62191ffe88..26e9a33387 100644 --- a/libavfilter/dnn/dnn_backend_native.h +++ b/libavfilter/dnn/dnn_backend_native.h @@ -43,10 +43,12 @@ typedef enum { DLT_MAXIMUM = 4, DLT_MATH_BINARY = 5, DLT_MATH_UNARY = 6, +DLT_AVG_POOL = 7, DLT_COUNT } DNNLayerType; typedef enum {DOT_INPUT = 1, DOT_OUTPUT = 2, DOT_INTERMEDIATE = DOT_INPUT | DOT_OUTPUT} DNNOperandType; +typedef enum {VALID, SAME, SAME_CLAMP_TO_EDGE} DNNPaddingParam; typedef struct Layer{ DNNLayerType type; diff --git a/libavfilter/dnn/dnn_backend_native_layer_avgpool.c b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c new file mode 100644 index 00..d745c35b4a --- /dev/null +++ b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * DNN native backend implementation. + */ + +#include "libavutil/avassert.h" +#include "dnn_backend_native_layer_avgpool.h" + +int dnn_load_layer_avg_pool(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +{ +AvgPoolParams *avgpool_params; +int dnn_size = 0; +avgpool_params = av_malloc(sizeof(*avgpool_params)); +if(!avgpool_params) +return 0; + +avgpool_params->strides = (int32_t)avio_rl32(model_file_context); +avgpool_params->padding_method = (int32_t)avio_rl32(model_file_context); +avgpool_params->kernel_size = (int32_t)avio_rl32(model_file_context); +dnn_size += 12; + +if (dnn_size > file_size || avgpool_params->kernel_size <= 0 || avgpool_params->strides <=0){ +av_freep(&avgpool_params); +return 0; +} + +layer->params = avgpool_params; +layer->input_operand_indexes[0] = (int32_t)avio_rl32(model_file_context); +layer->output_operand_i
[FFmpeg-devel] [PATCH V4 2/2] FATE/dnn: add unit test for dnn avgpool layer
'make fate-dnn-layer-avgpool' to run the test Signed-off-by: Ting Fu --- tests/dnn/.gitignore | 1 + tests/dnn/Makefile | 1 + tests/dnn/dnn-layer-avgpool-test.c | 202 + tests/fate/dnn.mak | 5 + 4 files changed, 209 insertions(+) create mode 100644 tests/dnn/dnn-layer-avgpool-test.c diff --git a/tests/dnn/.gitignore b/tests/dnn/.gitignore index 1fcd2410b4..b847a01177 100644 --- a/tests/dnn/.gitignore +++ b/tests/dnn/.gitignore @@ -4,3 +4,4 @@ /dnn-layer-pad-test /dnn-layer-mathbinary-test /dnn-layer-mathunary-test +/dnn-layer-avgpool-test diff --git a/tests/dnn/Makefile b/tests/dnn/Makefile index 64591b7851..8afdfab5d3 100644 --- a/tests/dnn/Makefile +++ b/tests/dnn/Makefile @@ -4,6 +4,7 @@ DNNTESTPROGS += dnn-layer-depth2space DNNTESTPROGS += dnn-layer-mathbinary DNNTESTPROGS += dnn-layer-maximum DNNTESTPROGS += dnn-layer-mathunary +DNNTESTPROGS += dnn-layer-avgpool DNNTESTOBJS := $(DNNTESTOBJS:%=$(DNNTESTSDIR)%) $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test.o) DNNTESTPROGS := $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test$(EXESUF)) diff --git a/tests/dnn/dnn-layer-avgpool-test.c b/tests/dnn/dnn-layer-avgpool-test.c new file mode 100644 index 00..1c47f9330d --- /dev/null +++ b/tests/dnn/dnn-layer-avgpool-test.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include //? +#include "libavfilter/dnn/dnn_backend_native_layer_avgpool.h" + +#define EPSON 0.1 + +static int test_with_same(void) +{ +// the input data and expected data are generated with below python code. +/* +import tensorflow as tf +import numpy as np + +x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) +y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], padding='VALID') +data = np.random.rand(1, 5, 6, 3); + +sess=tf.Session() +sess.run(tf.global_variables_initializer()) + +output = sess.run(y, feed_dict={x: data}) + +print("input:") +print(data.shape) +print(list(data.flatten())) + +print("output:") +print(output.shape) +print(list(output.flatten())) +*/ + +AvgPoolParams params; +DnnOperand operands[2]; +int32_t input_indexes[1]; +float input[1*5*6*3] = { +0.7461309859908424, 0.7567538372797069, 0.07662743569678687, 0.8882112610336333, 0.9720443314026668, 0.3337200343220823, 0.4421032129780248, +0.14940809044964876, 0.6773177061961277, 0.9778844630669781, 0.6522650522626998, 0.0317651530878591, 0.31259897552911364, 0.6235936821891896, +0.40016094349542775, 0.4599222930032276, 0.7893807222960093, 0.8475986363538283, 0.5058802717647394, 0.7827005363222633, 0.3032188123727916, +0.8983728631302361, 0.20622408444965523, 0.22966072303869878, 0.09535751273161308, 0.8760709100995375, 0.9982324154558745, 0.7904595468621013, +0.13883671508879347, 0.9332751439533138, 0.0010861680752152214, 0.3607210449251048, 0.6600652759586171, 0.7629572058138805, 0.29441975810476106, +0.2683471432889405, 0.22574580829831536, 0.8893251976212904, 0.3907737043801005, 0.6421829842863968, 0.6670373870457297, 0.9383850793160277, +0.4120458907436003, 0.3589847212711481, 0.48047736550128983, 0.6428192648418949, 0.0313661686292348, 0.429357100401472, 0.5123413386514056, +0.8492446404097114, 0.9045286128486804, 0.8123708563814285, 0.3943245008451698, 0.9576713003177785, 0.5985610965938726, 0.9350833279543561, +0.8010079897491659, 0.45882114217642866, 0.35275037908941487, 0.4555844661432271, 0.12352455940255314, 0.37801756635035544, 0.2824056214573083, +0.6229462823245029, 0.7235305681391472, 0.5408259266122064, 0.12142224381781208, 0.34431198802873686, 0.7112823816321276, 0.6307144385115417, +0.8136734589018082, 0.842095618140585, 0.8602767724004784, 0.6649236853766185, 0.5184782829419623, 0.9119607270982825, 0.3084111974561645, +0.39460705638161364, 0.17710447526170836, 0.1715485945814199, 0.17277563576521882, 0.40188232428735704, 0.22847985411491878, 0.4135361701550696, +0.24621846601980057, 0.6576588108454774, 0.6063336087333997, 0.6452342242996931, 0.7071689702737508, 0.1973416063
[FFmpeg-devel] [PATCH V5 1/2] dnn/native: add native support for avg_pool
Not support pooling strides in channel dimension now. It can be tested with the model generated with below python script: import tensorflow as tf import numpy as np import imageio in_img = imageio.imread('input_odd.jpg') in_img = in_img.astype(np.float32)/255.0 in_data = in_img[np.newaxis, :] x = tf.placeholder(tf.float32, shape=[1, None, None, 3], name='dnn_in') x_pool = tf.nn.avg_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME') #please alter the params as needed y = tf.identity(x_pool, name='dnn_out') sess=tf.Session() sess.run(tf.global_variables_initializer()) graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, ['dnn_out']) tf.train.write_graph(graph_def, '.', 'image_process.pb', as_text=False) print("image_process.pb generated, please use \ path_to_ffmpeg/tools/python/convert.py to generate image_process.model\n") output = sess.run(y, feed_dict={x: in_data}) imageio.imsave("out.jpg", np.squeeze(output)) Signed-off-by: Ting Fu --- libavfilter/dnn/Makefile | 1 + libavfilter/dnn/dnn_backend_native.h | 2 + .../dnn/dnn_backend_native_layer_avgpool.c| 141 ++ .../dnn/dnn_backend_native_layer_avgpool.h| 40 + .../dnn/dnn_backend_native_layer_conv2d.h | 3 +- libavfilter/dnn/dnn_backend_native_layers.c | 2 + tools/python/convert_from_tensorflow.py | 37 - 7 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.c create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.h diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile index d90137ec42..e0957073ee 100644 --- a/libavfilter/dnn/Makefile +++ b/libavfilter/dnn/Makefile @@ -1,6 +1,7 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_interface.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layers.o +OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_avgpool.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_pad.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_conv2d.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_depth2space.o diff --git a/libavfilter/dnn/dnn_backend_native.h b/libavfilter/dnn/dnn_backend_native.h index 62191ffe88..26e9a33387 100644 --- a/libavfilter/dnn/dnn_backend_native.h +++ b/libavfilter/dnn/dnn_backend_native.h @@ -43,10 +43,12 @@ typedef enum { DLT_MAXIMUM = 4, DLT_MATH_BINARY = 5, DLT_MATH_UNARY = 6, +DLT_AVG_POOL = 7, DLT_COUNT } DNNLayerType; typedef enum {DOT_INPUT = 1, DOT_OUTPUT = 2, DOT_INTERMEDIATE = DOT_INPUT | DOT_OUTPUT} DNNOperandType; +typedef enum {VALID, SAME, SAME_CLAMP_TO_EDGE} DNNPaddingParam; typedef struct Layer{ DNNLayerType type; diff --git a/libavfilter/dnn/dnn_backend_native_layer_avgpool.c b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c new file mode 100644 index 00..d745c35b4a --- /dev/null +++ b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * DNN native backend implementation. + */ + +#include "libavutil/avassert.h" +#include "dnn_backend_native_layer_avgpool.h" + +int dnn_load_layer_avg_pool(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +{ +AvgPoolParams *avgpool_params; +int dnn_size = 0; +avgpool_params = av_malloc(sizeof(*avgpool_params)); +if(!avgpool_params) +return 0; + +avgpool_params->strides = (int32_t)avio_rl32(model_file_context); +avgpool_params->padding_method = (int32_t)avio_rl32(model_file_context); +avgpool_params->kernel_size = (int32_t)avio_rl32(model_file_context); +dnn_size += 12; + +if (dnn_size > file_size || avgpool_params->kernel_size <= 0 || avgpool_params->strides <=0){ +av_freep(&avgpool_params); +return 0; +} + +layer->params = avgpool_params; +layer->input_operand_indexes[0] = (int32_t)avio_rl32(model_file_context); +layer->output_operand_i
[FFmpeg-devel] [PATCH V5 2/2] FATE/dnn: add unit test for dnn avgpool layer
'make fate-dnn-layer-avgpool' to run the test Signed-off-by: Ting Fu --- V5: Fix the issue V4 make fate failed. tests/dnn/.gitignore | 1 + tests/dnn/Makefile | 1 + tests/dnn/dnn-layer-avgpool-test.c | 202 + tests/fate/dnn.mak | 5 + 4 files changed, 209 insertions(+) create mode 100644 tests/dnn/dnn-layer-avgpool-test.c diff --git a/tests/dnn/.gitignore b/tests/dnn/.gitignore index 1fcd2410b4..b847a01177 100644 --- a/tests/dnn/.gitignore +++ b/tests/dnn/.gitignore @@ -4,3 +4,4 @@ /dnn-layer-pad-test /dnn-layer-mathbinary-test /dnn-layer-mathunary-test +/dnn-layer-avgpool-test diff --git a/tests/dnn/Makefile b/tests/dnn/Makefile index 64591b7851..8afdfab5d3 100644 --- a/tests/dnn/Makefile +++ b/tests/dnn/Makefile @@ -4,6 +4,7 @@ DNNTESTPROGS += dnn-layer-depth2space DNNTESTPROGS += dnn-layer-mathbinary DNNTESTPROGS += dnn-layer-maximum DNNTESTPROGS += dnn-layer-mathunary +DNNTESTPROGS += dnn-layer-avgpool DNNTESTOBJS := $(DNNTESTOBJS:%=$(DNNTESTSDIR)%) $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test.o) DNNTESTPROGS := $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test$(EXESUF)) diff --git a/tests/dnn/dnn-layer-avgpool-test.c b/tests/dnn/dnn-layer-avgpool-test.c new file mode 100644 index 00..1c47f9330d --- /dev/null +++ b/tests/dnn/dnn-layer-avgpool-test.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include //? +#include "libavfilter/dnn/dnn_backend_native_layer_avgpool.h" + +#define EPSON 0.1 + +static int test_with_same(void) +{ +// the input data and expected data are generated with below python code. +/* +import tensorflow as tf +import numpy as np + +x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) +y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], padding='VALID') +data = np.random.rand(1, 5, 6, 3); + +sess=tf.Session() +sess.run(tf.global_variables_initializer()) + +output = sess.run(y, feed_dict={x: data}) + +print("input:") +print(data.shape) +print(list(data.flatten())) + +print("output:") +print(output.shape) +print(list(output.flatten())) +*/ + +AvgPoolParams params; +DnnOperand operands[2]; +int32_t input_indexes[1]; +float input[1*5*6*3] = { +0.7461309859908424, 0.7567538372797069, 0.07662743569678687, 0.8882112610336333, 0.9720443314026668, 0.3337200343220823, 0.4421032129780248, +0.14940809044964876, 0.6773177061961277, 0.9778844630669781, 0.6522650522626998, 0.0317651530878591, 0.31259897552911364, 0.6235936821891896, +0.40016094349542775, 0.4599222930032276, 0.7893807222960093, 0.8475986363538283, 0.5058802717647394, 0.7827005363222633, 0.3032188123727916, +0.8983728631302361, 0.20622408444965523, 0.22966072303869878, 0.09535751273161308, 0.8760709100995375, 0.9982324154558745, 0.7904595468621013, +0.13883671508879347, 0.9332751439533138, 0.0010861680752152214, 0.3607210449251048, 0.6600652759586171, 0.7629572058138805, 0.29441975810476106, +0.2683471432889405, 0.22574580829831536, 0.8893251976212904, 0.3907737043801005, 0.6421829842863968, 0.6670373870457297, 0.9383850793160277, +0.4120458907436003, 0.3589847212711481, 0.48047736550128983, 0.6428192648418949, 0.0313661686292348, 0.429357100401472, 0.5123413386514056, +0.8492446404097114, 0.9045286128486804, 0.8123708563814285, 0.3943245008451698, 0.9576713003177785, 0.5985610965938726, 0.9350833279543561, +0.8010079897491659, 0.45882114217642866, 0.35275037908941487, 0.4555844661432271, 0.12352455940255314, 0.37801756635035544, 0.2824056214573083, +0.6229462823245029, 0.7235305681391472, 0.5408259266122064, 0.12142224381781208, 0.34431198802873686, 0.7112823816321276, 0.6307144385115417, +0.8136734589018082, 0.842095618140585, 0.8602767724004784, 0.6649236853766185, 0.5184782829419623, 0.9119607270982825, 0.3084111974561645, +0.39460705638161364, 0.17710447526170836, 0.1715485945814199, 0.17277563576521882, 0.40188232428735704, 0.22847985411491878, 0.4135361701550696, +0.24621846601980057, 0.6576588108454774, 0.6063336087333997, 0.64523422
[FFmpeg-devel] [PATCH V6 1/2] dnn/native: add native support for avg_pool
Not support pooling strides in channel dimension now. It can be tested with the model generated with below python script: import tensorflow as tf import numpy as np import imageio in_img = imageio.imread('input_odd.jpg') in_img = in_img.astype(np.float32)/255.0 in_data = in_img[np.newaxis, :] x = tf.placeholder(tf.float32, shape=[1, None, None, 3], name='dnn_in') x_pool = tf.nn.avg_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME') #please alter the params as needed y = tf.identity(x_pool, name='dnn_out') sess=tf.Session() sess.run(tf.global_variables_initializer()) graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def, ['dnn_out']) tf.train.write_graph(graph_def, '.', 'image_process.pb', as_text=False) print("image_process.pb generated, please use \ path_to_ffmpeg/tools/python/convert.py to generate image_process.model\n") output = sess.run(y, feed_dict={x: in_data}) imageio.imsave("out.jpg", np.squeeze(output)) Signed-off-by: Ting Fu --- libavfilter/dnn/Makefile | 1 + libavfilter/dnn/dnn_backend_native.h | 2 + .../dnn/dnn_backend_native_layer_avgpool.c| 141 ++ .../dnn/dnn_backend_native_layer_avgpool.h| 40 + .../dnn/dnn_backend_native_layer_conv2d.h | 3 +- libavfilter/dnn/dnn_backend_native_layers.c | 2 + tools/python/convert_from_tensorflow.py | 37 - 7 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.c create mode 100644 libavfilter/dnn/dnn_backend_native_layer_avgpool.h diff --git a/libavfilter/dnn/Makefile b/libavfilter/dnn/Makefile index d90137ec42..e0957073ee 100644 --- a/libavfilter/dnn/Makefile +++ b/libavfilter/dnn/Makefile @@ -1,6 +1,7 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_interface.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layers.o +OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_avgpool.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_pad.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_conv2d.o OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_depth2space.o diff --git a/libavfilter/dnn/dnn_backend_native.h b/libavfilter/dnn/dnn_backend_native.h index 62191ffe88..26e9a33387 100644 --- a/libavfilter/dnn/dnn_backend_native.h +++ b/libavfilter/dnn/dnn_backend_native.h @@ -43,10 +43,12 @@ typedef enum { DLT_MAXIMUM = 4, DLT_MATH_BINARY = 5, DLT_MATH_UNARY = 6, +DLT_AVG_POOL = 7, DLT_COUNT } DNNLayerType; typedef enum {DOT_INPUT = 1, DOT_OUTPUT = 2, DOT_INTERMEDIATE = DOT_INPUT | DOT_OUTPUT} DNNOperandType; +typedef enum {VALID, SAME, SAME_CLAMP_TO_EDGE} DNNPaddingParam; typedef struct Layer{ DNNLayerType type; diff --git a/libavfilter/dnn/dnn_backend_native_layer_avgpool.c b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c new file mode 100644 index 00..d745c35b4a --- /dev/null +++ b/libavfilter/dnn/dnn_backend_native_layer_avgpool.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * DNN native backend implementation. + */ + +#include "libavutil/avassert.h" +#include "dnn_backend_native_layer_avgpool.h" + +int dnn_load_layer_avg_pool(Layer *layer, AVIOContext *model_file_context, int file_size, int operands_num) +{ +AvgPoolParams *avgpool_params; +int dnn_size = 0; +avgpool_params = av_malloc(sizeof(*avgpool_params)); +if(!avgpool_params) +return 0; + +avgpool_params->strides = (int32_t)avio_rl32(model_file_context); +avgpool_params->padding_method = (int32_t)avio_rl32(model_file_context); +avgpool_params->kernel_size = (int32_t)avio_rl32(model_file_context); +dnn_size += 12; + +if (dnn_size > file_size || avgpool_params->kernel_size <= 0 || avgpool_params->strides <=0){ +av_freep(&avgpool_params); +return 0; +} + +layer->params = avgpool_params; +layer->input_operand_indexes[0] = (int32_t)avio_rl32(model_file_context); +layer->output_operand_i
[FFmpeg-devel] [PATCH V6 2/2] FATE/dnn: add unit test for dnn avgpool layer
'make fate-dnn-layer-avgpool' to run the test Signed-off-by: Ting Fu --- V6: Fix the issue of make fate failed in V4&V5 tests/dnn/.gitignore | 1 + tests/dnn/Makefile | 1 + tests/dnn/dnn-layer-avgpool-test.c | 198 + tests/fate/dnn.mak | 5 + 4 files changed, 205 insertions(+) create mode 100644 tests/dnn/dnn-layer-avgpool-test.c diff --git a/tests/dnn/.gitignore b/tests/dnn/.gitignore index 1fcd2410b4..b847a01177 100644 --- a/tests/dnn/.gitignore +++ b/tests/dnn/.gitignore @@ -4,3 +4,4 @@ /dnn-layer-pad-test /dnn-layer-mathbinary-test /dnn-layer-mathunary-test +/dnn-layer-avgpool-test diff --git a/tests/dnn/Makefile b/tests/dnn/Makefile index 64591b7851..8afdfab5d3 100644 --- a/tests/dnn/Makefile +++ b/tests/dnn/Makefile @@ -4,6 +4,7 @@ DNNTESTPROGS += dnn-layer-depth2space DNNTESTPROGS += dnn-layer-mathbinary DNNTESTPROGS += dnn-layer-maximum DNNTESTPROGS += dnn-layer-mathunary +DNNTESTPROGS += dnn-layer-avgpool DNNTESTOBJS := $(DNNTESTOBJS:%=$(DNNTESTSDIR)%) $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test.o) DNNTESTPROGS := $(DNNTESTPROGS:%=$(DNNTESTSDIR)/%-test$(EXESUF)) diff --git a/tests/dnn/dnn-layer-avgpool-test.c b/tests/dnn/dnn-layer-avgpool-test.c new file mode 100644 index 00..5fadde1024 --- /dev/null +++ b/tests/dnn/dnn-layer-avgpool-test.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2020 + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include //? +#include "libavfilter/dnn/dnn_backend_native_layer_avgpool.h" + +#define EPSON 0.1 + +static int test_with_same(void) +{ +// the input data and expected data are generated with below python code. +/* +import tensorflow as tf +import numpy as np + +x = tf.placeholder(tf.float32, shape=[1, None, None, 3]) +y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], padding='VALID') +data = np.random.rand(1, 5, 6, 3); + +sess=tf.Session() +sess.run(tf.global_variables_initializer()) + +output = sess.run(y, feed_dict={x: data}) + +print("input:") +print(data.shape) +print(list(data.flatten())) + +print("output:") +print(output.shape) +print(list(output.flatten())) +*/ + +AvgPoolParams params; +DnnOperand operands[2]; +int32_t input_indexes[1]; +float input[1*5*6*3] = { +0.7461309859908424, 0.7567538372797069, 0.07662743569678687, 0.8882112610336333, 0.9720443314026668, 0.3337200343220823, 0.4421032129780248, +0.14940809044964876, 0.6773177061961277, 0.9778844630669781, 0.6522650522626998, 0.0317651530878591, 0.31259897552911364, 0.6235936821891896, +0.40016094349542775, 0.4599222930032276, 0.7893807222960093, 0.8475986363538283, 0.5058802717647394, 0.7827005363222633, 0.3032188123727916, +0.8983728631302361, 0.20622408444965523, 0.22966072303869878, 0.09535751273161308, 0.8760709100995375, 0.9982324154558745, 0.7904595468621013, +0.13883671508879347, 0.9332751439533138, 0.0010861680752152214, 0.3607210449251048, 0.6600652759586171, 0.7629572058138805, 0.29441975810476106, +0.2683471432889405, 0.22574580829831536, 0.8893251976212904, 0.3907737043801005, 0.6421829842863968, 0.6670373870457297, 0.9383850793160277, +0.4120458907436003, 0.3589847212711481, 0.48047736550128983, 0.6428192648418949, 0.0313661686292348, 0.429357100401472, 0.5123413386514056, +0.8492446404097114, 0.9045286128486804, 0.8123708563814285, 0.3943245008451698, 0.9576713003177785, 0.5985610965938726, 0.9350833279543561, +0.8010079897491659, 0.45882114217642866, 0.35275037908941487, 0.4555844661432271, 0.12352455940255314, 0.37801756635035544, 0.2824056214573083, +0.6229462823245029, 0.7235305681391472, 0.5408259266122064, 0.12142224381781208, 0.34431198802873686, 0.7112823816321276, 0.6307144385115417, +0.8136734589018082, 0.842095618140585, 0.8602767724004784, 0.6649236853766185, 0.5184782829419623, 0.9119607270982825, 0.3084111974561645, +0.39460705638161364, 0.17710447526170836, 0.1715485945814199, 0.17277563576521882, 0.40188232428735704, 0.22847985411491878, 0.4135361701550696, +0.24621846601980057, 0.6576588108454774, 0.6063336087333997, 0.