Re: [FFmpeg-devel] APV codec with OpenAPV support
On Tue, 22 Apr 2025, 09:44 , wrote: > Hi, > > > > I'm Dariusz from Samsung Electronics, you can know me from last VDD in > Korea, I was presenting APV. > > > > I'm glad that Mark created native APV decoder. As you might know we're also > working on APV implementation for FFmpeg. > > Our approach is different from yours but they can exist in FFmpeg in > parallel. We're using external library OpenAPV for encoding and decoding: > https://github.com/AcademySoftwareFoundation/openapv > > This OpenAPV implementation will be also used by Google in next Android 16: > https://developer.android.com/about/versions/16/features#apv > > In our approach we have implemented: encoding, decoding and mp4 muxing. > Today we will send patches. > > > > So I think now it's a good moment to review both implementations and > integrate them in parallel in FFmpeg. > > > > What's your opinion about that? > > > > Regards, > > Dariusz > Hi Dariusz, The general "policy" is that external libraries are not used if we already have a native implementation. Unless that native library has capabilities (e.g encoding in this case) that we don't have. Regards, Kieran Kunhya > ___ 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/3] lavc/hashtable: create generic robin hood hash table
Adds a generic hash table with the DXV encoder as an initial use case. Signed-off-by: Emma Worley --- libavcodec/Makefile | 2 + libavcodec/hashtable.c | 192 +++ libavcodec/hashtable.h | 91 + libavcodec/tests/hashtable.c | 110 4 files changed, 395 insertions(+) create mode 100644 libavcodec/hashtable.c create mode 100644 libavcodec/hashtable.h create mode 100644 libavcodec/tests/hashtable.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 7bd1dbec9a..8071c59378 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -42,6 +42,7 @@ OBJS = ac3_parser.o \ dv_profile.o \ encode.o \ get_buffer.o \ + hashtable.o \ imgconvert.o \ jni.o\ lcevcdec.o \ @@ -1321,6 +1322,7 @@ TESTPROGS = avcodec \ bitstream_le\ celp_math \ codec_desc \ +hashtable \ htmlsubtitles \ jpeg2000dwt \ mathops\ diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c new file mode 100644 index 00..4d6d4a9506 --- /dev/null +++ b/libavcodec/hashtable.c @@ -0,0 +1,192 @@ +/* + * Generic hashtable + * Copyright (C) 2024 Connor Worley + * + * 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 "libavutil/crc.h" +#include "libavutil/error.h" +#include "libavutil/mem.h" +#include "hashtable.h" + +#define ALIGN _Alignof(size_t) + +struct FFHashtableContext { +size_t key_size; +size_t key_size_aligned; +size_t val_size; +size_t val_size_aligned; +size_t entry_size; +size_t max_entries; +size_t utilization; +const AVCRC *crc; +uint8_t *table; +uint8_t *swapbuf; +}; + +#define ENTRY_PSL(entry) (entry) +#define ENTRY_OCC(entry) (ENTRY_PSL(entry) + FFALIGN(sizeof(size_t), ALIGN)) +#define ENTRY_KEY(entry) (ENTRY_OCC(entry) + FFALIGN(sizeof(size_t), ALIGN)) +#define ENTRY_VAL(entry) (ENTRY_KEY(entry) + ctx->key_size_aligned) + +#define KEYS_EQUAL(k1, k2) !memcmp(k1, k2, ctx->key_size) + +int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, size_t val_size, size_t max_entries) +{ +struct FFHashtableContext *res = av_malloc(sizeof(struct FFHashtableContext)); +if (!res) +return AVERROR(ENOMEM); +res->key_size = key_size; +res->key_size_aligned = FFALIGN(key_size, ALIGN); +res->val_size = val_size; +res->val_size_aligned = FFALIGN(val_size, ALIGN); +res->entry_size = FFALIGN(sizeof(size_t), ALIGN) ++ FFALIGN(sizeof(size_t), ALIGN) ++ res->key_size_aligned ++ res->val_size_aligned; +res->max_entries = max_entries; +res->utilization = 0; +res->crc = av_crc_get_table(AV_CRC_32_IEEE); +if (!res->crc) { +ff_hashtable_freep(&res); +return AVERROR_BUG; +} +res->table = av_calloc(res->max_entries, res->entry_size); +if (!res->table) { +ff_hashtable_freep(&res); +return AVERROR(ENOMEM); +} +res->swapbuf = av_calloc(2, res->key_size_aligned + res->val_size_aligned); +if (!res->swapbuf) { +ff_hashtable_freep(&res); +return AVERROR(ENOMEM); +} +*ctx = res; +return 0; +} + +static size_t hash_key(const struct FFHashtableContext *ctx, const void *key) +{ +return av_crc(ctx->crc, 0, key, ctx
[FFmpeg-devel] [PATCH v4 3/3] lavc/dxvenc: improve compatibility with Resolume products
Improves compatibility with Resolume products by adding an additional hashtable for DXT color+LUT combinations, and padding the DXT texture dimensions to the next largest multiple of 16. Produces identical packets to Resolume Alley in manual tests. Signed-off-by: Emma Worley --- libavcodec/dxvenc.c | 131 +++- tests/ref/fate/dxv3enc-dxt1 | 2 +- 2 files changed, 86 insertions(+), 47 deletions(-) diff --git a/libavcodec/dxvenc.c b/libavcodec/dxvenc.c index 207ac1f24f..48548ae811 100644 --- a/libavcodec/dxvenc.c +++ b/libavcodec/dxvenc.c @@ -34,6 +34,11 @@ #define DXV_HEADER_LENGTH 12 +/* + * Resolume will refuse to display frames that are not padded to 16x16 pixels. + */ +#define DXV_ALIGN(x) FFALIGN(x, 16) + /* * DXV uses LZ-like back-references to avoid copying words that have already * appeared in the decompressed stream. Using a simple hash table (HT) @@ -60,6 +65,7 @@ typedef struct DXVEncContext { struct FFHashtableContext *color_ht; struct FFHashtableContext *lut_ht; +struct FFHashtableContext *combo_ht; } DXVEncContext; /* Converts an index offset value to a 2-bit opcode and pushes it to a stream. @@ -94,10 +100,14 @@ static int dxv_compress_dxt1(AVCodecContext *avctx) DXVEncContext *ctx = avctx->priv_data; PutByteContext *pbc = &ctx->pbc; void *value; -uint32_t color, lut, idx, color_idx, lut_idx, prev_pos, state = 16, pos = 0, op = 0; +uint64_t combo; +uint32_t color, lut, idx, combo_idx, prev_pos, old_pos, state = 16, pos = 0, op = 0; ff_hashtable_clear(ctx->color_ht); ff_hashtable_clear(ctx->lut_ht); +ff_hashtable_clear(ctx->combo_ht); + +ff_hashtable_set(ctx->combo_ht, ctx->tex_data, &pos); bytestream2_put_le32(pbc, AV_RL32(ctx->tex_data)); ff_hashtable_set(ctx->color_ht, ctx->tex_data, &pos); @@ -107,51 +117,46 @@ static int dxv_compress_dxt1(AVCodecContext *avctx) pos++; while (pos + 2 <= ctx->tex_size / 4) { -idx = 0; -color_idx = 0; -lut_idx = 0; +combo = AV_RL64(ctx->tex_data + pos * 4); +combo_idx = ff_hashtable_get(ctx->combo_ht, &combo, &prev_pos) ? pos - prev_pos : 0; +idx = combo_idx; +PUSH_OP(2); +if (pos >= LOOKBACK_WORDS) { +old_pos = pos - LOOKBACK_WORDS; +if (ff_hashtable_get(ctx->combo_ht, ctx->tex_data + old_pos * 4, &prev_pos) && prev_pos <= old_pos) +ff_hashtable_delete(ctx->combo_ht, ctx->tex_data + old_pos * 4); +} +ff_hashtable_set(ctx->combo_ht, &combo, &pos); color = AV_RL32(ctx->tex_data + pos * 4); -if (ff_hashtable_get(ctx->color_ht, &color, &prev_pos)) -color_idx = pos - prev_pos; -ff_hashtable_set(ctx->color_ht, &color, &pos); - +if (!combo_idx) { +idx = ff_hashtable_get(ctx->color_ht, &color, &prev_pos) ? pos - prev_pos : 0; +PUSH_OP(2); +if (!idx) +bytestream2_put_le32(pbc, color); +} if (pos >= LOOKBACK_WORDS) { -uint32_t old_pos = pos - LOOKBACK_WORDS; +old_pos = pos - LOOKBACK_WORDS; if (ff_hashtable_get(ctx->color_ht, ctx->tex_data + old_pos * 4, &prev_pos) && prev_pos <= old_pos) ff_hashtable_delete(ctx->color_ht, ctx->tex_data + old_pos * 4); } +ff_hashtable_set(ctx->color_ht, &color, &pos); pos++; lut = AV_RL32(ctx->tex_data + pos * 4); -if (color_idx && lut == AV_RL32(ctx->tex_data + (pos - color_idx) * 4)) { -idx = color_idx; -} else { -idx = 0; -if (ff_hashtable_get(ctx->lut_ht, &lut, &prev_pos)) -lut_idx = pos - prev_pos; -ff_hashtable_set(ctx->lut_ht, &lut, &pos); +if (!combo_idx) { +idx = ff_hashtable_get(ctx->lut_ht, &lut, &prev_pos) ? pos - prev_pos : 0; +PUSH_OP(2); +if (!idx) +bytestream2_put_le32(pbc, lut); } if (pos >= LOOKBACK_WORDS) { -uint32_t old_pos = pos - LOOKBACK_WORDS; +old_pos = pos - LOOKBACK_WORDS; if (ff_hashtable_get(ctx->lut_ht, ctx->tex_data + old_pos * 4, &prev_pos) && prev_pos <= old_pos) ff_hashtable_delete(ctx->lut_ht, ctx->tex_data + old_pos * 4); } +ff_hashtable_set(ctx->lut_ht, &lut, &pos); pos++; - -PUSH_OP(2); - -if (!idx) { -idx = color_idx; -PUSH_OP(2); -if (!idx) -bytestream2_put_le32(pbc, color); - -idx = lut_idx; -PUSH_OP(2); -if (!idx) -bytestream2_put_le32(pbc, lut); -} } return 0; @@ -172,12 +177,50 @@ static int dxv_encode(AVCodecContext *avctx, AVPacket *pkt, return ret; if (ctx->enc.tex_funct) { +uint8_t *safe_data[4] = {frame->data[0],
[FFmpeg-devel] [PATCH v4 2/3] lavc/dxvenc: migrate DXT1 encoder to lavc hashtable
Offers a modest performance gain due to the switch from naive linear probling to robin hood. Signed-off-by: Emma Worley --- libavcodec/dxvenc.c | 121 1 file changed, 33 insertions(+), 88 deletions(-) diff --git a/libavcodec/dxvenc.c b/libavcodec/dxvenc.c index 808d8daedb..207ac1f24f 100644 --- a/libavcodec/dxvenc.c +++ b/libavcodec/dxvenc.c @@ -21,7 +21,7 @@ #include -#include "libavutil/crc.h" +#include "libavcodec/hashtable.h" #include "libavutil/imgutils.h" #include "libavutil/mem.h" #include "libavutil/opt.h" @@ -39,72 +39,9 @@ * appeared in the decompressed stream. Using a simple hash table (HT) * significantly speeds up the lookback process while encoding. */ -#define LOOKBACK_HT_ELEMS 0x4 +#define LOOKBACK_HT_ELEMS 0x20202 #define LOOKBACK_WORDS0x20202 -typedef struct HTEntry { -uint32_t key; -uint32_t pos; -} HTEntry; - -static void ht_init(HTEntry *ht) -{ -for (size_t i = 0; i < LOOKBACK_HT_ELEMS; i++) { -ht[i].pos = -1; -} -} - -static uint32_t ht_lookup_and_upsert(HTEntry *ht, const AVCRC *hash_ctx, -uint32_t key, uint32_t pos) -{ -uint32_t ret = -1; -size_t hash = av_crc(hash_ctx, 0, (uint8_t*)&key, 4) % LOOKBACK_HT_ELEMS; -for (size_t i = hash; i < hash + LOOKBACK_HT_ELEMS; i++) { -size_t wrapped_index = i % LOOKBACK_HT_ELEMS; -HTEntry *entry = &ht[wrapped_index]; -if (entry->key == key || entry->pos == -1) { -ret = entry->pos; -entry->key = key; -entry->pos = pos; -break; -} -} -return ret; -} - -static void ht_delete(HTEntry *ht, const AVCRC *hash_ctx, - uint32_t key, uint32_t pos) -{ -HTEntry *removed_entry = NULL; -size_t removed_hash; -size_t hash = av_crc(hash_ctx, 0, (uint8_t*)&key, 4) % LOOKBACK_HT_ELEMS; - -for (size_t i = hash; i < hash + LOOKBACK_HT_ELEMS; i++) { -size_t wrapped_index = i % LOOKBACK_HT_ELEMS; -HTEntry *entry = &ht[wrapped_index]; -if (entry->pos == -1) -return; -if (removed_entry) { -size_t candidate_hash = av_crc(hash_ctx, 0, (uint8_t*)&entry->key, 4) % LOOKBACK_HT_ELEMS; -if ((wrapped_index > removed_hash && (candidate_hash <= removed_hash || candidate_hash > wrapped_index)) || -(wrapped_index < removed_hash && (candidate_hash <= removed_hash && candidate_hash > wrapped_index))) { -*removed_entry = *entry; -entry->pos = -1; -removed_entry = entry; -removed_hash = wrapped_index; -} -} else if (entry->key == key) { -if (entry->pos <= pos) { -entry->pos = -1; -removed_entry = entry; -removed_hash = wrapped_index; -} else { -return; -} -} -} -} - typedef struct DXVEncContext { AVClass *class; @@ -121,10 +58,8 @@ typedef struct DXVEncContext { DXVTextureFormat tex_fmt; int (*compress_tex)(AVCodecContext *avctx); -const AVCRC *crc_ctx; - -HTEntry color_lookback_ht[LOOKBACK_HT_ELEMS]; -HTEntry lut_lookback_ht[LOOKBACK_HT_ELEMS]; +struct FFHashtableContext *color_ht; +struct FFHashtableContext *lut_ht; } DXVEncContext; /* Converts an index offset value to a 2-bit opcode and pushes it to a stream. @@ -159,27 +94,32 @@ static int dxv_compress_dxt1(AVCodecContext *avctx) DXVEncContext *ctx = avctx->priv_data; PutByteContext *pbc = &ctx->pbc; void *value; -uint32_t color, lut, idx, color_idx, lut_idx, prev_pos, state = 16, pos = 2, op = 0; +uint32_t color, lut, idx, color_idx, lut_idx, prev_pos, state = 16, pos = 0, op = 0; -ht_init(ctx->color_lookback_ht); -ht_init(ctx->lut_lookback_ht); +ff_hashtable_clear(ctx->color_ht); +ff_hashtable_clear(ctx->lut_ht); bytestream2_put_le32(pbc, AV_RL32(ctx->tex_data)); +ff_hashtable_set(ctx->color_ht, ctx->tex_data, &pos); +pos++; bytestream2_put_le32(pbc, AV_RL32(ctx->tex_data + 4)); - -ht_lookup_and_upsert(ctx->color_lookback_ht, ctx->crc_ctx, AV_RL32(ctx->tex_data), 0); -ht_lookup_and_upsert(ctx->lut_lookback_ht, ctx->crc_ctx, AV_RL32(ctx->tex_data + 4), 1); +ff_hashtable_set(ctx->lut_ht, ctx->tex_data + 4, &pos); +pos++; while (pos + 2 <= ctx->tex_size / 4) { idx = 0; +color_idx = 0; +lut_idx = 0; color = AV_RL32(ctx->tex_data + pos * 4); -prev_pos = ht_lookup_and_upsert(ctx->color_lookback_ht, ctx->crc_ctx, color, pos); -color_idx = prev_pos != -1 ? pos - prev_pos : 0; +if (ff_hashtable_get(ctx->color_ht, &color, &prev_pos)) +color_idx = pos - prev_pos; +ff_hashtable_set(ctx->color_ht, &color, &pos); + if (pos >= LOOKBACK_WORDS) { uint32_t old_pos = pos - L
Re: [FFmpeg-devel] [PATCH v4 3/3] lavc/dxvenc: improve compatibility with Resolume products
Emma Worley: > Improves compatibility with Resolume products by adding an additional > hashtable for DXT color+LUT combinations, and padding the DXT texture > dimensions to the next largest multiple of 16. Produces identical > packets to Resolume Alley in manual tests. > > Signed-off-by: Emma Worley > --- > libavcodec/dxvenc.c | 131 +++- > tests/ref/fate/dxv3enc-dxt1 | 2 +- > 2 files changed, 86 insertions(+), 47 deletions(-) > > diff --git a/libavcodec/dxvenc.c b/libavcodec/dxvenc.c > index 207ac1f24f..48548ae811 100644 > --- a/libavcodec/dxvenc.c > +++ b/libavcodec/dxvenc.c > @@ -34,6 +34,11 @@ > > #define DXV_HEADER_LENGTH 12 > > +/* > + * Resolume will refuse to display frames that are not padded to 16x16 > pixels. > + */ > +#define DXV_ALIGN(x) FFALIGN(x, 16) > + > /* > * DXV uses LZ-like back-references to avoid copying words that have already > * appeared in the decompressed stream. Using a simple hash table (HT) > @@ -60,6 +65,7 @@ typedef struct DXVEncContext { > > struct FFHashtableContext *color_ht; > struct FFHashtableContext *lut_ht; > +struct FFHashtableContext *combo_ht; > } DXVEncContext; > > /* Converts an index offset value to a 2-bit opcode and pushes it to a > stream. > @@ -94,10 +100,14 @@ static int dxv_compress_dxt1(AVCodecContext *avctx) > DXVEncContext *ctx = avctx->priv_data; > PutByteContext *pbc = &ctx->pbc; > void *value; > -uint32_t color, lut, idx, color_idx, lut_idx, prev_pos, state = 16, pos > = 0, op = 0; > +uint64_t combo; > +uint32_t color, lut, idx, combo_idx, prev_pos, old_pos, state = 16, pos > = 0, op = 0; > > ff_hashtable_clear(ctx->color_ht); > ff_hashtable_clear(ctx->lut_ht); > +ff_hashtable_clear(ctx->combo_ht); > + > +ff_hashtable_set(ctx->combo_ht, ctx->tex_data, &pos); > > bytestream2_put_le32(pbc, AV_RL32(ctx->tex_data)); > ff_hashtable_set(ctx->color_ht, ctx->tex_data, &pos); > @@ -107,51 +117,46 @@ static int dxv_compress_dxt1(AVCodecContext *avctx) > pos++; > > while (pos + 2 <= ctx->tex_size / 4) { > -idx = 0; > -color_idx = 0; > -lut_idx = 0; > +combo = AV_RL64(ctx->tex_data + pos * 4); > +combo_idx = ff_hashtable_get(ctx->combo_ht, &combo, &prev_pos) ? pos > - prev_pos : 0; > +idx = combo_idx; > +PUSH_OP(2); > +if (pos >= LOOKBACK_WORDS) { > +old_pos = pos - LOOKBACK_WORDS; > +if (ff_hashtable_get(ctx->combo_ht, ctx->tex_data + old_pos * 4, > &prev_pos) && prev_pos <= old_pos) > +ff_hashtable_delete(ctx->combo_ht, ctx->tex_data + old_pos * > 4); > +} > +ff_hashtable_set(ctx->combo_ht, &combo, &pos); > > color = AV_RL32(ctx->tex_data + pos * 4); > -if (ff_hashtable_get(ctx->color_ht, &color, &prev_pos)) > -color_idx = pos - prev_pos; > -ff_hashtable_set(ctx->color_ht, &color, &pos); > - > +if (!combo_idx) { > +idx = ff_hashtable_get(ctx->color_ht, &color, &prev_pos) ? pos - > prev_pos : 0; > +PUSH_OP(2); > +if (!idx) > +bytestream2_put_le32(pbc, color); > +} > if (pos >= LOOKBACK_WORDS) { > -uint32_t old_pos = pos - LOOKBACK_WORDS; > +old_pos = pos - LOOKBACK_WORDS; > if (ff_hashtable_get(ctx->color_ht, ctx->tex_data + old_pos * 4, > &prev_pos) && prev_pos <= old_pos) > ff_hashtable_delete(ctx->color_ht, ctx->tex_data + old_pos * > 4); > } > +ff_hashtable_set(ctx->color_ht, &color, &pos); > pos++; > > lut = AV_RL32(ctx->tex_data + pos * 4); > -if (color_idx && lut == AV_RL32(ctx->tex_data + (pos - color_idx) * > 4)) { > -idx = color_idx; > -} else { > -idx = 0; > -if (ff_hashtable_get(ctx->lut_ht, &lut, &prev_pos)) > -lut_idx = pos - prev_pos; > -ff_hashtable_set(ctx->lut_ht, &lut, &pos); > +if (!combo_idx) { > +idx = ff_hashtable_get(ctx->lut_ht, &lut, &prev_pos) ? pos - > prev_pos : 0; > +PUSH_OP(2); > +if (!idx) > +bytestream2_put_le32(pbc, lut); > } > if (pos >= LOOKBACK_WORDS) { > -uint32_t old_pos = pos - LOOKBACK_WORDS; > +old_pos = pos - LOOKBACK_WORDS; > if (ff_hashtable_get(ctx->lut_ht, ctx->tex_data + old_pos * 4, > &prev_pos) && prev_pos <= old_pos) > ff_hashtable_delete(ctx->lut_ht, ctx->tex_data + old_pos * > 4); > } > +ff_hashtable_set(ctx->lut_ht, &lut, &pos); > pos++; > - > -PUSH_OP(2); > - > -if (!idx) { > -idx = color_idx; > -PUSH_OP(2); > -if (!idx) > -bytestream2_put_le32(pbc, color); > - > -idx = lut_idx; > -PUSH_OP(2); > -
[FFmpeg-devel] APV codec with OpenAPV support
Hi, I'm Dariusz from Samsung Electronics, you can know me from last VDD in Korea, I was presenting APV. I'm glad that Mark created native APV decoder. As you might know we're also working on APV implementation for FFmpeg. Our approach is different from yours but they can exist in FFmpeg in parallel. We're using external library OpenAPV for encoding and decoding: https://github.com/AcademySoftwareFoundation/openapv This OpenAPV implementation will be also used by Google in next Android 16: https://developer.android.com/about/versions/16/features#apv In our approach we have implemented: encoding, decoding and mp4 muxing. Today we will send patches. So I think now it's a good moment to review both implementations and integrate them in parallel in FFmpeg. What's your opinion about that? Regards, Dariusz ___ 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 v4 3/3] lavc/dxvenc: improve compatibility with Resolume products
On Tue, Apr 22, 2025 at 1:00 AM Andreas Rheinhardt wrote: > Did you try to avoid the above by modifying > ff_texturedsp_exec_compress_threads()? I considered it but adding support to substitute in padding seemed like a rather large refactor. ___ 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 v4 1/3] lavc/hashtable: create generic robin hood hash table
Emma Worley (HE12025-04-22): > Adds a generic hash table with the DXV encoder as an initial use case. Hi. This code is already really good. I have some local remarks that will not require a lot of work from you and make it better. And I have some global remarks that would require a lot of work from you and might shave a few cycles. For the rice wine of clarity, I have decided to send them separately. This is the mail about the later. After writing most of what follows I thought of checking how this data structure is used in practice. What I wrote is more relevant as the size of the entries grows, but in practice the entries are very small, which means the current version is probably close to the best. Still, I wrote it, I might as well send it. As I said, the code is already really good. I do not consider necessary to act on what I will say here, or even to read it. But it may contain ideas to do even better, for you or somebody else, for now or for later. This is about hash tables and algorithmic. Vocabulary as I will use it here: Hash bucket, or bucket: integer-indexed cell where the hash function directs us to start searching for a key. Entry: key and its associated value, as wanted by the code that uses the hash table. Entry slot, or slot: memory that can store an entry, especially relevant if pre-allocated. We all know the core difficulty with hash tables: different keys can map to the same hash value and therefore hash bucket. There are two kinds of solutions to this collision issue: - try to find another hash bucket to find an available entry slot; - make hash buckets capable of holding multiple entries, typically by the means of some kind of linked list. In the most C and simplistic implementation, hash buckets and entry slots are the same, and the code, common to add, get, del, just tries the next bucket until it finds the right key or a hole. In the most Java/GLib implementation, hash buckets are just pointers and each entry is a separately allocated slot. (Though I am sure the efficient Java hash tables are written much more in the C style.) The issue with the second way is that it requires an extra number (pointer/index, whatever) per bucket and per entry slot. The first way has two problems. Clustering ruins the efficiency the table. And deletion becomes hard, because just leaving a hole would prevent from finding an entry that has the be stored after the hole compared to its ideal place. Clustering can be reduced with a secondary hash function (or even more subtle): instead of looking at bucket h+1, look at bucket h+h'. Make sure h' and the size of the hash table do not have common factors. But that does not solve the issue of deletions. I was not familiar with this “Robin Hood” algorithm. From what I understand, it is a solution to both clustering and deletion. Excellent. Except it costs a number per bucket/slot. If we consider spending extra memory, we have to consider if the linked list solution might not be more efficient. This hash table has constant size. That makes it easy to pre-allocate all slots in a big array. It can be the same array as the buckets or a separate one. If we keep buckets = slots and if we accept to move an entry on occasion, then we can make it work with just one number per entry/bucket. When adding a new entry, if the bucket is not empty, check if it is a collision: same hash value? If it is a collision, then take any empty bucket/slot (keeping them chained is easy) for the new entry and link it to the existing one. If it is not a collision, then take the bucket/slot for the new entry after moving the entry that was there into an empty bucket. What I described above is not very nice, but it is the best I know / can find that only costs one number per bucket/slot. If we can afford to spend more memory on it, we can do better by the virtue of breaking the buckets = slots equivalence. It is especially interesting if the entries are large, because this version does not require copying entries. Also, we can have more buckets than slots, reducing collisions. All of this is very dependant on specifics. In particular, cache locality can make a solution that seems slightly worse actually better. It would require extensive benchmarking. Regards, -- Nicolas George ___ 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] aarch64/h26x: Add put_hevc_pel_bi_w_pixels
From: Zhao Zhili On rpi5 (A76): put_hevc_pel_bi_w_pixels4_8_c: 90.0 ( 1.00x) put_hevc_pel_bi_w_pixels4_8_neon: 34.1 ( 2.64x) put_hevc_pel_bi_w_pixels6_8_c: 188.3 ( 1.00x) put_hevc_pel_bi_w_pixels6_8_neon: 73.5 ( 2.56x) put_hevc_pel_bi_w_pixels8_8_c: 327.1 ( 1.00x) put_hevc_pel_bi_w_pixels8_8_neon: 75.8 ( 4.32x) put_hevc_pel_bi_w_pixels12_8_c:728.8 ( 1.00x) put_hevc_pel_bi_w_pixels12_8_neon: 186.1 ( 3.92x) put_hevc_pel_bi_w_pixels16_8_c: 1288.1 ( 1.00x) put_hevc_pel_bi_w_pixels16_8_neon: 268.5 ( 4.80x) put_hevc_pel_bi_w_pixels24_8_c: 2855.5 ( 1.00x) put_hevc_pel_bi_w_pixels24_8_neon: 723.8 ( 3.95x) put_hevc_pel_bi_w_pixels32_8_c: 5095.3 ( 1.00x) put_hevc_pel_bi_w_pixels32_8_neon:1165.0 ( 4.37x) put_hevc_pel_bi_w_pixels48_8_c: 11521.5 ( 1.00x) put_hevc_pel_bi_w_pixels48_8_neon:2856.0 ( 4.03x) put_hevc_pel_bi_w_pixels64_8_c: 21020.5 ( 1.00x) put_hevc_pel_bi_w_pixels64_8_neon:4699.1 ( 4.47x) --- libavcodec/aarch64/h26x/dsp.h | 5 + libavcodec/aarch64/h26x/epel_neon.S | 373 ++ libavcodec/aarch64/hevcdsp_init_aarch64.c | 13 + 3 files changed, 391 insertions(+) diff --git a/libavcodec/aarch64/h26x/dsp.h b/libavcodec/aarch64/h26x/dsp.h index 6ea6a8d36a..6c91004301 100644 --- a/libavcodec/aarch64/h26x/dsp.h +++ b/libavcodec/aarch64/h26x/dsp.h @@ -92,6 +92,11 @@ NEON8_FNPROTO(pel_bi_pixels, (uint8_t *dst, ptrdiff_t dststride, const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2, int height, intptr_t mx, intptr_t my, int width),); +NEON8_FNPROTO(pel_bi_w_pixels, (uint8_t *_dst, ptrdiff_t _dststride, +const uint8_t *_src, ptrdiff_t _srcstride, const int16_t *src2, +int height, int denom, int wx0, int wx1, +int ox0, int ox1, intptr_t mx, intptr_t my, int width),); + NEON8_FNPROTO(epel_bi_h, (uint8_t *dst, ptrdiff_t dststride, const uint8_t *src, ptrdiff_t srcstride, const int16_t *src2, int height, intptr_t mx, intptr_t my, int width),); diff --git a/libavcodec/aarch64/h26x/epel_neon.S b/libavcodec/aarch64/h26x/epel_neon.S index e44a448b1f..4cf6339171 100644 --- a/libavcodec/aarch64/h26x/epel_neon.S +++ b/libavcodec/aarch64/h26x/epel_neon.S @@ -473,6 +473,379 @@ function ff_hevc_put_hevc_pel_bi_pixels64_8_neon, export=1 ret endfunc +.macro load_bi_w_pixels_param +ldrsw x8, [sp]// wx1 +#if defined(__APPLE__) +ldpsw x9, x10, [sp, #4] // ox0, ox1 +ldrsw x11, [sp, #32] // width +#else +ldrsw x9, [sp, #8]// ox0 +ldrsw x10, [sp, #16] // ox1 +ldrsw x11, [sp, 40] // width +#endif +.endm + +function ff_hevc_put_hevc_pel_bi_w_pixels4_8_neon, export=1 +load_bi_w_pixels_param +add w6, w6, #6 // log2Wd +dup v0.8h, w7 // wx0 +dup v1.8h, w8 // wx1 +add w9, w9, w10 +add w9, w9, #1 // ox0 + ox1 + 1 +lsl w9, w9, w6 +add w7, w6, #1 // (log2Wd + 1) +mov x8, #(2 * HEVC_MAX_PB_SIZE) +neg w7, w7 +dup v2.4s, w9 // (ox0 + ox1 + 1) << logwWd +dup v6.4s, w7 // -(log2Wd + 1) +1: +ld1 {v4.8b}, [x2], x3 // load src +ld1 {v5.8b}, [x4], x8 // load src2 +subsw5, w5, #1 +mov v3.16b, v2.16b +ushll v4.8h, v4.8b, #6 +smlal v3.4s, v4.4h, v1.4h +smlal v3.4s, v5.4h, v0.4h +sshlv3.4s, v3.4s, v6.4s +sqxtn v3.4h, v3.4s +sqxtun v3.8b, v3.8h +st1 {v3.s}[0], [x0], x1 +b.ne1b +ret +endfunc + +function ff_hevc_put_hevc_pel_bi_w_pixels6_8_neon, export=1 +load_bi_w_pixels_param +add w6, w6, #6 // log2Wd +dup v0.8h, w7 // wx0 +dup v1.8h, w8 // wx1 +add w9, w9, w10 +add w9, w9, #1 // ox0 + ox1 + 1 +lsl w9, w9, w6 +add w7, w6, #1 // (log2Wd + 1) +mov x8, #(2 * HEVC_MAX_PB_SIZE) +neg w7, w7 +dup v2.4s, w9 // (ox0 + ox1 + 1) << logwWd +dup v6.4s, w7
Re: [FFmpeg-devel] [RFC PATCH 2/2] ffmpeg_demux: make readrate stall warning input-specific
On 2025-04-23 02:26 am, Marvin Scholz wrote: Given the readrate catchup is input-specific, it seems to make sense to also warn on a per-input demux basis. We want to warn once each time reading is resumed but only for the first stream resumption. That's the case right now. With this change, if an input stalls thrice, only the resumption after the first stall will get reported. Regards, Gyan --- fftools/ffmpeg_demux.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 6e01efc420..1f7ec20a43 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -101,6 +101,8 @@ typedef struct DemuxStream { int64_t resume_pts; // measure of how far behind packet reading is against spceified readrate int64_t lag; +// state for resume after stall warning +int resume_warned; } DemuxStream; typedef struct Demuxer { @@ -504,7 +506,6 @@ static void readrate_sleep(Demuxer *d) (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0) ); int64_t initial_burst = AV_TIME_BASE * d->readrate_initial_burst; -int resume_warn = 0; for (int i = 0; i < f->nb_streams; i++) { InputStream *ist = f->streams[i]; @@ -523,12 +524,12 @@ static void readrate_sleep(Demuxer *d) ds->lag = lag; ds->resume_wc = now; ds->resume_pts = pts; -av_log_once(ds, AV_LOG_WARNING, AV_LOG_DEBUG, &resume_warn, +av_log_once(ds, AV_LOG_WARNING, AV_LOG_DEBUG, &ds->resume_warned, "Resumed reading at pts %0.3f with rate %0.3f after a lag of %0.3fs\n", (float)pts/AV_TIME_BASE, d->readrate_catchup, (float)lag/AV_TIME_BASE); } if (ds->lag && !lag) -ds->lag = ds->resume_wc = ds->resume_pts = 0; +ds->lag = ds->resume_wc = ds->resume_pts = ds->resume_warned = 0; if (ds->resume_wc) { elapsed = now - ds->resume_wc; limit_pts = ds->resume_pts + elapsed * d->readrate_catchup; ___ 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] avfilter: add PCM dumping between filters for audio debugging
This patch introduces PCM dumping support between AVFilter links, intended for audio debugging. It adds a configure-time option `--dumpdir=PATH` to specify the output directory for raw PCM data (default: /tmp/). Two commands are exposed to control dumping: - dump_raw_start - dump_raw_stop Dump files are written as: srcname-dstname-channel.pcm Supports packed and planar formats. File descriptors are managed automatically and work only on audio links. Example usage: avfilter_process_command(filter, "dump_raw_start", "volume", NULL, 0, 0); This feature helps developers debug filter behavior by inspecting intermediate audio data. --- >From 6a31c85afd2800c09076c1e2b7c734c7b719f73d Mon Sep 17 00:00:00 2001 From: Yibo Fang Date: Wed, 23 Apr 2025 09:17:51 +0800 Subject: [PATCH 1/1] avfilter: add PCM dumping between filters for audio debugging This patch adds the ability to dump raw PCM audio data between AVFilter links. It introduces a configure-time option `--dumpdir=PATH` to control the output directory of dump files (default: /tmp/). This feature is helpful for debugging filter behavior and verifying audio processing. Two filter commands are added: - dump_raw_start - dump_raw_stop The PCM files are written in the format: srcname-dstname-.pcm. Supports both packed and planar formats. File descriptors are automatically managed. Works only on audio links. Example usage: avfilter_process_command(filter, "dump_raw_start", "volume", NULL, 0, 0); Signed-off-by: Yibo Fang --- configure | 7 +++ libavfilter/avfilter.c | 110 + libavfilter/avfilter.h | 4 ++ 3 files changed, 121 insertions(+) diff --git a/configure b/configure index c94b8eac43..381633749d 100755 --- a/configure +++ b/configure @@ -524,6 +524,7 @@ Developer options (useful when working on FFmpeg itself): --disable-large-testsdisable tests that use a large amount of memory --disable-ptx-compression don't compress CUDA PTX code even when possible --disable-version-tracking don't include the git/release version in the build + --dumpdir=PATH location of pcm dump files to save. NOTE: Object files are built at the place where configure is launched. EOF @@ -2690,6 +2691,7 @@ PATHS_LIST=" prefix shlibdir install_name_dir +dumpdir " CMDLINE_SET=" @@ -4123,6 +4125,9 @@ incdir_default='${prefix}/include' libdir_default='${prefix}/lib' mandir_default='${prefix}/share/man' +# runtime path +dumpdir_default='/tmp/' + # toolchain ar_default="ar" cc_default="gcc" @@ -8118,6 +8123,7 @@ DOCDIR=\$(DESTDIR)$docdir MANDIR=\$(DESTDIR)$mandir PKGCONFIGDIR=\$(DESTDIR)$pkgconfigdir INSTALL_NAME_DIR=$install_name_dir +DUMPDIR=$dumpdir SRC_PATH=$source_path SRC_LINK=$source_link ifndef MAIN_MAKEFILE @@ -8267,6 +8273,7 @@ cat > $TMPH < +#include + #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/bprint.h" @@ -195,6 +198,66 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad, return 0; } +static av_cold void link_uninit_dump_pcm(AVFilterLink *link, int stop) +{ +if (link->dump_pcm_fds) { +int i; +for (i = 0; i < link->nb_dump_pcm_fds; i++) { +if (link->dump_pcm_fds[i]) +close(link->dump_pcm_fds[i]); +} +av_free(link->dump_pcm_fds); +link->dump_pcm_fds= NULL; +link->nb_dump_pcm_fds = 0; +} + +if (stop) +link->dump_pcm = 0; +} + +static av_cold int link_init_dump_pcm(AVFilterLink *link) +{ +char path[4096]; +int fd, i; + +link->nb_dump_pcm_fds = av_sample_fmt_is_planar(link->format)? link->ch_layout.nb_channels : 1; +link->dump_pcm_fds = av_malloc_array(link->nb_dump_pcm_fds, sizeof(int)); +if (!link->dump_pcm_fds) +return AVERROR(ENOMEM); + +for (i = 0; i < link->nb_dump_pcm_fds; i++) { +snprintf(path, sizeof(path), FFMPEG_DUMPDIR"%.16s-%.8s-%d.pcm", link->src->name, link->dst->name, i); +fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); +if (fd < 0) { +link_uninit_dump_pcm(link, 1); +return AVERROR(errno); +} +link->dump_pcm_fds[i] = fd; +} + +return 0; +} + +static int filter_set_dump_pcm(AVFilterContext *filter, const char *target, int set) +{ +int i; + +for (i = 0; i < filter->nb_outputs; i++) { +AVFilterLink *link = filter->outputs[i]; +if (!target || !strcmp(link->dst->name, target)) { +if (set) { +link->dump_pcm = 1; +} else +link_uninit_dump_pcm(link, 1); + +if (target) +return 0; +} +} + +return target ? AVERROR(EINVAL) : 0; +} + static void link_free(AVFilterLink **link) { FilterLinkInternal *li; @@ -208,6 +271,8 @@ static void link_free(AVFilterLink **link) av_channel_layout_uninit(&(*link)->ch_layout); av_frame_side_data_fr
[FFmpeg-devel] Unable to register on trac.ffmpeg.org
Hi, I apologize if this is not the appropriate mailing list for my question, but I am having trouble in registering on trac.ffmpeg.org. I filled out the form but never received the email with the verification token. Does anyone know how to fix this? Best, Rafael Laboissière ___ 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 v4 1/3] lavc/hashtable: create generic robin hood hash table
Perhaps I can add a `mode` enum parameter to the FFHashtableContext to control behavior? Then we can benchmark different behaviors on a per-use-case basis. On Tue, Apr 22, 2025 at 10:24 AM Nicolas George wrote: > > Emma Worley (HE12025-04-22): > > Adds a generic hash table with the DXV encoder as an initial use case. > > Hi. > > This code is already really good. I have some local remarks that will > not require a lot of work from you and make it better. And I have some > global remarks that would require a lot of work from you and might shave > a few cycles. For the rice wine of clarity, I have decided to send them > separately. This is the mail about the later. > > After writing most of what follows I thought of checking how this data > structure is used in practice. What I wrote is more relevant as the size > of the entries grows, but in practice the entries are very small, which > means the current version is probably close to the best. Still, I wrote > it, I might as well send it. > > As I said, the code is already really good. I do not consider necessary > to act on what I will say here, or even to read it. But it may contain > ideas to do even better, for you or somebody else, for now or for later. > > This is about hash tables and algorithmic. > > Vocabulary as I will use it here: > > Hash bucket, or bucket: integer-indexed cell where the hash function > directs us to start searching for a key. > > Entry: key and its associated value, as wanted by the code that uses the > hash table. > > Entry slot, or slot: memory that can store an entry, especially relevant > if pre-allocated. > > We all know the core difficulty with hash tables: different keys can map > to the same hash value and therefore hash bucket. There are two kinds of > solutions to this collision issue: > > - try to find another hash bucket to find an available entry slot; > > - make hash buckets capable of holding multiple entries, typically by > the means of some kind of linked list. > > In the most C and simplistic implementation, hash buckets and entry > slots are the same, and the code, common to add, get, del, just tries > the next bucket until it finds the right key or a hole. > > In the most Java/GLib implementation, hash buckets are just pointers and > each entry is a separately allocated slot. (Though I am sure the > efficient Java hash tables are written much more in the C style.) > > The issue with the second way is that it requires an extra number > (pointer/index, whatever) per bucket and per entry slot. > > The first way has two problems. Clustering ruins the efficiency the > table. And deletion becomes hard, because just leaving a hole would > prevent from finding an entry that has the be stored after the hole > compared to its ideal place. > > Clustering can be reduced with a secondary hash function (or even more > subtle): instead of looking at bucket h+1, look at bucket h+h'. Make > sure h' and the size of the hash table do not have common factors. But > that does not solve the issue of deletions. > > I was not familiar with this “Robin Hood” algorithm. From what I > understand, it is a solution to both clustering and deletion. Excellent. > > Except it costs a number per bucket/slot. > > If we consider spending extra memory, we have to consider if the linked > list solution might not be more efficient. > > This hash table has constant size. That makes it easy to pre-allocate > all slots in a big array. It can be the same array as the buckets or a > separate one. > > If we keep buckets = slots and if we accept to move an entry on > occasion, then we can make it work with just one number per > entry/bucket. When adding a new entry, if the bucket is not empty, check > if it is a collision: same hash value? If it is a collision, then take > any empty bucket/slot (keeping them chained is easy) for the new entry > and link it to the existing one. If it is not a collision, then take the > bucket/slot for the new entry after moving the entry that was there into > an empty bucket. > > What I described above is not very nice, but it is the best I know / can > find that only costs one number per bucket/slot. If we can afford to > spend more memory on it, we can do better by the virtue of breaking the > buckets = slots equivalence. > > It is especially interesting if the entries are large, because this > version does not require copying entries. Also, we can have more buckets > than slots, reducing collisions. > > All of this is very dependant on specifics. In particular, cache > locality can make a solution that seems slightly worse actually better. > It would require extensive benchmarking. > > Regards, > > -- > Nicolas George > ___ > 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 1/2] ffmpeg_demux: init resume_warn variable
Fixes an uninitialized read introduced with 6232f416b172358c9dd82462037953f02743df27 Fix CID1643162 Uninitialized scalar variable --- fftools/ffmpeg_demux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index cb4318c75b..6e01efc420 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -504,7 +504,7 @@ static void readrate_sleep(Demuxer *d) (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0) ); int64_t initial_burst = AV_TIME_BASE * d->readrate_initial_burst; -int resume_warn; +int resume_warn = 0; for (int i = 0; i < f->nb_streams; i++) { InputStream *ist = f->streams[i]; -- 2.39.5 (Apple Git-154) ___ 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] [RFC PATCH 2/2] ffmpeg_demux: make readrate stall warning input-specific
Given the readrate catchup is input-specific, it seems to make sense to also warn on a per-input demux basis. --- fftools/ffmpeg_demux.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 6e01efc420..1f7ec20a43 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -101,6 +101,8 @@ typedef struct DemuxStream { int64_t resume_pts; // measure of how far behind packet reading is against spceified readrate int64_t lag; +// state for resume after stall warning +int resume_warned; } DemuxStream; typedef struct Demuxer { @@ -504,7 +506,6 @@ static void readrate_sleep(Demuxer *d) (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0) ); int64_t initial_burst = AV_TIME_BASE * d->readrate_initial_burst; -int resume_warn = 0; for (int i = 0; i < f->nb_streams; i++) { InputStream *ist = f->streams[i]; @@ -523,12 +524,12 @@ static void readrate_sleep(Demuxer *d) ds->lag = lag; ds->resume_wc = now; ds->resume_pts = pts; -av_log_once(ds, AV_LOG_WARNING, AV_LOG_DEBUG, &resume_warn, +av_log_once(ds, AV_LOG_WARNING, AV_LOG_DEBUG, &ds->resume_warned, "Resumed reading at pts %0.3f with rate %0.3f after a lag of %0.3fs\n", (float)pts/AV_TIME_BASE, d->readrate_catchup, (float)lag/AV_TIME_BASE); } if (ds->lag && !lag) -ds->lag = ds->resume_wc = ds->resume_pts = 0; +ds->lag = ds->resume_wc = ds->resume_pts = ds->resume_warned = 0; if (ds->resume_wc) { elapsed = now - ds->resume_wc; limit_pts = ds->resume_pts + elapsed * d->readrate_catchup; -- 2.39.5 (Apple Git-154) ___ 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 1/2] tests: Add stream dump test API util, use it to dump stream data for chained ogg/{vorbis, opus, flac} streams.
--- tests/Makefile | 4 + tests/api/Makefile | 2 +- tests/api/api-dump-stream-meta-test.c | 177 + tests/fate/ogg-flac.mak| 11 ++ tests/fate/ogg-opus.mak| 11 ++ tests/fate/ogg-vorbis.mak | 11 ++ tests/ref/fate/ogg-flac-chained-meta.txt | 12 ++ tests/ref/fate/ogg-opus-chained-meta.txt | 27 tests/ref/fate/ogg-vorbis-chained-meta.txt | 17 ++ 9 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 tests/api/api-dump-stream-meta-test.c create mode 100644 tests/fate/ogg-flac.mak create mode 100644 tests/fate/ogg-opus.mak create mode 100644 tests/fate/ogg-vorbis.mak create mode 100644 tests/ref/fate/ogg-flac-chained-meta.txt create mode 100644 tests/ref/fate/ogg-opus-chained-meta.txt create mode 100644 tests/ref/fate/ogg-vorbis-chained-meta.txt diff --git a/tests/Makefile b/tests/Makefile index f9f5fc07f3..75b9bcc729 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -219,6 +219,9 @@ include $(SRC_PATH)/tests/fate/mpeg4.mak include $(SRC_PATH)/tests/fate/mpegps.mak include $(SRC_PATH)/tests/fate/mpegts.mak include $(SRC_PATH)/tests/fate/mxf.mak +include $(SRC_PATH)/tests/fate/ogg-vorbis.mak +include $(SRC_PATH)/tests/fate/ogg-flac.mak +include $(SRC_PATH)/tests/fate/ogg-opus.mak include $(SRC_PATH)/tests/fate/oma.mak include $(SRC_PATH)/tests/fate/opus.mak include $(SRC_PATH)/tests/fate/pcm.mak @@ -277,6 +280,7 @@ $(FATE_FFPROBE) $(FATE_FFMPEG_FFPROBE) $(FATE_SAMPLES_FFPROBE) $(FATE_SAMPLES_FF $(FATE_SAMPLES_FASTSTART): tools/qt-faststart$(EXESUF) $(FATE_SAMPLES_DUMP_DATA) $(FATE_SAMPLES_DUMP_DATA-yes): tools/venc_data_dump$(EXESUF) $(FATE_SAMPLES_SCALE_SLICE): tools/scale_slice_test$(EXESUF) +$(FATE_SAMPLES_DUMP_STREAM_META): tests/api/api-dump-stream-meta-test$(EXESUF) ifdef SAMPLES FATE += $(FATE_EXTERN) diff --git a/tests/api/Makefile b/tests/api/Makefile index c96e636756..a2cb06a729 100644 --- a/tests/api/Makefile +++ b/tests/api/Makefile @@ -1,7 +1,7 @@ APITESTPROGS-$(call ENCDEC, FLAC, FLAC) += api-flac APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264 APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264-slice -APITESTPROGS-yes += api-seek +APITESTPROGS-yes += api-seek api-dump-stream-meta APITESTPROGS-$(call DEMDEC, H263, H263) += api-band APITESTPROGS-$(HAVE_THREADS) += api-threadmessage APITESTPROGS += $(APITESTPROGS-yes) diff --git a/tests/api/api-dump-stream-meta-test.c b/tests/api/api-dump-stream-meta-test.c new file mode 100644 index 00..bbfbd1f30b --- /dev/null +++ b/tests/api/api-dump-stream-meta-test.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2025 Romain Beauxis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Dump stream metadata + */ + +#include "libavcodec/avcodec.h" +#include "libavformat/avformat.h" +#include "libavutil/timestamp.h" + +static int dump_stream_meta(const char *input_filename) { +const AVCodec *codec = NULL; +AVPacket *pkt = NULL; +AVFrame *fr = NULL; +AVFormatContext *fmt_ctx = NULL; +AVCodecContext *ctx = NULL; +AVCodecParameters *origin_par = NULL; +AVStream *st; +int stream_idx = 0; +int result; +char *metadata; + +result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); +if (result < 0) { +av_log(NULL, AV_LOG_ERROR, "Can't open file\n"); +return result; +} + +result = avformat_find_stream_info(fmt_ctx, NULL); +if (result < 0) { +av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n"); +goto end; +} + +if (fmt_ctx->nb_streams > 1) { +av_log(NULL, AV_LOG_ERROR, "More than one stream found in input!\n"); +goto end; +} + +origin_par = fmt_ctx->streams[stream_idx]->codecpar; +st = fmt_ctx->streams[stream_idx]; + +result = av_dict_get_string(st->metadata, &metadata, '=', ':'); +if (resu
[FFmpeg-devel] [PATCH 0/2] Remove chained ogg stream header packets from demuxer.
These patches remove the ogg header packets from secondary chainged ogg streams from the demuxer. First, a test utility is added to track what is currently happening with chained streams. Then the changes are introduced: the packet demuxing function is used to explicitely tell the demuxer to skip header packets. Also, the packet demuxing functions are adapted to properly copy extra data from the new chained streams so that decoding can keep happening. The diff from the test output makes it possible to follow what the changes do to the extracted streams. Test samples are available at: https://www.dropbox.com/scl/fo/xrtrna2rxr1j354hrtymq/AGwemlxHYecBLNmQ8Fsy--4?rlkey=lzilr4m9w4gfdqygoe172vvy8&dl=0 Romain Beauxis (2): tests: Add stream dump test API util, use it to dump stream data for chained ogg/{vorbis,opus,flac} streams. ogg/{vorbis,flac,opus}: Remove header packets from subsequent ogg streams from the demuxer output. libavformat/oggdec.c | 26 +-- libavformat/oggdec.h | 6 + libavformat/oggparseflac.c | 28 +++- libavformat/oggparseopus.c | 12 ++ libavformat/oggparsevorbis.c | 4 +- tests/Makefile | 4 + tests/api/Makefile | 2 +- tests/api/api-dump-stream-meta-test.c | 177 + tests/fate/ogg-flac.mak| 11 ++ tests/fate/ogg-opus.mak| 11 ++ tests/fate/ogg-vorbis.mak | 11 ++ tests/ref/fate/ogg-flac-chained-meta.txt | 10 ++ tests/ref/fate/ogg-opus-chained-meta.txt | 26 +++ tests/ref/fate/ogg-vorbis-chained-meta.txt | 14 ++ 14 files changed, 326 insertions(+), 16 deletions(-) create mode 100644 tests/api/api-dump-stream-meta-test.c create mode 100644 tests/fate/ogg-flac.mak create mode 100644 tests/fate/ogg-opus.mak create mode 100644 tests/fate/ogg-vorbis.mak create mode 100644 tests/ref/fate/ogg-flac-chained-meta.txt create mode 100644 tests/ref/fate/ogg-opus-chained-meta.txt create mode 100644 tests/ref/fate/ogg-vorbis-chained-meta.txt -- 2.39.5 (Apple Git-154) ___ 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 2/2] ogg/{vorbis, flac, opus}: Remove header packets from subsequent ogg streams from the demuxer output.
--- libavformat/oggdec.c | 26 ++-- libavformat/oggdec.h | 6 + libavformat/oggparseflac.c | 28 -- libavformat/oggparseopus.c | 12 ++ libavformat/oggparsevorbis.c | 4 +++- tests/ref/fate/ogg-flac-chained-meta.txt | 2 -- tests/ref/fate/ogg-opus-chained-meta.txt | 1 - tests/ref/fate/ogg-vorbis-chained-meta.txt | 3 --- 8 files changed, 61 insertions(+), 21 deletions(-) diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 5339fdd32c..5557eb4a14 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -239,10 +239,6 @@ static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic, os->start_trimming = 0; os->end_trimming = 0; -/* Chained files have extradata as a new packet */ -if (codec == &ff_opus_codec) -os->header = -1; - return i; } @@ -605,20 +601,26 @@ static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, } else { os->pflags= 0; os->pduration = 0; + +ret = 0; if (os->codec && os->codec->packet) { if ((ret = os->codec->packet(s, idx)) < 0) { av_log(s, AV_LOG_ERROR, "Packet processing failed: %s\n", av_err2str(ret)); return ret; } } -if (sid) -*sid = idx; -if (dstart) -*dstart = os->pstart; -if (dsize) -*dsize = os->psize; -if (fpos) -*fpos = os->sync_pos; + +if (!ret) { +if (sid) +*sid = idx; +if (dstart) +*dstart = os->pstart; +if (dsize) +*dsize = os->psize; +if (fpos) +*fpos = os->sync_pos; +} + os->pstart += os->psize; os->psize= 0; if(os->pstart == os->bufpos) diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h index 43df23f4cb..09f698f99a 100644 --- a/libavformat/oggdec.h +++ b/libavformat/oggdec.h @@ -38,6 +38,12 @@ struct ogg_codec { * -1 if an error occurred or for unsupported stream */ int (*header)(AVFormatContext *, int); +/** + * Attempt to process a packet as a data packet + * @return 1 if the packet was a header from a chained bitstream. + * 0 if the packet was a regular data packet. + * -1 if an error occurred or for unsupported stream + */ int (*packet)(AVFormatContext *, int); /** * Translate a granule into a timestamp. diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c index f25ed9cc15..d66b85b09e 100644 --- a/libavformat/oggparseflac.c +++ b/libavformat/oggparseflac.c @@ -27,6 +27,8 @@ #include "oggdec.h" #define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F +#define OGG_FLAC_MAGIC "\177FLAC" +#define OGG_FLAC_MAGIC_SIZE sizeof(OGG_FLAC_MAGIC)-1 static int flac_header (AVFormatContext * s, int idx) @@ -78,6 +80,27 @@ flac_header (AVFormatContext * s, int idx) return 1; } +static int +flac_packet (AVFormatContext * s, int idx) +{ +struct ogg *ogg = s->priv_data; +struct ogg_stream *os = ogg->streams + idx; + +if (os->psize > OGG_FLAC_MAGIC_SIZE && +!memcmp( +os->buf + os->pstart, +OGG_FLAC_MAGIC, +OGG_FLAC_MAGIC_SIZE)) +return 1; + +if (os->psize > 0 && +((os->buf[os->pstart] & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT)) { +return 1; +} + +return 0; +} + static int old_flac_header (AVFormatContext * s, int idx) { @@ -127,10 +150,11 @@ fail: } const struct ogg_codec ff_flac_codec = { -.magic = "\177FLAC", -.magicsize = 5, +.magic = OGG_FLAC_MAGIC, +.magicsize = OGG_FLAC_MAGIC_SIZE, .header = flac_header, .nb_header = 2, +.packet = flac_packet, }; const struct ogg_codec ff_old_flac_codec = { diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c index 218e9df581..07ddba8c82 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -81,6 +81,7 @@ static int opus_header(AVFormatContext *avf, int idx) if (priv->need_comments) { if (os->psize < 8 || memcmp(packet, "OpusTags", 8)) return AVERROR_INVALIDDATA; + ff_vorbis_stream_comment(avf, st, packet + 8, os->psize - 8); priv->need_comments--; return 1; @@ -125,6 +126,17 @@ static int opus_packet(AVFormatContext *avf, int idx) return AVERROR_INVALIDDATA; } + if (os->psize > 8 && !memcmp(packet, "OpusHead", 8)) { +if ((ret = ff_alloc_extradata(st->codecpar, os->psize)) < 0) +return ret; + +memcpy(st->codecpar->extradata, packet, os->psize); +return 1; +} + +if (os->psize > 8 && !memcmp(packet, "OpusTags", 8)) +return 1; + if ((!os->lastpts || os->las
[FFmpeg-devel] [PATCH] avformat/iamfdec: Check side_substream_id before use
Fixes: poc-iamf-2025-04 Found-by: 苏童 <220235...@seu.edu.cn> Signed-off-by: Michael Niedermayer --- libavformat/iamfdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/iamfdec.c b/libavformat/iamfdec.c index 0f273bdd438..3a6276dcdea 100644 --- a/libavformat/iamfdec.c +++ b/libavformat/iamfdec.c @@ -126,7 +126,7 @@ static int iamf_read_header(AVFormatContext *s) // Swap back and side stream ids as our native channel layout ordering doen't match the // order from ITU-R - BS.2051-3 for Systems I and J (where side channels come before back ones). -if (back_substream_id >= 0 && av_channel_layout_compare(&layer->ch_layout, +if (back_substream_id >= 0 && side_substream_id >= 0 && av_channel_layout_compare(&layer->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_9POINT1POINT6)) { const IAMFSubStream *back_substream = &audio_element->substreams[back_substream_id]; const IAMFSubStream *side_substream = &audio_element->substreams[side_substream_id]; -- 2.49.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] postproc/postprocess_template: Fix reading uninitialized pixels in dering_C()
This issue was found through the new blocktest Signed-off-by: Michael Niedermayer --- libpostproc/postprocess_altivec_template.c | 2 +- libpostproc/postprocess_template.c | 14 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libpostproc/postprocess_altivec_template.c b/libpostproc/postprocess_altivec_template.c index 827d6300e5f..1fc7c65ee47 100644 --- a/libpostproc/postprocess_altivec_template.c +++ b/libpostproc/postprocess_altivec_template.c @@ -530,7 +530,7 @@ static inline void doVertDefFilter_altivec(uint8_t src[], int stride, PPContext STORE(5) } -static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) { +static inline void dering_altivec(uint8_t src[], int stride, PPContext *c, int leftborder, int rightborder) { const vector signed int vsint32_8 = vec_splat_s32(8); const vector unsigned int vuint32_4 = vec_splat_u32(4); const vector signed char neg1 = vec_splat_s8(-1); diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c index f0e3c50d88c..d2e7a642ffb 100644 --- a/libpostproc/postprocess_template.c +++ b/libpostproc/postprocess_template.c @@ -831,7 +831,7 @@ static inline void RENAME(doVertDefFilter)(uint8_t src[], int stride, PPContext #endif //TEMPLATE_PP_ALTIVEC #if !TEMPLATE_PP_ALTIVEC -static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c) +static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c, int leftborder, int rightborder) { #if TEMPLATE_PP_MMXEXT && HAVE_7REGS DECLARE_ALIGNED(8, uint64_t, tmp)[3]; @@ -1046,7 +1046,7 @@ DERING_CORE((%0, %1, 8) ,(%%FF_REGd, %1, 4),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5, for(y=0; y<10; y++){ int t = 0; -if(src[stride*y + 0] > avg) t+= 1; +if(!leftborder && src[stride*y + 0] > avg) t+= 1; if(src[stride*y + 1] > avg) t+= 2; if(src[stride*y + 2] > avg) t+= 4; if(src[stride*y + 3] > avg) t+= 8; @@ -1055,7 +1055,7 @@ DERING_CORE((%0, %1, 8) ,(%%FF_REGd, %1, 4),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5, if(src[stride*y + 6] > avg) t+= 64; if(src[stride*y + 7] > avg) t+= 128; if(src[stride*y + 8] > avg) t+= 256; -if(src[stride*y + 9] > avg) t+= 512; +if(!rightborder && src[stride*y + 9] > avg) t+= 512; t |= (~t)<<16; t &= (t<<1) & (t>>1); @@ -1072,8 +1072,8 @@ DERING_CORE((%0, %1, 8) ,(%%FF_REGd, %1, 4),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5, int x; int t = s[y-1]; -p= src + stride*y; -for(x=1; x<9; x++){ +p= src + stride*y + leftborder; +for(x=1+leftborder; x<9-rightborder; x++){ p++; if(t & (1<0) RENAME(dering)(dstBlock - stride - 8, stride, c); +if(y>0) RENAME(dering)(dstBlock - stride - 8, stride, c, x<=8, 0); } if(mode & TEMP_NOISE_FILTER) @@ -3232,7 +3232,7 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ } if(mode & DERING){ -if(y > 0) RENAME(dering)(dstBlock - dstStride - 8, dstStride, c); +if(y > 0) RENAME(dering)(dstBlock - dstStride - 8, dstStride, c, 0, 1); } if((mode & TEMP_NOISE_FILTER)){ -- 2.49.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/dump: Change precision of stream start offsets
On Tue, 22 Apr 2025, Gyan Doshi wrote: On 2025-04-22 02:22 am, softworkz . wrote: -Original Message- From: ffmpeg-devel On Behalf Of Marton Balint Sent: Montag, 21. April 2025 22:18 To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] avformat/dump: Change precision of stream start offsets On Mon, 21 Apr 2025, softworkz . wrote: -Original Message- From: ffmpeg-devel On Behalf Of Marton Balint Sent: Montag, 21. April 2025 21:32 To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] avformat/dump: Change precision of stream start offsets On Mon, 21 Apr 2025, softworkz . wrote: -Original Message- From: ffmpeg-devel On Behalf Of Gyan Doshi Sent: Montag, 21. April 2025 06:51 To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] avformat/dump: Change precision of stream start offsets On 2025-04-21 01:41 am, softworkz wrote: From: softworkz Changing this to 6 digits to align with other printed times Signed-off-by: softworkz --- avformat/dump: Change precision of stream start offsets Changing this to 6 digits to align with other printed times Signed-off-by: softworkz softwo...@hotmail.com Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr- ffstaging-72%2Fsoftworkz%2Fsubmit_start_offsets-v1 Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr- ffstaging-72/softworkz/submit_start_offsets-v1 Pull-Request: https://github.com/ffstaging/FFmpeg/pull/72 libavformat/dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dump.c b/libavformat/dump.c index 8c7db7b275..1bd0424f3d 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -680,7 +680,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (st->start_time != AV_NOPTS_VALUE && st->start_time != 0 && st->time_base.den && st->time_base.num) { const double stream_start = av_q2d(st->time_base) * st- start_time; -av_log(NULL, AV_LOG_INFO, ", Start-Time %.3fs", stream_start); +av_log(NULL, AV_LOG_INFO, ", Start-Time %.6fs", stream_start); The camel case is incongruous with the formatting of the text next To It. Hi Gyan, as far as I'm seeing it, captions/labels are title case and values are lower case. I would consider "Start-Time" to be a caption/label. Let's look at an example: Stream #0:0[0x8fd]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], Level 40, 25 fps, 50 tbr, 90k tbn, Start-Time 32476.588s Stream #0:1[0x907](dut): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s, Start-Time 32476.706s Stream #0:2[0x908](dut): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 448 kb/s, Start-Time 32476.643s Stream #0:3[0x909](GOS): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s, Start-Time 32476.674s (visual impaired) (descriptions) Stream #0:4[0x962](dut): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006), Start-Time 32476.588s Stream #0:5[0x963](dut): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006), Start-Time 32476.719s (hearing impaired) I think Gyan means fps, tbr or tbn. These are all lowercase and abbreviations. Yes, I understood that. But these are units, not labels. The one-line stream info should be as compact as possible. Agreed. So we should make it shorter, and we should lose the "s" unit as well. I'm afraid, but omitting the unit makes no sense to me. Why? Because it is redundant. You always print the start time in seconds, users will have no problem guessing the time measurement unit of timestamps. E.g. see the status line of ffplay or mpv. Timestamps or time differences miss the measurement unit, and nobody complianed... It's redundant only for those who know what it is. Everybody else will need to guess whether it's s or ms or us and whether it's in the time base of the stream or not. With the same argument, you can omit kb/s, fps, tbr, tbn etc. (user can infer the units from the order and count of values) This is something that I totally hate when applications are doing it, and I need to dig down deep into the source code for getting a definitive answer. Letting users "guess" is not ok IMO. Something like: "in 1234.567" What means "in"? in is short for inpoint. Maybe "offset" if it's gotta be short..? Or simply "start", if you don't like "in". It's not about liking, it's just that "in" doesn't ring any bell for me in that context. The problem with start is that it could also mean the timestamp value where the stream (incl. container) starts, so "start-offset" or "stream-start" would be more clear imo, even though I wouldn't completely reject having just "Start". Regarding the casing: Example: Stream #0:0(eng): Video
Re: [FFmpeg-devel] [PATCH v4 04/11] fftools/tf_internal: Use ac_default_item_name
> -Original Message- > From: Stefano Sabatini > Sent: Montag, 21. April 2025 19:31 > To: FFmpeg development discussions and patches de...@ffmpeg.org> > Cc: softworkz > Subject: Re: [FFmpeg-devel] [PATCH v4 04/11] fftools/tf_internal: Use > ac_default_item_name > > On date Sunday 2025-04-20 22:59:07 +, softworkz wrote: > > From: softworkz > > > > Signed-off-by: softworkz > > --- > > fftools/textformat/tf_internal.h | 6 +- > > 1 file changed, 1 insertion(+), 5 deletions(-) > > Typo in commit headling: ac_default... -> av_default... > > > > > diff --git a/fftools/textformat/tf_internal.h > b/fftools/textformat/tf_internal.h > > index 7b326328cb..e145bc83bb 100644 > > --- a/fftools/textformat/tf_internal.h > > +++ b/fftools/textformat/tf_internal.h > > @@ -29,13 +29,9 @@ > > #include "avtextformat.h" > > > > #define DEFINE_FORMATTER_CLASS(name)\ > > -static const char *name##_get_name(void *ctx) \ > > -{ \ > > -return #name ; \ > > -} \ > > static const AVClass name##_class = { \ > > .class_name = #name,\ > > -.item_name = name##_get_name, \ > > +.item_name = av_default_item_name, \ > > .option = name##_options\ > > } > > Looks good to me. Hi Stefano, thanks a lot for the review. I have applied all the suggested changes (including those where I didn't explicitly say I would). For the avtext_context_open() function, I have introduced a new structure AVTextFormatOptions to achieve a stable function signature that doesn't need to be changed when adding new options. This is done in a separate commit. The other two changes where you mentioned have been moved into their own commits as well. (V5 patchset coming) Thanks again, sw ___ 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 v4 1/3] lavc/hashtable: create generic robin hood hash table
Emma Worley (HE12025-04-22): > Adds a generic hash table with the DXV encoder as an initial use case. > > Signed-off-by: Emma Worley > --- > libavcodec/Makefile | 2 + > libavcodec/hashtable.c | 192 +++ > libavcodec/hashtable.h | 91 + Thanks. Since it is no longer public and the only user for now has small entries and a bounded total size, I would suggest to change back all the unsigned integers that I-do-not-remember-who had you replace with size_t and see the effect on speed. I suspect it might be non-negligible. You can use a typedef to make switching between size_t and unsigned easy. > libavcodec/tests/hashtable.c | 110 > 4 files changed, 395 insertions(+) > create mode 100644 libavcodec/hashtable.c > create mode 100644 libavcodec/hashtable.h > create mode 100644 libavcodec/tests/hashtable.c > > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index 7bd1dbec9a..8071c59378 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -42,6 +42,7 @@ OBJS = ac3_parser.o > \ > dv_profile.o \ > encode.o \ > get_buffer.o \ > + hashtable.o \ > imgconvert.o \ > jni.o\ > lcevcdec.o \ > @@ -1321,6 +1322,7 @@ TESTPROGS = avcodec > \ > bitstream_le\ > celp_math \ > codec_desc \ > +hashtable \ > htmlsubtitles \ > jpeg2000dwt \ > mathops\ > diff --git a/libavcodec/hashtable.c b/libavcodec/hashtable.c > new file mode 100644 > index 00..4d6d4a9506 > --- /dev/null > +++ b/libavcodec/hashtable.c > @@ -0,0 +1,192 @@ > +/* > + * Generic hashtable > + * Copyright (C) 2024 Connor Worley > + * > + * 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 "libavutil/crc.h" > +#include "libavutil/error.h" > +#include "libavutil/mem.h" > +#include "hashtable.h" > + > +#define ALIGN _Alignof(size_t) > + > +struct FFHashtableContext { > +size_t key_size; > +size_t key_size_aligned; > +size_t val_size; > +size_t val_size_aligned; > +size_t entry_size; > +size_t max_entries; > +size_t utilization; Nit: nb_entries? > +const AVCRC *crc; > +uint8_t *table; > +uint8_t *swapbuf; > +}; > + > +#define ENTRY_PSL(entry) (entry) Except for the definition of the next macro, it is always used with *(size_t*) in front, you might as well make it part of the macro. > +#define ENTRY_OCC(entry) (ENTRY_PSL(entry) + FFALIGN(sizeof(size_t), ALIGN)) Is it a flag that tells if the bucket is occupied? Maybe add a comment. Also, you could make *ENTRY_PSL(entry) one more than it is currently, zero for an empty bucket. It saves one field. And less memory without more complex code should be faster. > +#define ENTRY_KEY(entry) (ENTRY_OCC(entry) + FFALIGN(sizeof(size_t), ALIGN)) > +#define ENTRY_VAL(entry) (ENTRY_KEY(entry) + ctx->key_size_aligned) > + > +#define KEYS_EQUAL(k1, k2) !memcmp(k1, k2, ctx->key_size) Not necessary here but usually a good practice to protect macros with parentheses. > + > +int ff_hashtable_alloc(struct FFHashtableContext **ctx, size_t key_size, > size_t val_size, size_t max_entries) > +{ > +struct FFHashtableContext *res = av_malloc(sizeof(struct > FFHashtableContext)); > +if (!res) > +return AVERROR(ENO
Re: [FFmpeg-devel] [PATCH v4 1/3] lavc/hashtable: create generic robin hood hash table
Emma Worley (HE12025-04-22): > Perhaps I can add a `mode` enum parameter to the FFHashtableContext to > control behavior? Then we can benchmark different behaviors on a > per-use-case basis. For benchmarks, I think #ifdef might be less hassle. Anyway, I repeat: I do not consider it mandatory, and it probably is only relevant for larger entries. Regards, -- Nicolas George ___ 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 v5 01/14] fftools/textformat: Formatting and whitespace changes
From: softworkz Signed-off-by: softworkz --- fftools/textformat/avtextformat.c | 86 ++-- fftools/textformat/avtextformat.h | 16 +++--- fftools/textformat/avtextwriters.h | 11 ++-- fftools/textformat/tf_compact.c| 91 +- fftools/textformat/tf_default.c| 20 +++ fftools/textformat/tf_flat.c | 26 + fftools/textformat/tf_ini.c| 36 ++-- fftools/textformat/tf_json.c | 10 ++-- fftools/textformat/tf_xml.c| 30 +- 9 files changed, 172 insertions(+), 154 deletions(-) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 9200b9b1ad..74d179c516 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -34,9 +34,9 @@ #include "libavutil/opt.h" #include "avtextformat.h" -#define SECTION_ID_NONE -1 +#define SECTION_ID_NONE (-1) -#define SHOW_OPTIONAL_FIELDS_AUTO -1 +#define SHOW_OPTIONAL_FIELDS_AUTO (-1) #define SHOW_OPTIONAL_FIELDS_NEVER 0 #define SHOW_OPTIONAL_FIELDS_ALWAYS 1 @@ -64,14 +64,14 @@ static const char *textcontext_get_formatter_name(void *p) static const AVOption textcontext_options[] = { { "string_validation", "set string validation mode", - OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=AV_TEXTFORMAT_STRING_VALIDATION_REPLACE}, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB-1, .unit = "sv" }, + OFFSET(string_validation), AV_OPT_TYPE_INT, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB - 1, .unit = "sv" }, { "sv", "set string validation mode", - OFFSET(string_validation), AV_OPT_TYPE_INT, {.i64=AV_TEXTFORMAT_STRING_VALIDATION_REPLACE}, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB-1, .unit = "sv" }, -{ "ignore", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_TEXTFORMAT_STRING_VALIDATION_IGNORE}, .unit = "sv" }, -{ "replace", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE}, .unit = "sv" }, -{ "fail",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_TEXTFORMAT_STRING_VALIDATION_FAIL},.unit = "sv" }, -{ "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str=""}}, -{ "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, {.str="\xEF\xBF\xBD"}}, + OFFSET(string_validation), AV_OPT_TYPE_INT, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, 0, AV_TEXTFORMAT_STRING_VALIDATION_NB - 1, .unit = "sv" }, +{ "ignore", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_IGNORE }, .unit = "sv" }, +{ "replace", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_REPLACE }, .unit = "sv" }, +{ "fail",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_TEXTFORMAT_STRING_VALIDATION_FAIL },.unit = "sv" }, +{ "string_validation_replacement", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, { .str = "" } }, +{ "svr", "set string validation replacement string", OFFSET(string_validation_replacement), AV_OPT_TYPE_STRING, { .str = "\xEF\xBF\xBD" } }, { NULL } }; @@ -126,7 +126,7 @@ void avtext_context_close(AVTextFormatContext **ptctx) int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args, -const struct AVTextFormatSection *sections, int nb_sections, +const AVTextFormatSection *sections, int nb_sections, int show_value_unit, int use_value_prefix, int use_byte_value_binary_prefix, @@ -200,7 +200,7 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form av_dict_free(&opts); } -if (show_data_hash) { +if (show_data_hash) if ((ret = av_hash_alloc(&tctx->hash, show_data_hash)) < 0) { if (ret == AVERROR(EINVAL)) { const char *n; @@ -211,7 +211,6 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form } return ret; } -} /* validate replace string */ { @@ -224,7 +223,7 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form if (ret < 0) { AVBPrint bp; av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); -bprint_bytes(&bp, p0, p-p0), +bprint_bytes(&bp, p0, p - p0), av_log(tctx, AV_LOG_ERROR, "Invalid UTF8 sequence %s found in string validation replace '%s'\n", bp.str, tctx->string_validation_replacement); @@ -248,15 +247,13 @@ fail: } /* Temporary defini
[FFmpeg-devel] [PATCH v5 00/14] Execution Graph Printing
Shortest cover letter for my longest-running FFmpeg patchset: * Apply * Build * Add the "-sg" switch to any FFmpeg command line * Press 'q' when you don't want to wait SG = Show Graph Documentation and examples can be found here: https://github.com/softworkz/ffmpeg_output_apis/wiki Version Updates === V2 == * Rebased on top of Andreas' improvements * Applied changes from review (thanks, Andreas) V3 == * Fixed all "new warnings" * Fixed out-of-tree building (thanks, Michael) V4 == * Resolved merge conflict * Fixed build on MinGW (missing include due to WIN32_LEAN_AND_MEAN being defined) (thanks, Michael) V5 == * Applied changes as per review from Stefano (thanks!) * Introduced AVTextFormatOptions struct for options in avtext_context_open() . softworkz (14): fftools/textformat: Formatting and whitespace changes fftools/textformat: Apply quality improvements fftools/avtextformat: Re-use BPrint in loop fftools/textformat: Introduce AVTextFormatOptions for avtext_context_open() fftools/textformat: Introduce common header and deduplicate code fftools/textformat: AVTextWriter change writer_printf signature fftools/tf_internal: Use av_default_item_name fftools/textformat: Add function avtext_print_integer_flags() fftools/ffmpeg_filter: Move some declaration to new header file avfilter/avfilter: Add avfilter_link_get_hw_frames_ctx() fftools/resources: Add resource manager files fftools/ffmpeg_mux: Make ms_from_ost() inline fftools/graphprint: Add execution graph printing fftools/graphprint: Now, make it a Killer-Feature! doc/APIchanges |3 + doc/ffmpeg.texi| 14 + ffbuild/common.mak | 28 +- fftools/Makefile | 22 +- fftools/ffmpeg.c |4 + fftools/ffmpeg.h |4 + fftools/ffmpeg_filter.c| 195 + fftools/ffmpeg_filter.h| 234 ++ fftools/ffmpeg_mux.h |2 +- fftools/ffmpeg_opt.c | 17 + fftools/ffprobe.c | 13 +- fftools/graph/filelauncher.c | 205 + fftools/graph/graphprint.c | 1147 fftools/graph/graphprint.h | 62 ++ fftools/resources/.gitignore |4 + fftools/resources/Makefile | 27 + fftools/resources/graph.css| 353 + fftools/resources/graph.html | 86 +++ fftools/resources/resman.c | 213 ++ fftools/resources/resman.h | 50 ++ fftools/textformat/avtextformat.c | 229 +++--- fftools/textformat/avtextformat.h | 73 +- fftools/textformat/avtextwriters.h | 11 +- fftools/textformat/tf_compact.c| 121 +-- fftools/textformat/tf_default.c| 55 +- fftools/textformat/tf_flat.c | 51 +- fftools/textformat/tf_ini.c| 62 +- fftools/textformat/tf_internal.h | 81 ++ fftools/textformat/tf_json.c | 56 +- fftools/textformat/tf_mermaid.c| 658 fftools/textformat/tf_mermaid.h| 41 + fftools/textformat/tf_xml.c| 68 +- fftools/textformat/tw_avio.c | 18 +- fftools/textformat/tw_buffer.c |7 +- fftools/textformat/tw_stdout.c |8 +- libavfilter/avfilter.c |9 + libavfilter/avfilter.h | 12 + 37 files changed, 3686 insertions(+), 557 deletions(-) create mode 100644 fftools/ffmpeg_filter.h create mode 100644 fftools/graph/filelauncher.c create mode 100644 fftools/graph/graphprint.c create mode 100644 fftools/graph/graphprint.h create mode 100644 fftools/resources/.gitignore create mode 100644 fftools/resources/Makefile create mode 100644 fftools/resources/graph.css create mode 100644 fftools/resources/graph.html create mode 100644 fftools/resources/resman.c create mode 100644 fftools/resources/resman.h create mode 100644 fftools/textformat/tf_internal.h create mode 100644 fftools/textformat/tf_mermaid.c create mode 100644 fftools/textformat/tf_mermaid.h base-commit: 9e1162bdf1454d7ae3737429bcc6bd66e5da303a Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-66%2Fsoftworkz%2Fsubmit_print_execution_graph-v5 Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-66/softworkz/submit_print_execution_graph-v5 Pull-Request: https://github.com/ffstaging/FFmpeg/pull/66 Range-diff vs v4: 1: dbd9193a0d ! 1: 0672fc41e7 fftools/textformat: Formatting and whitespace changes @@ fftools/textformat/avtextformat.c: static const char *textcontext_get_formatter_ }; @@ fftools/textformat/avtextformat.c: void avtext_context_close(AVTextFormatContext **ptctx) - } --int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args, + int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormat
[FFmpeg-devel] [PATCH v5 03/14] fftools/avtextformat: Re-use BPrint in loop
From: softworkz Instead of initializing a new BPrint in each iteration of the loop, re-use the same BPrint struct and just clear it for each iteration. Signed-off-by: softworkz --- fftools/textformat/avtextformat.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 1939a1f739..0a221f4a9a 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -308,24 +308,25 @@ void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t va static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src) { -const uint8_t *p, *endp; +const uint8_t *p, *endp, *srcp = (const uint8_t *)src; AVBPrint dstbuf; +AVBPrint bp; int invalid_chars_nb = 0, ret = 0; +*dstp = NULL; av_bprint_init(&dstbuf, 0, AV_BPRINT_SIZE_UNLIMITED); +av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); -endp = src + strlen(src); -for (p = src; *p;) { -uint32_t code; +endp = srcp + strlen(src); +for (p = srcp; *p;) { +int32_t code; int invalid = 0; const uint8_t *p0 = p; if (av_utf8_decode(&code, &p, endp, tctx->string_validation_utf8_flags) < 0) { -AVBPrint bp; -av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); -bprint_bytes(&bp, p0, p-p0); -av_log(tctx, AV_LOG_DEBUG, - "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src); +av_bprint_clear(&bp); +bprint_bytes(&bp, p0, p - p0); +av_log(tctx, AV_LOG_DEBUG, "Invalid UTF-8 sequence %s found in string '%s'\n", bp.str, src); invalid = 1; } @@ -345,7 +346,7 @@ static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const } if (!invalid || tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_IGNORE) -av_bprint_append_data(&dstbuf, p0, p-p0); +av_bprint_append_data(&dstbuf, (const char *)p0, p - p0); } if (invalid_chars_nb && tctx->string_validation == AV_TEXTFORMAT_STRING_VALIDATION_REPLACE) @@ -355,6 +356,7 @@ static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const end: av_bprint_finalize(&dstbuf, dstp); +av_bprint_finalize(&bp, NULL); return ret; } -- ffmpeg-codebot ___ 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 v5 02/14] fftools/textformat: Apply quality improvements
From: softworkz Perform multiple improvements to increase code robustness. In particular: - favor unsigned counters for loops - add missing checks - avoid possibly leaks - move variable declarations to inner scopes when feasible - provide explicit type-casting when needed Signed-off-by: softworkz --- fftools/textformat/avtextformat.c | 85 --- fftools/textformat/avtextformat.h | 6 +-- fftools/textformat/tf_default.c | 8 ++- fftools/textformat/tf_ini.c | 2 +- fftools/textformat/tf_json.c | 17 --- fftools/textformat/tf_xml.c | 3 -- fftools/textformat/tw_avio.c | 11 +++- 7 files changed, 83 insertions(+), 49 deletions(-) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 74d179c516..1939a1f739 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -93,9 +93,8 @@ static const AVClass textcontext_class = { static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size) { -int i; av_bprintf(bp, "0X"); -for (i = 0; i < ubuf_size; i++) +for (unsigned i = 0; i < ubuf_size; i++) av_bprintf(bp, "%02X", ubuf[i]); } @@ -137,6 +136,9 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form AVTextFormatContext *tctx; int i, ret = 0; +if (!ptctx || !formatter) +return AVERROR(EINVAL); + if (!(tctx = av_mallocz(sizeof(AVTextFormatContext { ret = AVERROR(ENOMEM); goto fail; @@ -209,25 +211,26 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form av_log(NULL, AV_LOG_ERROR, " %s", n); av_log(NULL, AV_LOG_ERROR, "\n"); } -return ret; +goto fail; } /* validate replace string */ { -const uint8_t *p = tctx->string_validation_replacement; -const uint8_t *endp = p + strlen(p); +const uint8_t *p = (uint8_t *)tctx->string_validation_replacement; +const uint8_t *endp = p + strlen((const char *)p); while (*p) { const uint8_t *p0 = p; int32_t code; ret = av_utf8_decode(&code, &p, endp, tctx->string_validation_utf8_flags); if (ret < 0) { AVBPrint bp; -av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); +av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); bprint_bytes(&bp, p0, p - p0), av_log(tctx, AV_LOG_ERROR, "Invalid UTF8 sequence %s found in string validation replace '%s'\n", bp.str, tctx->string_validation_replacement); -return ret; +av_bprint_finalize(&bp, NULL); +goto fail; } } } @@ -255,6 +258,9 @@ static const char unit_bit_per_second_str[] = "bit/s"; void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, int section_id) { +if (section_id < 0 || section_id >= tctx->nb_sections) +return; + tctx->level++; av_assert0(tctx->level < SECTION_MAX_NB_LEVELS); @@ -268,6 +274,9 @@ void avtext_print_section_header(AVTextFormatContext *tctx, const void *data, in void avtext_print_section_footer(AVTextFormatContext *tctx) { +if (tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS) +return; + int section_id = tctx->section[tctx->level]->id; int parent_section_id = tctx->level ? tctx->section[tctx->level - 1]->id @@ -285,7 +294,11 @@ void avtext_print_section_footer(AVTextFormatContext *tctx) void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t val) { -const struct AVTextFormatSection *section = tctx->section[tctx->level]; +const AVTextFormatSection *section; + +av_assert0(key && tctx->level >= 0 && tctx->level < SECTION_MAX_NB_LEVELS); + +section = tctx->section[tctx->level]; if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) { tctx->formatter->print_integer(tctx, key, val); @@ -354,17 +367,18 @@ struct unit_value { const char *unit; }; -static char *value_string(AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv) +static char *value_string(const AVTextFormatContext *tctx, char *buf, int buf_size, struct unit_value uv) { double vald; -int64_t vali; +int64_t vali = 0; int show_float = 0; if (uv.unit == unit_second_str) { vald = uv.val.d; show_float = 1; } else { -vald = vali = uv.val.i; +vald = (double)uv.val.i; +vali = uv.val.i; } if (uv.unit == unit_second_str && tctx->use_value_sexagesimal_format) { @@ -383,17 +397,17 @@ static char *value_string(AVTextFormatContext *tctx, char *buf, int buf_size, st int64_t index; i
[FFmpeg-devel] [PATCH v5 04/14] fftools/textformat: Introduce AVTextFormatOptions for avtext_context_open()
From: softworkz This allows future addition of options without changes to the signature of avtext_context_open(). Signed-off-by: softworkz --- fftools/ffprobe.c | 13 + fftools/textformat/avtextformat.c | 21 - fftools/textformat/avtextformat.h | 22 +++--- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index f5c83925b9..1277b1e4f9 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -3168,10 +3168,15 @@ int main(int argc, char **argv) if (ret < 0) goto end; -if ((ret = avtext_context_open(&tctx, f, wctx, f_args, - sections, FF_ARRAY_ELEMS(sections), show_value_unit, -use_value_prefix, use_byte_value_binary_prefix, use_value_sexagesimal_format, -show_optional_fields, show_data_hash)) >= 0) { +AVTextFormatOptions tf_options = { +.show_optional_fields = show_optional_fields, +.show_value_unit = show_value_unit, +.use_value_prefix = use_value_prefix, +.use_byte_value_binary_prefix = use_byte_value_binary_prefix, +.use_value_sexagesimal_format = use_value_sexagesimal_format, +}; + +if ((ret = avtext_context_open(&tctx, f, wctx, f_args, sections, FF_ARRAY_ELEMS(sections), tf_options, show_data_hash)) >= 0) { if (f == &avtextformatter_xml) tctx->string_validation_utf8_flags |= AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES; diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 0a221f4a9a..217d9da25e 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -125,13 +125,7 @@ void avtext_context_close(AVTextFormatContext **ptctx) int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *formatter, AVTextWriterContext *writer_context, const char *args, -const AVTextFormatSection *sections, int nb_sections, -int show_value_unit, -int use_value_prefix, -int use_byte_value_binary_prefix, -int use_value_sexagesimal_format, -int show_optional_fields, -char *show_data_hash) +const AVTextFormatSection *sections, int nb_sections, AVTextFormatOptions options, char *show_data_hash) { AVTextFormatContext *tctx; int i, ret = 0; @@ -155,11 +149,11 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form goto fail; } -tctx->show_value_unit = show_value_unit; -tctx->use_value_prefix = use_value_prefix; -tctx->use_byte_value_binary_prefix = use_byte_value_binary_prefix; -tctx->use_value_sexagesimal_format = use_value_sexagesimal_format; -tctx->show_optional_fields = show_optional_fields; +tctx->show_value_unit = options.show_value_unit; +tctx->use_value_prefix = options.use_value_prefix; +tctx->use_byte_value_binary_prefix = options.use_byte_value_binary_prefix; +tctx->use_value_sexagesimal_format = options.use_value_sexagesimal_format; +tctx->show_optional_fields = options.show_optional_fields; if (nb_sections > SECTION_MAX_NB_SECTIONS) { av_log(tctx, AV_LOG_ERROR, "The number of section definitions (%d) is larger than the maximum allowed (%d)\n", nb_sections, SECTION_MAX_NB_SECTIONS); @@ -202,7 +196,7 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form av_dict_free(&opts); } -if (show_data_hash) +if (show_data_hash) { if ((ret = av_hash_alloc(&tctx->hash, show_data_hash)) < 0) { if (ret == AVERROR(EINVAL)) { const char *n; @@ -213,6 +207,7 @@ int avtext_context_open(AVTextFormatContext **ptctx, const AVTextFormatter *form } goto fail; } +} /* validate replace string */ { diff --git a/fftools/textformat/avtextformat.h b/fftools/textformat/avtextformat.h index aea691f351..05a358132e 100644 --- a/fftools/textformat/avtextformat.h +++ b/fftools/textformat/avtextformat.h @@ -118,17 +118,25 @@ struct AVTextFormatContext { unsigned int string_validation_utf8_flags; }; +typedef struct AVTextFormatOptions { +int show_optional_fields; +int show_value_unit; +int use_value_prefix; +int use_byte_value_binary_prefix; +int use_value_sexagesimal_format; +} AVTextFormatOptions; + #define AV_TEXTFORMAT_PRINT_STRING_OPTIONAL 1 #define AV_TEXTFORMAT_PRINT_STRING_VALIDATE 2 +#define AV_TEXTFORMAT_OPEN_SHOW_VALUE_UNIT 1 +#define AV_TEXTFORMAT_OPEN_USE_VALUE_PREFIX 2 +#define AV_TEXTFORMAT_OPEN_USE_BYTE_BINARY_PREFIX4 +#define AV_TEXTFORMAT_OPEN_USE_VALUE_SEXAGESIMAL_FORMAT 8 +#define AV_TEXTFORMAT_OPEN_SHOW_OPTIONAL_FIELDS 16 + int av
[FFmpeg-devel] [PATCH v5 13/14] fftools/graphprint: Add execution graph printing
From: softworkz The key benefits are: - Different to other graph printing methods, this is outputting: - all graphs with runtime state (including auto-inserted filters) - each graph with its inputs and outputs - all filters with their in- and output pads - all connections between all input- and output pads - for each connection: - the runtime-negotiated format and media type - the hw context - if video hw context, both: hw pixfmt + sw pixfmt - Output can either be printed to stdout or written to specified file - Output is machine-readable - Use the same output implementation as ffprobe, supporting multiple formats Signed-off-by: softworkz --- doc/ffmpeg.texi | 10 + fftools/Makefile | 20 +- fftools/ffmpeg.c |4 + fftools/ffmpeg.h |3 + fftools/ffmpeg_filter.c |5 + fftools/ffmpeg_opt.c | 13 + fftools/graph/graphprint.c| 1103 + fftools/graph/graphprint.h| 30 + fftools/textformat/avtextformat.c |2 + fftools/textformat/avtextformat.h | 29 + fftools/textformat/tf_mermaid.c | 658 + fftools/textformat/tf_mermaid.h | 41 ++ 12 files changed, 1917 insertions(+), 1 deletion(-) create mode 100644 fftools/graph/graphprint.c create mode 100644 fftools/graph/graphprint.h create mode 100644 fftools/textformat/tf_mermaid.c create mode 100644 fftools/textformat/tf_mermaid.h diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 17ba876ea3..35675b5309 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1394,6 +1394,16 @@ It is on by default, to explicitly disable it you need to specify @code{-nostats @item -stats_period @var{time} (@emph{global}) Set period at which encoding progress/statistics are updated. Default is 0.5 seconds. +@item -print_graphs (@emph{global}) +Prints execution graph details to stderr in the format set via -print_graphs_format. + +@item -print_graphs_file @var{filename} (@emph{global}) +Writes execution graph details to the specified file in the format set via -print_graphs_format. + +@item -print_graphs_format @var{format} (@emph{global}) +Sets the output format (available formats are: default, compact, csv, flat, ini, json, xml, mermaid, mermaidhtml) +The default format is json. + @item -progress @var{url} (@emph{global}) Send program-friendly progress information to @var{url}. diff --git a/fftools/Makefile b/fftools/Makefile index a30bec889e..361a4fd574 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -9,6 +9,8 @@ AVBASENAMES = ffmpeg ffplay ffprobe ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF)) ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF)) +include $(SRC_PATH)/fftools/resources/Makefile + OBJS-ffmpeg += \ fftools/ffmpeg_dec.o\ fftools/ffmpeg_demux.o \ @@ -19,8 +21,21 @@ OBJS-ffmpeg += \ fftools/ffmpeg_mux_init.o \ fftools/ffmpeg_opt.o\ fftools/ffmpeg_sched.o \ +fftools/graph/graphprint.o\ fftools/sync_queue.o\ fftools/thread_queue.o \ +fftools/textformat/avtextformat.o \ +fftools/textformat/tf_compact.o \ +fftools/textformat/tf_default.o \ +fftools/textformat/tf_flat.o \ +fftools/textformat/tf_ini.o \ +fftools/textformat/tf_json.o \ +fftools/textformat/tf_mermaid.o \ +fftools/textformat/tf_xml.o \ +fftools/textformat/tw_avio.o \ +fftools/textformat/tw_buffer.o\ +fftools/textformat/tw_stdout.o\ +$(OBJS-resman)\ OBJS-ffprobe += \ fftools/textformat/avtextformat.o \ @@ -29,10 +44,12 @@ OBJS-ffprobe += \ fftools/textformat/tf_flat.o \ fftools/textformat/tf_ini.o \ fftools/textformat/tf_json.o \ +fftools/textformat/tf_mermaid.o \ fftools/textformat/tf_xml.o \ fftools/textformat/tw_avio.o \ fftools/textformat/tw_buffer.o\ fftools/textformat/tw_stdout.o\ +$(OBJS-resman)\ OBJS-ffplay += fftools/ffplay_renderer.o @@ -42,7 +59,7 @@ ifdef HAVE_GNU_WINDRES OBJS-$(1) += fftools/fftoolsres.o endif $(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1)) -$$(OBJS-$(1)): | fftools fftools/textformat fftools/resources +$$(OBJS-$(1)): | fftools fftools/textformat fftools/resources fftools/graph $$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1)) $(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) $(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1)) @@ -57,6 +74,7 @@ fftools/ffprobe.o fftools/cmdutils.o: libavutil/ffversion.h | fftools OUTDIRS += fftools OUTDIRS += fftools/textformat OUTDIRS += fftools/resources +OUTDIRS += fftools/graph ifdef AVPROGS install: install-progs install-data diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index dc321fb4a2..6766ec209c
[FFmpeg-devel] [PATCH v5 14/14] fftools/graphprint: Now, make it a Killer-Feature!
From: softworkz remember this: -sg <= show-graph Signed-off-by: softworkz --- doc/ffmpeg.texi | 4 + fftools/Makefile | 1 + fftools/ffmpeg.c | 2 +- fftools/ffmpeg.h | 1 + fftools/ffmpeg_filter.c | 2 +- fftools/ffmpeg_opt.c | 4 + fftools/graph/filelauncher.c | 205 +++ fftools/graph/graphprint.c | 50 - fftools/graph/graphprint.h | 32 ++ 9 files changed, 296 insertions(+), 5 deletions(-) create mode 100644 fftools/graph/filelauncher.c diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 35675b5309..6e9e7aed0e 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1404,6 +1404,10 @@ Writes execution graph details to the specified file in the format set via -prin Sets the output format (available formats are: default, compact, csv, flat, ini, json, xml, mermaid, mermaidhtml) The default format is json. +@item -sg (@emph{global}) +Writes the execution graph to a temporary html file (mermaidhtml format) and +tries to launch it in the default browser. + @item -progress @var{url} (@emph{global}) Send program-friendly progress information to @var{url}. diff --git a/fftools/Makefile b/fftools/Makefile index 361a4fd574..56a2910212 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -22,6 +22,7 @@ OBJS-ffmpeg += \ fftools/ffmpeg_opt.o\ fftools/ffmpeg_sched.o \ fftools/graph/graphprint.o\ +fftools/graph/filelauncher.o \ fftools/sync_queue.o\ fftools/thread_queue.o \ fftools/textformat/avtextformat.o \ diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 6766ec209c..9875a1f7fd 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -309,7 +309,7 @@ const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; static void ffmpeg_cleanup(int ret) { -if (print_graphs || print_graphs_file) +if (print_graphs || print_graphs_file || show_graph) print_filtergraphs(filtergraphs, nb_filtergraphs, input_files, nb_input_files, output_files, nb_output_files); if (do_benchmark) { diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 7fbf0ad532..49fea0307d 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -721,6 +721,7 @@ extern int print_graphs; extern char *print_graphs_file; extern char *print_graphs_format; extern int auto_conversion_filters; +extern int show_graph; extern const AVIOInterruptCB int_cb; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index b774606562..e82e333b7f 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -2985,7 +2985,7 @@ read_frames: finish: -if (print_graphs || print_graphs_file) +if (print_graphs || print_graphs_file || show_graph) print_filtergraph(fg, fgt.graph); // EOF is normal termination diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 3d1efe32f9..24713d640f 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -79,6 +79,7 @@ int vstats_version = 2; int print_graphs = 0; char *print_graphs_file = NULL; char *print_graphs_format = NULL; +int show_graph = 0; int auto_conversion_filters = 1; int64_t stats_period = 50; @@ -1748,6 +1749,9 @@ const OptionDef options[] = { { "print_graphs_format", OPT_TYPE_STRING, 0, { &print_graphs_format }, "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml, mermaid, mermaidhtml)", "format" }, +{ "sg", OPT_TYPE_BOOL, 0, +{ &show_graph }, +"create execution graph as temporary html file and try to launch it in the default browser" }, { "auto_conversion_filters", OPT_TYPE_BOOL, OPT_EXPERT, { &auto_conversion_filters }, "enable automatic conversion filters globally" }, diff --git a/fftools/graph/filelauncher.c b/fftools/graph/filelauncher.c new file mode 100644 index 00..0cf5f15cf1 --- /dev/null +++ b/fftools/graph/filelauncher.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2025 - softworkz + * + * 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 + +#if defined(_WIN32) +# include +# include +#else +# include +# include +
[FFmpeg-devel] [PATCH v5 12/14] fftools/ffmpeg_mux: Make ms_from_ost() inline
From: softworkz Signed-off-by: softworkz --- fftools/ffmpeg_mux.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h index f41f2c18fa..4ca8ab73a4 100644 --- a/fftools/ffmpeg_mux.h +++ b/fftools/ffmpeg_mux.h @@ -123,7 +123,7 @@ typedef struct Muxer { int mux_check_init(void *arg); -static MuxStream *ms_from_ost(OutputStream *ost) +static inline MuxStream *ms_from_ost(OutputStream *ost) { return (MuxStream*)ost; } -- ffmpeg-codebot ___ 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 v5 11/14] fftools/resources: Add resource manager files
From: softworkz Signed-off-by: softworkz --- ffbuild/common.mak | 28 ++- fftools/Makefile | 3 +- fftools/resources/.gitignore | 4 + fftools/resources/Makefile | 27 +++ fftools/resources/graph.css | 353 +++ fftools/resources/graph.html | 86 + fftools/resources/resman.c | 213 + fftools/resources/resman.h | 50 + 8 files changed, 762 insertions(+), 2 deletions(-) create mode 100644 fftools/resources/.gitignore create mode 100644 fftools/resources/Makefile create mode 100644 fftools/resources/graph.css create mode 100644 fftools/resources/graph.html create mode 100644 fftools/resources/resman.c create mode 100644 fftools/resources/resman.h diff --git a/ffbuild/common.mak b/ffbuild/common.mak index ca45a0f368..6717092d44 100644 --- a/ffbuild/common.mak +++ b/ffbuild/common.mak @@ -139,6 +139,32 @@ else $(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@))) endif +# 1) Preprocess CSS to a minified version +%.css.min: %.css + # Must start with a tab in the real Makefile + sed 's!/\\*.*\\*/!!g' $< \ + | tr '\n' ' ' \ + | tr -s ' ' \ + | sed 's/^ //; s/ $$//' \ + > $@ + +# 2) Gzip the minified CSS +%.css.min.gz: %.css.min + $(M)gzip -nc9 $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) >$@ + +# 3) Convert the gzipped CSS to a .c array +%.css.c: %.css.min.gz $(BIN2CEXE) + $(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@))) + +# 4) Gzip the HTML file (no minification needed) +%.html.gz: TAG = GZIP +%.html.gz: %.html + $(M)gzip -nc9 $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) > $@ + +# 5) Convert the gzipped HTML to a .c array +%.html.c: %.html.gz $(BIN2CEXE) + $(BIN2C) $(patsubst $(SRC_PATH)/%,$(SRC_LINK)/%,$<) $@ $(subst .,_,$(basename $(notdir $@))) + clean:: $(RM) $(BIN2CEXE) $(CLEANSUFFIXES:%=ffbuild/%) @@ -214,7 +240,7 @@ $(TOOLOBJS): | tools OUTDIRS := $(OUTDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(SLIBOBJS) $(SHLIBOBJS) $(STLIBOBJS) $(TESTOBJS)) -CLEANSUFFIXES = *.d *.gcda *.gcno *.h.c *.ho *.map *.o *.objs *.pc *.ptx *.ptx.gz *.ptx.c *.ver *.version *$(DEFAULT_X86ASMD).asm *~ *.ilk *.pdb +CLEANSUFFIXES = *.d *.gcda *.gcno *.h.c *.ho *.map *.o *.objs *.pc *.ptx *.ptx.gz *.ptx.c *.ver *.version *.html.gz *.html.c *.css.gz *.css.c *$(DEFAULT_X86ASMD).asm *~ *.ilk *.pdb LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a define RULES diff --git a/fftools/Makefile b/fftools/Makefile index e9c9891c34..a30bec889e 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -42,7 +42,7 @@ ifdef HAVE_GNU_WINDRES OBJS-$(1) += fftools/fftoolsres.o endif $(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1)) -$$(OBJS-$(1)): | fftools fftools/textformat +$$(OBJS-$(1)): | fftools fftools/textformat fftools/resources $$(OBJS-$(1)): CFLAGS += $(CFLAGS-$(1)) $(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1)) $(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(EXTRALIBS-$(1)) @@ -56,6 +56,7 @@ all: $(AVPROGS) fftools/ffprobe.o fftools/cmdutils.o: libavutil/ffversion.h | fftools OUTDIRS += fftools OUTDIRS += fftools/textformat +OUTDIRS += fftools/resources ifdef AVPROGS install: install-progs install-data diff --git a/fftools/resources/.gitignore b/fftools/resources/.gitignore new file mode 100644 index 00..5f496535a6 --- /dev/null +++ b/fftools/resources/.gitignore @@ -0,0 +1,4 @@ +*.html.c +*.css.c +*.html.gz +*.css.gz diff --git a/fftools/resources/Makefile b/fftools/resources/Makefile new file mode 100644 index 00..f3a0d0a970 --- /dev/null +++ b/fftools/resources/Makefile @@ -0,0 +1,27 @@ +clean:: + $(RM) $(CLEANSUFFIXES:%=fftools/resources/%) + + +HTML_RESOURCES := fftools/resources/graph.html \ + +# .html => (gzip) .html.gz => (bin2c) .html.c => (cc) .o +HTML_RESOURCES_GZ := $(HTML_RESOURCES:.html=.html.gz) +HTML_RESOURCES_C := $(HTML_RESOURCES_GZ:.html.gz=.html.c) +HTML_RESOURCES_OBJS := $(HTML_RESOURCES_C:.c=.o) + +CSS_RESOURCES := fftools/resources/graph.css \ + +# .css => (sh) .css.min => (gzip) .css.min.gz => (bin2c) .css.c => (cc) .o +CSS_RESOURCES_MIN := $(CSS_RESOURCES:.css=.css.min) +CSS_RESOURCES_GZ := $(CSS_RESOURCES_MIN:.css.min=.css.min.gz) +CSS_RESOURCES_C := $(CSS_RESOURCES_GZ:.css.min.gz=.css.c) +CSS_RESOURCES_OBJS := $(CSS_RESOURCES_C:.c=.o) + +# Uncomment to prevent deletion +#.PRECIOUS: %.css.c %.css.min %.css.gz %.css.min.gz + +OBJS-resman += \ +fftools/resources/resman.o \ +$(HTML_RESOURCES_OBJS) \ +$(CSS_RESOURCES_OBJS) \ + diff --git a/fftools/resources/graph.css b/fftools/resources/graph.css new file mode 100644 index 00..ab480673ab --- /dev/null +++ b/fftools/resources/graph.css @@ -0,0 +1,353 @@ +/* Variables */ +.root { +--ff-colvideo: #6eaa7b; +--ff-colaudio: #477fb3; +--ff-colsubtitle: #ad76ab;
[FFmpeg-devel] [PATCH v5 05/14] fftools/textformat: Introduce common header and deduplicate code
From: softworkz Signed-off-by: softworkz --- fftools/textformat/tf_compact.c | 32 +--- fftools/textformat/tf_default.c | 27 +++--- fftools/textformat/tf_flat.c | 25 +++--- fftools/textformat/tf_ini.c | 24 +++-- fftools/textformat/tf_internal.h | 85 fftools/textformat/tf_json.c | 35 + fftools/textformat/tf_xml.c | 35 ++--- 7 files changed, 142 insertions(+), 121 deletions(-) create mode 100644 fftools/textformat/tf_internal.h diff --git a/fftools/textformat/tf_compact.c b/fftools/textformat/tf_compact.c index d4ac296a42..e52888239e 100644 --- a/fftools/textformat/tf_compact.c +++ b/fftools/textformat/tf_compact.c @@ -28,23 +28,7 @@ #include "libavutil/bprint.h" #include "libavutil/error.h" #include "libavutil/opt.h" - - -#define writer_w8(wctx_, b_) (wctx_)->writer->writer->writer_w8((wctx_)->writer, b_) -#define writer_put_str(wctx_, str_) (wctx_)->writer->writer->writer_put_str((wctx_)->writer, str_) -#define writer_printf(wctx_, fmt_, ...) (wctx_)->writer->writer->writer_printf((wctx_)->writer, fmt_, __VA_ARGS__) - - -#define DEFINE_FORMATTER_CLASS(name) \ -static const char *name##_get_name(void *ctx) \ -{ \ -return #name ; \ -} \ -static const AVClass name##_class = { \ -.class_name = #name,\ -.item_name = name##_get_name, \ -.option = name##_options\ -} +#include "tf_internal.h" /* Compact output */ @@ -157,9 +141,12 @@ static av_cold int compact_init(AVTextFormatContext *wctx) static void compact_print_section_header(AVTextFormatContext *wctx, const void *data) { CompactContext *compact = wctx->priv; -const struct AVTextFormatSection *section = wctx->section[wctx->level]; -const struct AVTextFormatSection *parent_section = wctx->level ? -wctx->section[wctx->level-1] : NULL; +const AVTextFormatSection *section = tf_get_section(wctx, wctx->level); +const AVTextFormatSection *parent_section = tf_get_parent_section(wctx, wctx->level); + +if (!section) +return; + compact->terminate_line[wctx->level] = 1; compact->has_nested_elems[wctx->level] = 0; @@ -210,8 +197,11 @@ static void compact_print_section_header(AVTextFormatContext *wctx, const void * static void compact_print_section_footer(AVTextFormatContext *wctx) { -const struct AVTextFormatSection *section = wctx->section[wctx->level]; CompactContext *compact = wctx->priv; +const AVTextFormatSection *section = tf_get_section(wctx, wctx->level); + +if (!section) +return; if (!compact->nested_section[wctx->level] && compact->terminate_line[wctx->level] && diff --git a/fftools/textformat/tf_default.c b/fftools/textformat/tf_default.c index ad97173b0b..019bda9d44 100644 --- a/fftools/textformat/tf_default.c +++ b/fftools/textformat/tf_default.c @@ -27,21 +27,7 @@ #include "avtextformat.h" #include "libavutil/bprint.h" #include "libavutil/opt.h" - -#define writer_w8(wctx_, b_) (wctx_)->writer->writer->writer_w8((wctx_)->writer, b_) -#define writer_put_str(wctx_, str_) (wctx_)->writer->writer->writer_put_str((wctx_)->writer, str_) -#define writer_printf(wctx_, fmt_, ...) (wctx_)->writer->writer->writer_printf((wctx_)->writer, fmt_, __VA_ARGS__) - -#define DEFINE_FORMATTER_CLASS(name) \ -static const char *name##_get_name(void *ctx) \ -{ \ -return #name ; \ -} \ -static const AVClass name##_class = { \ -.class_name = #name,\ -.item_name = name##_get_name, \ -.option = name##_options\ -} +#include "tf_internal.h" /* Default output */ @@ -80,9 +66,11 @@ static void default_print_section_header(AVTextFormatContext *wctx, const void * { DefaultContext *def = wctx->priv; char buf[32]; -const struct AVTextFormatSection *section = wctx->section[wctx->level]; -const struct AVTextFormatSection *parent_section = wctx->level ? -wctx->section[wctx->level-1] : NULL; +const AVTextFormatSection *section = tf_get_section(wctx, wctx->level); +const AVTextFormatSection *parent_section = tf_get_parent_section(wctx, wctx->level); + +if (!section) +return; av_bprint_clear(&wctx->section_pbuf[wctx->level]); if (parent_section && @@ -104,7 +92,8 @@ static void default_print_section_header(AVTextFormatContext *wctx, const void * static void default_print_section_footer(AVTextFormatContext *wctx) { DefaultContext *def = wctx->priv; -const struct AVTextFormatSection *section = wctx->
[FFmpeg-devel] [PATCH v5 09/14] fftools/ffmpeg_filter: Move some declaration to new header file
From: softworkz to allow filtergraph printing to access the information. Signed-off-by: softworkz --- fftools/ffmpeg_filter.c | 190 +--- fftools/ffmpeg_filter.h | 234 2 files changed, 235 insertions(+), 189 deletions(-) create mode 100644 fftools/ffmpeg_filter.h diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index d314aec206..eab9487f97 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -21,6 +21,7 @@ #include #include "ffmpeg.h" +#include "ffmpeg_filter.h" #include "libavfilter/avfilter.h" #include "libavfilter/buffersink.h" @@ -42,44 +43,6 @@ // FIXME private header, used for mid_pred() #include "libavcodec/mathops.h" -typedef struct FilterGraphPriv { -FilterGraph fg; - -// name used for logging -char log_name[32]; - -int is_simple; -// true when the filtergraph contains only meta filters -// that do not modify the frame data -int is_meta; -// source filters are present in the graph -int have_sources; -int disable_conversions; - -unsigned nb_outputs_done; - -const char *graph_desc; - -int nb_threads; - -// frame for temporarily holding output from the filtergraph -AVFrame *frame; -// frame for sending output to the encoder -AVFrame *frame_enc; - -Scheduler *sch; -unsigned sch_idx; -} FilterGraphPriv; - -static FilterGraphPriv *fgp_from_fg(FilterGraph *fg) -{ -return (FilterGraphPriv*)fg; -} - -static const FilterGraphPriv *cfgp_from_cfg(const FilterGraph *fg) -{ -return (const FilterGraphPriv*)fg; -} // data that is local to the filter thread and not visible outside of it typedef struct FilterGraphThread { @@ -102,157 +65,6 @@ typedef struct FilterGraphThread { uint8_t *eof_out; } FilterGraphThread; -typedef struct InputFilterPriv { -InputFilter ifilter; - -InputFilterOptions opts; - -int index; - -AVFilterContext*filter; - -// used to hold submitted input -AVFrame*frame; - -/* for filters that are not yet bound to an input stream, - * this stores the input linklabel, if any */ -uint8_t*linklabel; - -// filter data type -enum AVMediaTypetype; -// source data type: AVMEDIA_TYPE_SUBTITLE for sub2video, -// same as type otherwise -enum AVMediaTypetype_src; - -int eof; -int bound; -int drop_warned; -uint64_tnb_dropped; - -// parameters configured for this input -int format; - -int width, height; -AVRational sample_aspect_ratio; -enum AVColorSpace color_space; -enum AVColorRange color_range; - -int sample_rate; -AVChannelLayout ch_layout; - -AVRational time_base; - -AVFrameSideData **side_data; -int nb_side_data; - -AVFifo *frame_queue; - -AVBufferRef*hw_frames_ctx; - -int displaymatrix_present; -int displaymatrix_applied; -int32_t displaymatrix[9]; - -int downmixinfo_present; -AVDownmixInfo downmixinfo; - -struct { -AVFrame *frame; - -int64_t last_pts; -int64_t end_pts; - -/// marks if sub2video_update should force an initialization -unsigned int initialize; -} sub2video; -} InputFilterPriv; - -static InputFilterPriv *ifp_from_ifilter(InputFilter *ifilter) -{ -return (InputFilterPriv*)ifilter; -} - -typedef struct FPSConvContext { -AVFrame *last_frame; -/* number of frames emitted by the video-encoding sync code */ -int64_t frame_number; -/* history of nb_frames_prev, i.e. the number of times the - * previous frame was duplicated by vsync code in recent - * do_video_out() calls */ -int64_t frames_prev_hist[3]; - -uint64_t dup_warning; - -int last_dropped; -int dropped_keyframe; - -enum VideoSyncMethod vsync_method; - -AVRationalframerate; -AVRationalframerate_max; -const AVRational *framerate_supported; -int framerate_clip; -} FPSConvContext; - -typedef struct OutputFilterPriv { -OutputFilterofilter; - -int index; - -void *log_parent; -charlog_name[32]; - -char *name; - -AVFilterContext*filter; - -/* desired output stream properties */ -int format; -int width, height; -int sample_rate; -AVChannelLayout ch_layout; -
[FFmpeg-devel] [PATCH v5 10/14] avfilter/avfilter: Add avfilter_link_get_hw_frames_ctx()
From: softworkz Signed-off-by: softworkz --- doc/APIchanges | 3 +++ libavfilter/avfilter.c | 9 + libavfilter/avfilter.h | 12 3 files changed, 24 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index 75d66f87f3..d0869561f3 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28 API changes, most recent first: +2025-02-xx - xx - lavfi 10.10.100 - avfilter.h + Add avfilter_link_get_hw_frames_ctx(). + 2025-04-21 - xx - lavu 60.2.100 - log.h Add AV_CLASS_CATEGORY_HWDEVICE. diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 64c1075c40..c76d43a215 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -989,6 +989,15 @@ enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx) return pads[pad_idx].type; } +AVBufferRef *avfilter_link_get_hw_frames_ctx(AVFilterLink *link) +{ +FilterLink *plink = ff_filter_link(link); +if (plink->hw_frames_ctx) +return av_buffer_ref(plink->hw_frames_ctx); + +return NULL; +} + static int default_filter_frame(AVFilterLink *link, AVFrame *frame) { return ff_filter_frame(link->dst->outputs[0], frame); diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index a89d3cf658..f85929dc5c 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -96,6 +96,18 @@ const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx); */ enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx); +/** + * Get the hardware frames context of a filter link. + * + * @param link an AVFilterLink + * + * @return a ref-counted copy of the link's hw_frames_ctx field if there is + * a hardware frames context associated with the link or NULL otherwise. + * The returned AVBufferRef needs to be released with av_buffer_unref() + * when it is no longer used. + */ +AVBufferRef* avfilter_link_get_hw_frames_ctx(AVFilterLink *link); + /** * Lists of formats / etc. supported by an end of a link. * -- ffmpeg-codebot ___ 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 v5 08/14] fftools/textformat: Add function avtext_print_integer_flags()
From: softworkz This function works analog to the avtext_print_string() which already has a flags parameter. Signed-off-by: softworkz --- fftools/textformat/avtextformat.c | 21 + fftools/textformat/avtextformat.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/fftools/textformat/avtextformat.c b/fftools/textformat/avtextformat.c index 217d9da25e..4dae024814 100644 --- a/fftools/textformat/avtextformat.c +++ b/fftools/textformat/avtextformat.c @@ -301,6 +301,27 @@ void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t va } } +void avtext_print_integer_flags(AVTextFormatContext *tctx, const char *key, int64_t val, int flags) +{ +const AVTextFormatSection *section; + +if (!tctx || !key || tctx->level < 0 || tctx->level >= SECTION_MAX_NB_LEVELS) +return; + +section = tctx->section[tctx->level]; + +if (tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_NEVER || +(tctx->show_optional_fields == SHOW_OPTIONAL_FIELDS_AUTO +&& (flags & AV_TEXTFORMAT_PRINT_STRING_OPTIONAL) +&& !(tctx->formatter->flags & AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS))) +return; + +if (section->show_all_entries || av_dict_get(section->entries_to_show, key, NULL, 0)) { +tctx->formatter->print_integer(tctx, key, val); +tctx->nb_item[tctx->level]++; +} +} + static inline int validate_string(AVTextFormatContext *tctx, char **dstp, const char *src) { const uint8_t *p, *endp, *srcp = (const uint8_t *)src; diff --git a/fftools/textformat/avtextformat.h b/fftools/textformat/avtextformat.h index 05a358132e..c97a477fa9 100644 --- a/fftools/textformat/avtextformat.h +++ b/fftools/textformat/avtextformat.h @@ -147,6 +147,8 @@ void avtext_print_section_footer(AVTextFormatContext *tctx); void avtext_print_integer(AVTextFormatContext *tctx, const char *key, int64_t val); +void avtext_print_integer_flags(AVTextFormatContext *tctx, const char *key, int64_t val, int flags); + int avtext_print_string(AVTextFormatContext *tctx, const char *key, const char *val, int flags); void avtext_print_unit_int(AVTextFormatContext *tctx, const char *key, int value, const char *unit); -- ffmpeg-codebot ___ 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 v5 06/14] fftools/textformat: AVTextWriter change writer_printf signature
From: softworkz Using va_list provides greater flebility Signed-off-by: softworkz --- fftools/textformat/avtextwriters.h | 2 +- fftools/textformat/tw_avio.c | 7 ++- fftools/textformat/tw_buffer.c | 7 ++- fftools/textformat/tw_stdout.c | 8 ++-- 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/fftools/textformat/avtextwriters.h b/fftools/textformat/avtextwriters.h index 34db3f1832..fd6da747eb 100644 --- a/fftools/textformat/avtextwriters.h +++ b/fftools/textformat/avtextwriters.h @@ -41,7 +41,7 @@ typedef struct AVTextWriter { void (*uninit)(AVTextWriterContext *wctx); void (*writer_w8)(AVTextWriterContext *wctx, int b); void (*writer_put_str)(AVTextWriterContext *wctx, const char *str); -void (*writer_printf)(AVTextWriterContext *wctx, const char *fmt, ...); +void (*writer_printf)(AVTextWriterContext *wctx, const char *fmt, va_list vl); } AVTextWriter; typedef struct AVTextWriterContext { diff --git a/fftools/textformat/tw_avio.c b/fftools/textformat/tw_avio.c index 29889598bb..7d52dc4cf5 100644 --- a/fftools/textformat/tw_avio.c +++ b/fftools/textformat/tw_avio.c @@ -57,14 +57,11 @@ static void io_put_str(AVTextWriterContext *wctx, const char *str) avio_write(ctx->avio_context, (const unsigned char *)str, (int)strlen(str)); } -static void io_printf(AVTextWriterContext *wctx, const char *fmt, ...) +static void io_printf(AVTextWriterContext *wctx, const char *fmt, va_list vl) { IOWriterContext *ctx = wctx->priv; -va_list ap; -va_start(ap, fmt); -avio_vprintf(ctx->avio_context, fmt, ap); -va_end(ap); +avio_vprintf(ctx->avio_context, fmt, vl); } diff --git a/fftools/textformat/tw_buffer.c b/fftools/textformat/tw_buffer.c index f8b38414a6..f861722247 100644 --- a/fftools/textformat/tw_buffer.c +++ b/fftools/textformat/tw_buffer.c @@ -56,14 +56,11 @@ static void buffer_put_str(AVTextWriterContext *wctx, const char *str) av_bprintf(ctx->buffer, "%s", str); } -static void buffer_printf(AVTextWriterContext *wctx, const char *fmt, ...) +static void buffer_printf(AVTextWriterContext *wctx, const char *fmt, va_list vl) { BufferWriterContext *ctx = wctx->priv; -va_list vargs; -va_start(vargs, fmt); -av_vbprintf(ctx->buffer, fmt, vargs); -va_end(vargs); +av_vbprintf(ctx->buffer, fmt, vl); } diff --git a/fftools/textformat/tw_stdout.c b/fftools/textformat/tw_stdout.c index 23de6f671f..dace55f38a 100644 --- a/fftools/textformat/tw_stdout.c +++ b/fftools/textformat/tw_stdout.c @@ -53,13 +53,9 @@ static inline void stdout_put_str(AVTextWriterContext *wctx, const char *str) printf("%s", str); } -static inline void stdout_printf(AVTextWriterContext *wctx, const char *fmt, ...) +static inline void stdout_printf(AVTextWriterContext *wctx, const char *fmt, va_list vl) { -va_list ap; - -va_start(ap, fmt); -vprintf(fmt, ap); -va_end(ap); +vprintf(fmt, vl); } -- ffmpeg-codebot ___ 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 v5 07/14] fftools/tf_internal: Use av_default_item_name
From: softworkz Signed-off-by: softworkz --- fftools/textformat/tf_internal.h | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fftools/textformat/tf_internal.h b/fftools/textformat/tf_internal.h index 7b326328cb..e145bc83bb 100644 --- a/fftools/textformat/tf_internal.h +++ b/fftools/textformat/tf_internal.h @@ -29,13 +29,9 @@ #include "avtextformat.h" #define DEFINE_FORMATTER_CLASS(name)\ -static const char *name##_get_name(void *ctx) \ -{ \ -return #name ; \ -} \ static const AVClass name##_class = { \ .class_name = #name,\ -.item_name = name##_get_name, \ +.item_name = av_default_item_name, \ .option = name##_options\ } -- ffmpeg-codebot ___ 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/map: [WIP] Introduction
Hi On Mon, Apr 21, 2025 at 09:55:33PM +0200, Marton Balint wrote: > > > On Sun, 20 Apr 2025, Michael Niedermayer wrote: > > > Note, help is welcome. > > Time i spend on this, i cannot spend on other things > > > > Note2: i intend to push AVMap after the release unless the release > > ends up delayed alot for other reasons, theres no real reason > > to hurry here except that i seem to keep workig on it when > > people ask for some non trivial changes/improvments :) > > so dont ask, send patch yourself if its not a trivial change :)) > > > > Signed-off-by: Michael Niedermayer > > --- > > libavutil/map.h | 86 + > > 1 file changed, 86 insertions(+) > > > > diff --git a/libavutil/map.h b/libavutil/map.h > > index 8211a05ec8d..0d3f7eab9ac 100644 > > --- a/libavutil/map.h > > +++ b/libavutil/map.h > > @@ -31,6 +31,92 @@ > > #include "tree.h" > > > > /** > > + * @file > > + * > > + * AVMap is a simple and fast key -> value map. > > Is this intended to be an AVDictionary replacement? Yes. In how far a "automatic" replacement is possible iam not sure > Because as far as I > remember AVDictionary keeps key insertion order, and we even rely on this > behaviour sometimes, so an ordered-by-compare-function list is likely not > going to work as an instant drop-in replacement... What do you mean by "keeps key insertion order" ? this isnt documented, or is it ? In fact i dont think thats supposed to be guranteed by AVDictionary I think the order coming out of av_map_iterate() will match the order elements where added. Is that what you meant ? > > > + * > > + * -- Creating AVMaps -- > > + * > > + * AVMap *map = av_map_alloc(strcmp, AV_MAP_CMP_CASE_SENSITIVE + > > AV_MAP_CMP_KEY, NULL, NULL); > > + * > > + * This creates a case sensitve string based map using strcmp(). It will > > not allow > > + * multiple entries with the same key. > > + * or > > + * > > + * AVMap *map = av_map_alloc(av_map_strcmp_keyvalue, > > AV_MAP_CMP_CASE_SENSITIVE + AV_MAP_CMP_KEYVALUE, NULL, NULL); > > + * > > + * This is like the previous, but it will allow multiple entries with the > > same key > > + * the difference here is that the compare function compares the value too > > when > > + * the key is equal. > > + * All entries in a map must always be different. So by comparing the value > > + * too we can have multiple entries with the same key > > + * > > + * The remaining 2 pointers in av_map_alloc() are for a function copying > > an element > > + * and one for freeing it. That is only needed for complex objects, not > > for strings. > > + * > > + * > > + * --- Adding entries - > > + * > > + * av_map_add_strings(map, "cat", "neko", 0); // add new entry or do > > nothing > > What "or do nothing" means here? That it will not overwrite a key by > default? This is a different semantics than AVDictionary, where you need to > explicitly set DONT_OVERWRITE flag for such. yes, we can flip the default around if people prefer I really picked this solely because i felt negated flags with "DONT" in their name are suboptimal design > > I think we should use function names and flags similar to what we have in > AVDictionary. Like av_map_set_strings() instead of av_map_add_strings(), or > AV_MAP_DONT_OVERWRITE. So our users won't have to use different mindset for > similar stuff. like i said i dont like the "DONT" flag, i think we should avoid such names in new designs. Maybe AV_MAP_PRESERVE would be an alternative ? av_map_set_strings() implies setting a key to a value. When this in reality is more flexibl, depending on flags and setup > > > + * > > + * av_map_add_strings(map, "cat", "neko", AV_MAP_REPLACE); // add new > > entry or replace existing > > + * > > + * > > + * --- Removing entries - > > + * > > + * Removing entries does by default not rebuild the map. That is, while > > access will always > > + * be O(log n) when n becomes smaller, memory consumption will not > > decrease until > > + * AV_SET_ALLOW_REBUILD is used. Note if you use AV_SET_ALLOW_REBUILD, all > > previously > > + * returned elements become invalid. > > + * > > + * av_map_del(map, "cat", 0); // remove one entry matching "the key" > > + * > > + * av_map_del(map, "cat", AV_SET_ALLOW_REBUILD); // remove one entry > > matching "the key" and rebuild the map to re > > Do you specify a key, or a concatenated key + \0 + value? Or you can specify > both? it depends on the flags (which select the compare function) In fact it can be an arbitrary struct instead of a string, if the compare function during setup compares the specific struct. av_map_del(map, "cat\0katze", AV_MAP_CMP_KEYVALUE); av_map_del(map, "cat", AV_MAP_CMP_KEY); > > In general I believe the public API should not use const char * for keyvalue > types, that would be very fragile. A string constant is not a valid > concatenated keyvalue for example, and the compiler
[FFmpeg-devel] [PATCH] libavformat/mov: FMp4 Fixes duration calculation for individual streams on videos where crash occurs.
Both the audio and video sidx boxes at the end point to a range corresponding to the final mdat atom. Since there is no mfra following the final mdat when recording crashes, current logic sets the flag frag_index.complete flag on the penultimate sidx atom since it points to the end of the file. Results in underreporting duration by ffprobe and libavformat for one of the streams. Signed-off-by: Anthony Bajoua mailto:anthonybaj...@meta.com>> --- libavformat/mov.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 452690090c..36a60cab65 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6150,7 +6150,8 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) } } -c->frag_index.complete = 1; +if (offset == 0) +c->frag_index.complete = 1; } return 0; -- 2.49.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/mpegts: update stream info when PMT ES stream_type changes
On Mon, Apr 21, 2025 at 2:58 PM Michael Niedermayer wrote: > Hi Pavel > > On Sat, Apr 19, 2025 at 10:18:29AM -0600, Pavel Koshevoy wrote: > > I have a couple of .ts captures where video and audio codec changes > > even though the PMT version does not change and the PIDs stay the same. > > --- > > libavformat/mpegts.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > Changes fate output: > is this intended ? if so the output should be updated in the patch > > Looks right to me, I've submitted a new patch with updated ts-demux expected results. Thank you, Pavel. ___ 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] avformat/mpegts: update stream info when PMT ES stream_type changes
I have a couple of .ts captures where video and audio codec changes even though the PMT version does not change and the PIDs stay the same. I've updated fate ts-demux expected results. --- libavformat/mpegts.c| 2 +- tests/ref/fate/ts-demux | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 54594b3a11..8a72d6988a 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -2508,7 +2508,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (!st) goto out; -if (pes && !pes->stream_type) +if (pes && pes->stream_type != stream_type) mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc); add_pid_to_program(prg, pid); diff --git a/tests/ref/fate/ts-demux b/tests/ref/fate/ts-demux index 6a830d0d99..d56cc27937 100644 --- a/tests/ref/fate/ts-demux +++ b/tests/ref/fate/ts-demux @@ -24,6 +24,6 @@ packet|codec_type=video|stream_index=0|pts=3912686363|pts_time=43474.292922|dts= packet|codec_type=audio|stream_index=1|pts=3912644825|pts_time=43473.831389|dts=3912644825|dts_time=43473.831389|duration=2880|duration_time=0.032000|size=906|pos=474888|flags=K__|data_hash=CRC32:0893d398 packet|codec_type=audio|stream_index=2|pts=3912645580|pts_time=43473.839778|dts=3912645580|dts_time=43473.839778|duration=2880|duration_time=0.032000|size=354|pos=491808|flags=K__|data_hash=CRC32:f5963fa6 stream|index=0|codec_name=mpeg2video|profile=4|codec_type=video|codec_tag_string=[2][0][0][0]|codec_tag=0x0002|width=1280|height=720|coded_width=0|coded_height=0|has_b_frames=1|sample_aspect_ratio=1:1|display_aspect_ratio=16:9|pix_fmt=yuv420p|level=4|color_range=tv|color_space=unknown|color_transfer=unknown|color_primaries=unknown|chroma_location=left|field_order=progressive|refs=1|ts_id=32776|ts_packetsize=188|id=0x31|r_frame_rate=6/1001|avg_frame_rate=6/1001|time_base=1/9|start_pts=3912669846|start_time=43474.109400|duration_ts=19519|duration=0.216878|bit_rate=1500|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=15|extradata_size=150|extradata_hash=CRC32:53134fa8|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0| disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0|disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|side_datum/cpb_properties:side_data_type=CPB properties|side_datum/cpb_properties:max_bitrate=1500|side_datum/cpb_properties:min_bitrate=0|side_datum/cpb_properties:avg_bitrate=0|side_datum/cpb_properties:buffer_size=9781248|side_datum/cpb_properties:vbv_delay=-1 -stream|index=1|codec_name=ac3|profile=unknown|codec_type=audio|codec_tag_string=[4][0][0][0]|codec_tag=0x0004|sample_fmt=fltp|sample_rate=48000|channels=6|channel_layout=5.1(side)|bits_per_sample=0|initial_padding=0|dmix_mode=0|ltrt_cmixlev=0.00|ltrt_surmixlev=0.00|loro_cmixlev=0.00|loro_surmixlev=0.00|ts_id=32776|ts_packetsize=188|id=0x34|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/9|start_pts=3912633305|start_time=43473.703389|duration_ts=14400|duration=0.16|bit_rate=384000|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=5|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|disposition:descriptions=0|disposition:metadata=0| disposition:dependent=0|disposition:still_image=0|disposition:multilayer=0|tag:language=eng -stream|index=2|codec_name=ac3|profile=unknown|codec_type=audio|codec_tag_string=[4][0][0][0]|codec_tag=0x0004|sample_fmt=fltp|sample_rate=48000|channels=2|channel_layout=stereo|bits_per_sample=0|initial_padding=0|dmix_mode=0|ltrt_cmixlev=0.00|ltrt_surmixlev=0.00|loro_cmixlev=0.00|loro_surmixlev=0.00|ts_id=32776|ts_packetsize=188|id=0x35|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/9|start_pts=3912634060|start_time=43473.711778|duration_ts=14400|duration=0.16|bit_rate=192000|max_bit_rate=N/A|bits_per_raw_sample=N/A|nb_frames=N/A|nb_read_frames=N/A|nb_read_packets=5|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|disposition:non_diegetic=0|disposition:captions=0|di
[FFmpeg-devel] [PATCH 2/2] postproc/postprocess_template: fix handling of first row of dering_C
Signed-off-by: Michael Niedermayer --- libpostproc/postprocess_altivec_template.c | 5 - libpostproc/postprocess_template.c | 12 +++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libpostproc/postprocess_altivec_template.c b/libpostproc/postprocess_altivec_template.c index 1fc7c65ee47..feddab50356 100644 --- a/libpostproc/postprocess_altivec_template.c +++ b/libpostproc/postprocess_altivec_template.c @@ -530,7 +530,7 @@ static inline void doVertDefFilter_altivec(uint8_t src[], int stride, PPContext STORE(5) } -static inline void dering_altivec(uint8_t src[], int stride, PPContext *c, int leftborder, int rightborder) { +static inline void dering_altivec(uint8_t src[], int stride, PPContext *c, int leftborder, int rightborder, int topborder) { const vector signed int vsint32_8 = vec_splat_s32(8); const vector unsigned int vuint32_4 = vec_splat_u32(4); const vector signed char neg1 = vec_splat_s8(-1); @@ -577,6 +577,9 @@ static inline void dering_altivec(uint8_t src[], int stride, PPContext *c, int l const vector signed int zero = vec_splat_s32(0); vector unsigned char v_dt = vec_splat(vec_ld(0, dt), 0); +if (topborder) +return; + #define LOAD_LINE(i) \ const vector unsigned char perm##i = \ vec_lvsl(i * stride, srcCopy);\ diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c index d2e7a642ffb..0531e39477a 100644 --- a/libpostproc/postprocess_template.c +++ b/libpostproc/postprocess_template.c @@ -831,9 +831,11 @@ static inline void RENAME(doVertDefFilter)(uint8_t src[], int stride, PPContext #endif //TEMPLATE_PP_ALTIVEC #if !TEMPLATE_PP_ALTIVEC -static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c, int leftborder, int rightborder) +static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c, int leftborder, int rightborder, int topborder) { #if TEMPLATE_PP_MMXEXT && HAVE_7REGS +if (topborder) +return; DECLARE_ALIGNED(8, uint64_t, tmp)[3]; __asm__ volatile( "pxor %%mm6, %%mm6 \n\t" @@ -1043,7 +1045,8 @@ DERING_CORE((%0, %1, 8) ,(%%FF_REGd, %1, 4),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5, if (max - min < DERING_THRESHOLD) return; -for(y=0; y<10; y++){ +s[0] = 0; +for(y=topborder; y<10; y++){ int t = 0; if(!leftborder && src[stride*y + 0] > avg) t+= 1; @@ -3209,8 +3212,7 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ } #endif //TEMPLATE_PP_MMX if(mode & DERING){ -//FIXME filter first line -if(y>0) RENAME(dering)(dstBlock - stride - 8, stride, c, x<=8, 0); +RENAME(dering)(dstBlock - stride - 8, stride, c, x<=8, 0, y<=0); } if(mode & TEMP_NOISE_FILTER) @@ -3232,7 +3234,7 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ } if(mode & DERING){ -if(y > 0) RENAME(dering)(dstBlock - dstStride - 8, dstStride, c, 0, 1); +RENAME(dering)(dstBlock - dstStride - 8, dstStride, c, 0, 1, y<=0); } if((mode & TEMP_NOISE_FILTER)){ -- 2.49.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] fate: add stripetest
Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer --- libpostproc/Makefile | 3 +- libpostproc/tests/stripetest.c | 129 tests/fate/libpostproc.mak | 4 + tests/ref/fate/stripetest | 360 + 4 files changed, 495 insertions(+), 1 deletion(-) create mode 100644 libpostproc/tests/stripetest.c create mode 100644 tests/ref/fate/stripetest diff --git a/libpostproc/Makefile b/libpostproc/Makefile index 5afd2d2ad48..3823bec05fd 100644 --- a/libpostproc/Makefile +++ b/libpostproc/Makefile @@ -12,4 +12,5 @@ OBJS = postprocess.o \ # Windows resource file SHLIBOBJS-$(HAVE_GNU_WINDRES) += postprocres.o -TESTPROGS = blocktest +TESTPROGS = blocktest \ +stripetest \ diff --git a/libpostproc/tests/stripetest.c b/libpostproc/tests/stripetest.c new file mode 100644 index 000..7b6359c6daa --- /dev/null +++ b/libpostproc/tests/stripetest.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2025 Michael Niedermayer + * + * 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 "libavutil/frame.h" +#include "libavutil/adler32.h" +#include "libpostproc/postprocess.h" + +typedef const uint8_t *cuint8; + +static void strips(AVFrame *frame, int mul) +{ +for(int y=0; yheight; y++) { +for(int x=0; xwidth; x++) { +if (y&1) { +frame->data[0][x + y*frame->linesize[0]] = x*x + y*mul; +} else { +frame->data[0][x + y*frame->linesize[0]] = (y-x)*(y-x); +} +} +} +for(int y=0; y<(frame->height+1)/2; y++) { +for(int x=0; x<(frame->width+1)/2; x++) { +if (y&1) { +frame->data[1][x + y*frame->linesize[1]] = x + y + mul; +frame->data[2][x + y*frame->linesize[2]] = mul*x - y*x; +} else { +frame->data[1][x + y*frame->linesize[1]] = (x - y)/(mul+1); +frame->data[2][x + y*frame->linesize[2]] = (y + x)/(mul+1); +} +} +} +} + +static int64_t chksum(AVFrame *f) +{ +AVAdler a = 123; + +for(int y=0; yheight; y++) { +a = av_adler32_update(a, &f->data[0][y*f->linesize[0]], f->width); +} +for(int y=0; y<(f->height+1)/2; y++) { +a = av_adler32_update(a, &f->data[1][y*f->linesize[1]], (f->width+1)/2); +a = av_adler32_update(a, &f->data[2][y*f->linesize[2]], (f->width+1)/2); +} + +return a; +} + +static int64_t test(int width, int height, const char *testname, int mul, int flags, int pict_type, int quality) { +AVFrame *in = av_frame_alloc(); +AVFrame *out = av_frame_alloc(); +pp_context *context = pp_get_context(width, height, flags); +pp_mode *mode = pp_get_mode_by_name_and_quality(testname, quality); +int64_t ret; + +if (!in || !out || !context || !mode) { +ret = AVERROR(ENOMEM); +goto end; +} + +in-> width = out->width = width; +in->height = out->height = height; +in->format = out->format = AV_PIX_FMT_YUV420P; + +ret = av_frame_get_buffer(in, 0); +if (ret < 0) +goto end; + +ret = av_frame_get_buffer(out, 0); +if (ret < 0) +goto end; + +strips(in, mul); + +pp_postprocess( (cuint8[]){in->data[0], in->data[1], in->data[2]}, in->linesize, + out->data, out->linesize, + width, height, NULL, 0, + mode, context, pict_type); + +ret = chksum(out); +end: +av_frame_free(&in); +av_frame_free(&out); +pp_free_context(context); +pp_free_mode(mode); + +return ret; +} + +int main(int argc, char **argv) { +const char *teststrings[] = { +"be,lb", +"be,li", +"be,ci", +"be,md", +"be,fd", +"be,l5", +}; + +for (int w=8; w< 352; w=w*3-1) { +for (int h=8; h< 352; h=h*5-7) { +for (int b=0; b<6; b++) { +for (int m=0; m<17; m = 2*m+1) { +int64_t ret = test(352, 288, teststrings[b], m, PP_FORMAT_420, 0, 11); +printf("striptest %dx%d T:%s m:%d result %"PRIX64"\n", w, h, teststrings[b], m, ret); +} +} +} +} + +return 0; +} diff --git
[FFmpeg-devel] [PATCH 2/2] avcodec/ffv1enc: Eliminate fabs()
Fixes: warning: using floating point absolute value function 'fabs' when argument is of integer type No change in output Changing variables to float worsens compression significantly Found-by: ePirat Signed-off-by: Michael Niedermayer --- libavcodec/ffv1enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 75e40771b6f..6ab648fd805 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -1441,7 +1441,7 @@ static void encode_float32_remap(FFV1Context *f, FFV1SliceContext *sc, cost = FFMAX((delta + mul/2) / mul, 1); float score = 1; if (mul > 1) { -score *= (fabs(delta - cost*mul)+1); +score *= (FFABS(delta - cost*mul)+1); if (mul_count > 1) score *= score; } -- 2.49.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [RFC] STF 2025
On Fri, 15 Nov 2024, 18:12 Thilo Borgmann via ffmpeg-devel, < ffmpeg-devel@ffmpeg.org> wrote: > Hi, > > Am 17.05.24 um 15:49 schrieb Michael Niedermayer: > > Hi all > > > > Before this is forgotten again, better start some dicsussion too early > than too late > > > > I propose that if we have the oppertunity again next year to receive a > grant > > from STF. That we use it to fund: > > > > [...] > the trac page for the STF 2025 application is available: > > https://trac.ffmpeg.org/wiki/SponsoringPrograms/STF/2025 > > If you want to propose a project, add it to the end of the page. > Include an overview, a developer to work on it (most likely yourself), a > duration and the milestones together with corresponding deliverables. There > is a template, look at the 2024 page if you're unsure. > > We should finalize the discussion about proposed projects and create the > application before end of the year, so that STF can start looking at our > proposal first thing in 2025. > > Thanks, > Thilo > This page is empty > ___ 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] avformat/dump: Stream start offsets: change precision and label
From: softworkz - Change precision to 6 digits to align with other printed times - Change label to just "Start" - Add 's' unit to format 'start' value for consistency Signed-off-by: softworkz --- avformat/dump: Change precision of stream start offsets Changing this to 6 digits to align with other printed times Signed-off-by: softworkz softwo...@hotmail.com Versions V2 Following comments from Gyan and Marton: * Change precision to 6 digits to align with other printed times * Change label to just "Start" * Add 's' unit to format 'start' value for consistency Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-72%2Fsoftworkz%2Fsubmit_start_offsets-v2 Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-72/softworkz/submit_start_offsets-v2 Pull-Request: https://github.com/ffstaging/FFmpeg/pull/72 Range-diff vs v1: 1: 5f3052624c ! 1: 6ae8a0da2b avformat/dump: Change precision of stream start offsets @@ Metadata Author: softworkz ## Commit message ## -avformat/dump: Change precision of stream start offsets +avformat/dump: Stream start offsets: change precision and label -Changing this to 6 digits to align with other -printed times +- Change precision to 6 digits to align with other printed times +- Change label to just "Start" +- Add 's' unit to format 'start' value for consistency Signed-off-by: softworkz @@ libavformat/dump.c: FF_ENABLE_DEPRECATION_WARNINGS if (st->start_time != AV_NOPTS_VALUE && st->start_time != 0 && st->time_base.den && st->time_base.num) { const double stream_start = av_q2d(st->time_base) * st->start_time; -av_log(NULL, AV_LOG_INFO, ", Start-Time %.3fs", stream_start); -+av_log(NULL, AV_LOG_INFO, ", Start-Time %.6fs", stream_start); ++av_log(NULL, AV_LOG_INFO, ", Start %.6fs", stream_start); } dump_disposition(st->disposition, log_level); +@@ libavformat/dump.c: void av_dump_format(AVFormatContext *ic, int index, + av_log(NULL, AV_LOG_INFO, ", start: "); + secs = llabs(ic->start_time / AV_TIME_BASE); + us = llabs(ic->start_time % AV_TIME_BASE); +-av_log(NULL, AV_LOG_INFO, "%s%d.%06d", ++av_log(NULL, AV_LOG_INFO, "%s%d.%06ds", +ic->start_time >= 0 ? "" : "-", +secs, +(int) av_rescale(us, 100, AV_TIME_BASE)); libavformat/dump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/dump.c b/libavformat/dump.c index 8c7db7b275..dacedd5ef1 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -680,7 +680,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (st->start_time != AV_NOPTS_VALUE && st->start_time != 0 && st->time_base.den && st->time_base.num) { const double stream_start = av_q2d(st->time_base) * st->start_time; -av_log(NULL, AV_LOG_INFO, ", Start-Time %.3fs", stream_start); +av_log(NULL, AV_LOG_INFO, ", Start %.6fs", stream_start); } dump_disposition(st->disposition, log_level); @@ -883,7 +883,7 @@ void av_dump_format(AVFormatContext *ic, int index, av_log(NULL, AV_LOG_INFO, ", start: "); secs = llabs(ic->start_time / AV_TIME_BASE); us = llabs(ic->start_time % AV_TIME_BASE); -av_log(NULL, AV_LOG_INFO, "%s%d.%06d", +av_log(NULL, AV_LOG_INFO, "%s%d.%06ds", ic->start_time >= 0 ? "" : "-", secs, (int) av_rescale(us, 100, AV_TIME_BASE)); base-commit: 853e66a0726b0a9d6d6269a22f6f9b5be7763738 -- ffmpeg-codebot ___ 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 5/6] lavc/apv: AVX2 transquant for x86-64
On 4/21/2025 4:50 PM, Mark Thompson wrote: On 21/04/2025 17:53, James Almer wrote: On 4/21/2025 12:24 PM, Mark Thompson wrote: Typical checkasm result on Alder Lake: decode_transquant_8_c: 461.1 ( 1.00x) decode_transquant_8_avx2: 97.5 ( 4.73x) decode_transquant_10_c: 483.9 ( 1.00x) decode_transquant_10_avx2: 91.7 ( 5.28x) --- libavcodec/apv_dsp.c | 4 + libavcodec/apv_dsp.h | 2 + libavcodec/x86/Makefile | 2 + libavcodec/x86/apv_dsp.asm | 279 ++ libavcodec/x86/apv_dsp_init.c | 40 + tests/checkasm/Makefile | 1 + tests/checkasm/apv_dsp.c | 109 + tests/checkasm/checkasm.c | 3 + tests/checkasm/checkasm.h | 1 + tests/fate/checkasm.mak | 1 + 10 files changed, 442 insertions(+) create mode 100644 libavcodec/x86/apv_dsp.asm create mode 100644 libavcodec/x86/apv_dsp_init.c create mode 100644 tests/checkasm/apv_dsp.c ... diff --git a/libavcodec/x86/apv_dsp.asm b/libavcodec/x86/apv_dsp.asm new file mode 100644 index 00..6b045e989a --- /dev/null +++ b/libavcodec/x86/apv_dsp.asm @@ -0,0 +1,279 @@ +; +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +; Full matrix for row transform. +const tmatrix_row + dw 64, 89, 84, 75, 64, 50, 35, 18 + dw 64, -18, -84, 50, 64, -75, -35, 89 + dw 64, 75, 35, -18, -64, -89, -84, -50 + dw 64, -50, -35, 89, -64, -18, 84, -75 + dw 64, 50, -35, -89, -64, 18, 84, 75 + dw 64, -75, 35, 18, -64, 89, -84, 50 + dw 64, 18, -84, -50, 64, 75, -35, -89 + dw 64, -89, 84, -75, 64, -50, 35, -18 + +; Constant pairs for broadcast in column transform. +const tmatrix_col_even + dw 64, 64, 64, -64 + dw 84, 35, 35, -84 +const tmatrix_col_odd + dw 89, 75, 50, 18 + dw 75, -18, -89, -50 + dw 50, -89, 18, 75 + dw 18, -50, 75, -89 + +; Memory targets for vpbroadcastd (register version requires AVX512). +cextern pd_1 +const sixtyfour + dd 64 + +SECTION .text + +; void ff_apv_decode_transquant_avx2(void *output, +; ptrdiff_t pitch, +; const int16_t *input, +; const int16_t *qmatrix, +; int bit_depth, +; int qp_shift); + +INIT_YMM avx2 + +cglobal apv_decode_transquant, 6, 7, 16, output, pitch, input, qmatrix, bit_depth, qp_shift, tmp + + ; Load input and dequantise + + vpbroadcastd m10, [pd_1] + lea tmpq, [bit_depthq - 2] lea tmpd, [bit_depthd - 2] The upper 32 bits of the register may have garbage. Ah, I was assuming that lea had to be pointer-sized, but apparently it doesn't. Changed. + movd xm8, qp_shiftd If you declare the function as 5, 7, 16, then qp_shift will not be loaded into a gpr on ABIs where it's on stack (Win64, and x86_32 if it was supported), and then you can do movd xm8, qp_shiftm Which will load it directly to the simd register from memory, saving one instruction in the prologue. This seems like highly dubious magic since it is lying about the number of arguments. You're not lying. That value is to tell x86inc to load x arguments onto gprs in the prologue if they are in stack. If they are not (As is the case with the first six arguments on Unix64, first four on Win64), qp_shiftm will be equivalent of qp_shiftd, and if they are, it will be the stack memory address. So with my suggestion, on Win64 you get movd xmm8, [rsp]; qp_shiftm points to memory instead of mov r11, [rsp] ; prologue loads argument into what will be qp_shiftd movd xmm8, r11d ; qp_shiftd is an alias of r11d It's ricing, yes, but it's free. I've changed it, but I want to check a Windows machine as well. + movd xm9, tmpd + vpslld m10, m10, xm9 + vpsrld m10, m10, 1 + +
Re: [FFmpeg-devel] [PATCH] postproc/postprocess_template: Fix reading uninitialized pixels in dering_C()
Hi Kieran On Tue, Apr 22, 2025 at 01:23:19AM -0100, Kieran Kunhya via ffmpeg-devel wrote: > On Tue, 22 Apr 2025, 00:44 Michael Niedermayer, > wrote: > > > Sponsored-by: Sovereign Tech Fund > > Signed-off-by: Michael Niedermayer > > > > I thought we decided postproc work in STF wasn't going to happen? I thought i am going to do the work for the 2 remaining milestones and I will donate the money for these 2 milestones to FFmpeg. I thought everyone was happy with that. If the FFmpeg community prefers, we can explore the posibility to change the contracts to remove the postproc work. This would mean that i will do the work exactly the same way and FFmpeg would then get nothing. Also iam not sure how STF would see this if we told them that we will do the work but want it taken out of the contract so we receive no money for it. > > Note that the STF wiki doesn't mention anything about bugfixes to > libpostproc. The bugfix was required for blocktest to work. And teh wiki lists "Have functioning build and selftest systems" But ive removed the "Sponsored-by: Sovereign Tech Fund" from the commit message. thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB He who knows, does not speak. He who speaks, does not know. -- Lao Tsu 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 2/2] lavfi/f_sendcmd: clear Command on alloc failure
On 30 Jan 2025, at 1:25, Marvin Scholz wrote: > If the command array failed to allocate, the current parsed > Command has to be cleared, else memory allocated for it > would be leaked. > > Fix CID 1638635 > --- I intend to push the set in a few days, if no one has comments or objections. > libavfilter/f_sendcmd.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c > index 8a0c368108..64f284f4f1 100644 > --- a/libavfilter/f_sendcmd.c > +++ b/libavfilter/f_sendcmd.c > @@ -263,6 +263,7 @@ static int parse_commands(Command **cmds, int *nb_cmds, > int interval_count, > if (!*cmds) { > av_log(log_ctx, AV_LOG_ERROR, > "Could not (re)allocate command array\n"); > +clear_command(&cmd); > return AVERROR(ENOMEM); > } > } > -- > 2.39.5 (Apple Git-154) ___ 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".