[FFmpeg-devel] [PATCH] Add writing of vorbis comments to flac files

James Darnley james.darnley
Sat Mar 13 18:24:30 CET 2010


On 13 March 2010 02:28, James Darnley <james.darnley at gmail.com> wrote:
> On 13 March 2010 01:00, Aurelien Jacobs <aurel at gnuage.org> wrote:
>> On Fri, Mar 12, 2010 at 02:19:54PM +0100, James Darnley wrote:
>>> On 12 March 2010 13:44, Aurelien Jacobs <aurel at gnuage.org> wrote:
>>> > You are not allowed to access to the content of AVMetadata *m by
>>> > yourself. You must not use anything else than what's described in
>>> > Public Metadata API (avformat.h).
>>> > Basically you should use av_metadata_get() to iterate over all the
>>> > elements.
>>> > Something like this should do the trick:
>>> >
>>> > ?AVMetadataTag *t = NULL;
>>> > ?while ((t = av_metadata_get(m, "", t, AV_METADATA_IGNORE_SUFFIX))) {
>>> > ? ? /* do wathever you want with 't' */
>>> > ?}
>>> >
>>> > Aurel
>>>
>>> Ew. ?Why isn't there a cleaner method for getting the next tag?
>>
>> What kind of cleaner method would you expect ?
>> Are you simply thinking about something like this :
>>
>> ?#define av_metadata_next(m, t) \
>> ? ? ? ? ?av_metadata_get(m, "", t, AV_METADATA_IGNORE_SUFFIX)
>>
>> I thougt about something like this while we were designing the API,
>> but it would only hide the real API... I'm not sure that it's a good
>> idea.
>>
>> Aurel
>
> Yeah, something like that. ?This is used in 13 other places. ?Another
> thing I discovered when making changes is that if I can't use m->count
> I need to count the number of tags over the while loop. ?Sounds
> redundant to me. ?Is making this value public (somehow) such a bad
> idea?
>

Changed patches attached.  Text below is the changes of the first
patch, 0001-*.patch

diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index 555fba2..ff90731 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -66,10 +66,10 @@ static int flac_write_block_comment(ByteIOContext
*pb, AVMetadata *m,
                                     int last_block, int bitexact)
 {
     const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
-    unsigned int len;
+    unsigned int len, count;
     uint8_t *p, *p0;

-    len = ff_vorbiscomment_length(m, vendor);
+    len = ff_vorbiscomment_length(m, vendor, &count);
     p0 = av_malloc(len+4);
     if (!p0)
         return AVERROR(ENOMEM);
@@ -77,7 +77,7 @@ static int flac_write_block_comment(ByteIOContext
*pb, AVMetadata *m,

     bytestream_put_byte(&p, last_block ? 0x84 : 0x04);
     bytestream_put_be24(&p, len);
-    ff_vorbiscomment_write(&p, m, vendor);
+    ff_vorbiscomment_write(&p, m, vendor, count);

     put_buffer(pb, p0, len+4);
     av_freep(&p0);
diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c
index 1ff92f9..d23c66d 100644
--- a/libavformat/vorbiscomment.c
+++ b/libavformat/vorbiscomment.c
@@ -35,34 +35,37 @@ const AVMetadataConv ff_vorbiscomment_metadata_conv[] = {
     { 0 }
 };

-int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string)
+int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string,
+                            unsigned *count)
 {
     int len = 8;
     len += strlen(vendor_string);
+    *count = 0;
     if (m) {
-        int i;
-        len += m->count * 4;
-        for (i = 0; i < m->count; i++)
-            len += strlen(m->elems[i].key) + 1 + strlen(m->elems[i].value);
+        AVMetadataTag *tag = NULL;
+        while ( (tag = av_metadata_get(m, "", tag,
AV_METADATA_IGNORE_SUFFIX) ) ) {
+            len += 4 +strlen(tag->key) + 1 + strlen(tag->value);
+            (*count)++;
+        }
     }
     return len;
 }

 int ff_vorbiscomment_write(uint8_t **p, AVMetadata *m,
-                           const char *vendor_string)
+                           const char *vendor_string, const unsigned count)
 {
     bytestream_put_le32(p, strlen(vendor_string));
     bytestream_put_buffer(p, vendor_string, strlen(vendor_string));
     if (m) {
-        int i;
-        bytestream_put_le32(p, m->count);
-        for (i = 0; i < m->count; i++) {
-            unsigned int len1 = strlen(m->elems[i].key);
-            unsigned int len2 = strlen(m->elems[i].value);
+        AVMetadataTag *tag = NULL;
+        bytestream_put_le32(p, count);
+        while ( (tag = av_metadata_get(m, "", tag,
AV_METADATA_IGNORE_SUFFIX) ) ) {
+            unsigned int len1 = strlen(tag->key);
+            unsigned int len2 = strlen(tag->value);
             bytestream_put_le32(p, len1+1+len2);
-            bytestream_put_buffer(p, m->elems[i].key, len1);
+            bytestream_put_buffer(p, tag->key, len1);
             bytestream_put_byte(p, '=');
-            bytestream_put_buffer(p, m->elems[i].value, len2);
+            bytestream_put_buffer(p, tag->value, len2);
         }
     } else
         bytestream_put_le32(p, 0);
diff --git a/libavformat/vorbiscomment.h b/libavformat/vorbiscomment.h
index af900f1..714f1f2 100644
--- a/libavformat/vorbiscomment.h
+++ b/libavformat/vorbiscomment.h
@@ -32,9 +32,11 @@
  * @param m The metadata structure to be parsed. For no metadata, set to NULL.
  * @param vendor_string The vendor string to be added into the VorbisComment.
  * For no string, set to an empty string.
+ * @param count Pointer to store the number of tags in m because
m->count is "not allowed"
  * @return The length in bytes.
  */
-int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string);
+int ff_vorbiscomment_length(AVMetadata *m, const char *vendor_string,
+                            unsigned *count);

 /**
  * Writes a VorbisComment into a buffer. The buffer, p, must have enough
@@ -45,9 +47,10 @@ int ff_vorbiscomment_length(AVMetadata *m, const
char *vendor_string);
  * @param p The buffer in which to write.
  * @param m The metadata struct to write.
  * @param vendor_string The vendor string to write.
+ * @param count The number of tags in m because m->count is "not allowed"
  */
 int ff_vorbiscomment_write(uint8_t **p, AVMetadata *m,
-                           const char *vendor_string);
+                           const char *vendor_string, const unsigned count);

 extern const AVMetadataConv ff_vorbiscomment_metadata_conv[];
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-VorbisComment-writing-to-flac-files.patch
Type: application/octet-stream
Size: 14650 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100313/15ea76cc/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Add-VorbisComment-writing-to-ogg-flac-and-ogg-speex.patch
Type: application/octet-stream
Size: 5284 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100313/15ea76cc/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Changelog-entry-and-micro-version-bump-for-VorbisCom.patch
Type: application/octet-stream
Size: 1122 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100313/15ea76cc/attachment-0002.obj>



More information about the ffmpeg-devel mailing list