[FFmpeg-devel] AVWriter again (was: v2 1/2] avformat/url: check double dot is not to parent directory)
Nicolas George
george at nsup.org
Tue Jul 28 00:34:13 EEST 2020
Steven Liu (12020-07-27):
> Because language barries. maybe I cannot deep understand, maybe need
> more code examples.
> But look interesting, maybe more easy for use.
All right, here is a practical albeit fictional example.
Let us say we want av_metadata_to_user_string() that turns an
AVDictionary into a string for users, and show_metadata_in_dialog() to
print the metadata of all the streams in a file in a GUI dialog.
av_metadata_to_user_string() using naïve av_malloc():
char *av_metadata_to_user_string(AVDictionary *meta)
{
size_t size = 1, len;
AVDictionaryEntry *entry;
char *str, *cur;
entry = NULL;
while ((entry = av_dict_get(meta, "", entry, AV_DICT_IGNORE_SUFFIX))) {
len = strlen(entry->key);
if (len > SIZE_MAX - size)
return NULL;
size += len;
len = strlen(entry->value);
if (len > SIZE_MAX - size)
return NULL;
size += len;
if (3 > SIZE_MAX - size)
return NULL;
size += 3;
}
str = av_malloc(size);
if (!str)
return AVERROR(ENOMEM);
cur = str;
entry = NULL;
while ((entry = av_dict_get(meta, "", entry, AV_DICT_IGNORE_SUFFIX))) {
cur += av_strlcatf(cur, "%s: %s\n", entry->key, entry->value, str + size - cur);
}
av_assert0(cur == str + size - 1);
return str;
}
av_metadata_to_user_string() using AVBPrint:
void av_metadata_to_user_string(AVWriter wr, AVDictionary *meta)
{
AVDictionaryEntry *entry;
while ((entry = av_dict_get(meta, "", entry, AV_DICT_IGNORE_SUFFIX))) {
av_writer_printf(wr, entry->key, entry->value, str + size - cur);
}
}
show_metadata_in_dialog(), without AVBPrint, but relying on Gtk+'s
features (I want to show AVWriter is good, it would be dishonest not to
use all the tools to make the other side look good):
void show_metadata_in_dialog(AVFormatContext *ctx, GtkLabel *label)
{
GString *str = g_string_new();
unsigned i;
for (i = 0; i < ctx->nb_streams; i++) {
char *meta = av_metadata_to_user_string(ctx->streams->metadata);
if (!meta)
fatal_error("out of memory");
g_string_printf("Stream #%d:\n%s\n", i, meta);
av_free(meta);
}
gtk_label_set_text(label, str->str);
g_string_free(str);
}
show_metadata_in_dialog() using AVBPrint:
void show_metadata_in_dialog(AVFormatContext *ctx, GtkLabel *label)
{
AVWriter = av_dynbuf_writer();
unsigned i;
for (i = 0; i < ctx->nb_streams; i++) {
av_writer_printf(wr, "Stream #%d:\n", i);
av_metadata_to_user_string(wr, ctx->streams->metadata);
g_string_print(wr, "\n");
}
if (av_dynbuf_writer_get_error(wr))
fatal_error("out of memory");
gtk_label_set_text(label, av_dynbuf_writer_get_data(wr, NULL));
av_dynbuf_writer_reset(wr);
}
Now, imagine if a lot of FFmpeg functions did use the same AVWriter, and
therefore worked well together.
Also, not visible in the code: unless the metadata is big, the AVWriter
version will keep all in the stack.
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20200727/de3adba9/attachment.sig>
More information about the ffmpeg-devel
mailing list