Le 08/06/2016 15:37, Michael Niedermayer a écrit : > On Wed, Jun 08, 2016 at 12:03:10AM +0200, miniupnp wrote: >>>> On 6/1/16, miniupnp <miniu...@free.fr> wrote: >>>>> Hello, >>>>> >>>>> I'm using the .AU audio file format and noticed that FFmpeg always put 8 >>>>> zero's in the annotation field. >>>>> SOX does use the annotation field to put metadata >>>>> (Title/Author/Album/Genre/Track) >>>>> >>>>> I don't think there is any precise specification for this AU annotation >>>>> field as long as it is a null terminated character string, but what SOX >>>>> does looks good. >>>>> >>>>> Attached are my patches to write metadata to AU files. >>>> look fine to me. >>> applied >>> thx >> And now is the patch to READ theses metadata in AU files. >> >> Regards, >> >> Thomas Bernard >> >> >> au.c | 69 >> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- >> 1 file changed, 67 insertions(+), 2 deletions(-) >> 501f81b2747e0758344d189918af2863d76c774d >> 0001-Read-MetaData-from-AU-Sun-audio-file-header.patch >> From 10ca03e6a944b6a5385a92d72f633e98a0c1b57f Mon Sep 17 00:00:00 2001 >> From: Thomas Bernard <miniu...@free.fr> >> Date: Tue, 7 Jun 2016 00:25:38 +0200 >> Subject: [PATCH] Read MetaData from AU Sun audio file header >> >> recognize title= album= artist= genre= track= >> --- >> libavformat/au.c | 69 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++-- >> 1 file changed, 67 insertions(+), 2 deletions(-) >> >> diff --git a/libavformat/au.c b/libavformat/au.c >> index 4a0400b..dba2a83 100644 >> --- a/libavformat/au.c >> +++ b/libavformat/au.c >> @@ -66,6 +66,71 @@ static int au_probe(AVProbeData *p) >> return 0; >> } >> >> +static int au_read_annotation(AVFormatContext *s, int size) >> +{ >> + static const char * keys[] = { >> + "title", >> + "artist", >> + "album", >> + "track", >> + "genre", >> + NULL }; >> + AVIOContext *pb = s->pb; >> + enum { PARSE_KEY, PARSE_VALUE, PARSE_FINISHED } state = PARSE_KEY; >> + char c; >> + AVBPrint bprint; >> + char * key = NULL; >> + char * value = NULL; >> + int i; >> + >> + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); >> + >> + while (size-- > 0) { >> + c = avio_r8(pb); >> + switch(state) { >> + case PARSE_KEY: >> + if (c == '\0') { >> + state = PARSE_FINISHED; >> + } else if (c == '=') { >> + av_bprint_finalize(&bprint, &key); >> + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); >> + state = PARSE_VALUE; >> + } else { >> + av_bprint_chars(&bprint, c, 1); >> + } >> + break; >> + case PARSE_VALUE: >> + if (c == '\0' || c == '\n') { >> + if (av_bprint_finalize(&bprint, &value) != 0) { >> + av_log(s, AV_LOG_ERROR, "Memory error while parsing AU >> metadata.\n"); >> + } else { >> + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); >> + for (i = 0; keys[i] != NULL && key != NULL; i++) { >> + if (av_strcasecmp(keys[i], key) == 0) { >> + av_dict_set(&(s->metadata), keys[i], value, >> AV_DICT_DONT_STRDUP_VAL); >> + av_freep(&key); >> + value = NULL; >> + } >> + } >> + } >> + if (key != NULL) av_freep(&key); >> + if (value != NULL) av_freep(&value); > redundant if()
I was not sure of what av_freep(&key) does when key==NULL. here is the patch, plus a potential memory leak fix.
From 10ca03e6a944b6a5385a92d72f633e98a0c1b57f Mon Sep 17 00:00:00 2001 From: Thomas Bernard <miniu...@free.fr> Date: Tue, 7 Jun 2016 00:25:38 +0200 Subject: [PATCH 1/2] Read MetaData from AU Sun audio file header recognize title= album= artist= genre= track= --- libavformat/au.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/libavformat/au.c b/libavformat/au.c index 4a0400b..dba2a83 100644 --- a/libavformat/au.c +++ b/libavformat/au.c @@ -66,6 +66,71 @@ static int au_probe(AVProbeData *p) return 0; } +static int au_read_annotation(AVFormatContext *s, int size) +{ + static const char * keys[] = { + "title", + "artist", + "album", + "track", + "genre", + NULL }; + AVIOContext *pb = s->pb; + enum { PARSE_KEY, PARSE_VALUE, PARSE_FINISHED } state = PARSE_KEY; + char c; + AVBPrint bprint; + char * key = NULL; + char * value = NULL; + int i; + + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + + while (size-- > 0) { + c = avio_r8(pb); + switch(state) { + case PARSE_KEY: + if (c == '\0') { + state = PARSE_FINISHED; + } else if (c == '=') { + av_bprint_finalize(&bprint, &key); + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + state = PARSE_VALUE; + } else { + av_bprint_chars(&bprint, c, 1); + } + break; + case PARSE_VALUE: + if (c == '\0' || c == '\n') { + if (av_bprint_finalize(&bprint, &value) != 0) { + av_log(s, AV_LOG_ERROR, "Memory error while parsing AU metadata.\n"); + } else { + av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); + for (i = 0; keys[i] != NULL && key != NULL; i++) { + if (av_strcasecmp(keys[i], key) == 0) { + av_dict_set(&(s->metadata), keys[i], value, AV_DICT_DONT_STRDUP_VAL); + av_freep(&key); + value = NULL; + } + } + } + if (key != NULL) av_freep(&key); + if (value != NULL) av_freep(&value); + state = (c == '\0') ? PARSE_FINISHED : PARSE_KEY; + } else { + av_bprint_chars(&bprint, c, 1); + } + break; + case PARSE_FINISHED: + break; + default: + /* should never happen */ + av_assert0(0); + } + } + av_bprint_finalize(&bprint, NULL); + return 0; +} + #define BLOCK_SIZE 1024 static int au_read_header(AVFormatContext *s) @@ -94,8 +159,8 @@ static int au_read_header(AVFormatContext *s) channels = avio_rb32(pb); if (size > 24) { - /* skip unused data */ - avio_skip(pb, size - 24); + /* parse annotation field to get metadata */ + au_read_annotation(s, size - 24); } codec = ff_codec_get_id(codec_au_tags, id); -- 1.7.10.4
From d375766a75877583ad46d92ae23683716b7bc56d Mon Sep 17 00:00:00 2001 From: Thomas Bernard <miniu...@free.fr> Date: Wed, 8 Jun 2016 16:12:07 +0200 Subject: [PATCH 2/2] AU metadata : remove redundant if() and fix potential mem leak --- libavformat/au.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/au.c b/libavformat/au.c index dba2a83..f70f827 100644 --- a/libavformat/au.c +++ b/libavformat/au.c @@ -113,8 +113,8 @@ static int au_read_annotation(AVFormatContext *s, int size) } } } - if (key != NULL) av_freep(&key); - if (value != NULL) av_freep(&value); + av_freep(&key); + av_freep(&value); state = (c == '\0') ? PARSE_FINISHED : PARSE_KEY; } else { av_bprint_chars(&bprint, c, 1); @@ -128,6 +128,7 @@ static int au_read_annotation(AVFormatContext *s, int size) } } av_bprint_finalize(&bprint, NULL); + av_freep(&key); return 0; } -- 1.7.10.4
signature.asc
Description: OpenPGP digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel