[FFmpeg-devel] [PATCH 3] add tag/comment support to the raw flac demuxer

Jim Radford radford
Thu Dec 11 00:10:06 CET 2008


On Wed, Dec 10, 2008 at 10:08:15AM +0100, Reimar D?ffinger wrote:
> On Tue, Dec 09, 2008 at 01:38:33PM -0800, Jim Radford wrote:
> > On Thu, 4 Dec 2008 at 21:44:51, Reimar D?ffinger wrote:
> > > On Mon, Dec 01, 2008 at 02:18:02PM -0800, Jim Radford wrote:
> > > > This patch adds support for parsing vorbis comments in plain flac
> > > > streams.  Only metadata packets are parsed leaving the frame data to
> > > > be parsed in raw 1024 byte chunks like before.

> > > > +        init_get_bits(&gb, header, ret*8);
> > > > +        flac->metadata_done = get_bits(&gb, 1);
> > > > +        type = get_bits(&gb, 7);
> > > > +        length = get_bits(&gb, 24);

> > > Seems very much like overkill to use get_bits here. Actually
> > > get_be32 to me seems much more appropriate than get_buffer to get
> > > the header anyway.

> > I thought so too, but given that I need to copy the data back into the
> > stream where it needs to be in its original endian, so the code
> > doesn't get any simpler.

> Nonsense, AV_WB32 is simpler and possibly a lot faster than memcpy
> (depends on whether the compiler inlines his own memcpy variant).

Ahh, I hadn't seen AV_WB32() and friends.  How's this version?

-Jim
-------------- next part --------------
Index: libavformat/raw.c
===================================================================
--- libavformat/raw.c	(revision 16041)
+++ libavformat/raw.c	(working copy)
@@ -27,7 +27,57 @@
 #include "avformat.h"
 #include "raw.h"
 
+#define RAW_PACKET_SIZE 1024
+
 /* simple formats */
+
+#ifdef CONFIG_FLAC_DEMUXER
+#include "oggdec.h" // vorbis_comment()
+
+struct flac
+{
+    int flac_done, metadata_done;
+};
+
+static int flac_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    struct flac *flac = s->priv_data;
+
+    if (!flac->flac_done) {
+        if (av_get_packet(s->pb, pkt, 4) <= 0)
+            return AVERROR(EIO);
+        flac->flac_done = 1;
+    } else if (!flac->metadata_done) {
+        int32_t pos = url_ftell(s->pb);
+        uint32_t header = get_be32(s->pb);
+        int type, length, ret;
+
+        flac->metadata_done = (header & 0x80000000);
+        type                = (header & 0x7f000000) >> 24;
+        length              = (header & 0x00ffffff);
+
+        if ((ret = av_new_packet(pkt, sizeof(header) + length)) < 0)
+            return ret;
+
+        AV_WB32(pkt->data, header);
+        if (get_buffer(s->pb, pkt->data + sizeof(header), length) < length)
+            return AVERROR(EIO);
+
+        pkt->pos = pos;
+        pkt->size = length + sizeof(header);
+
+        if (type == 4)
+            vorbis_comment(s, pkt->data+sizeof(header), length);
+    } else {
+        if (av_get_packet(s->pb, pkt, RAW_PACKET_SIZE) <= 0)
+            return AVERROR(EIO);
+    }
+
+    pkt->stream_index = 0;
+    return pkt->size;
+}
+#endif
+
 #ifdef CONFIG_FLAC_MUXER
 static int flac_write_header(struct AVFormatContext *s)
 {
@@ -134,8 +184,6 @@
     return 0;
 }
 
-#define RAW_PACKET_SIZE 1024
-
 static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret, size, bps;
@@ -773,10 +821,10 @@
 AVInputFormat flac_demuxer = {
     "flac",
     NULL_IF_CONFIG_SMALL("raw FLAC"),
-    0,
+    sizeof(struct flac),
     flac_probe,
     audio_read_header,
-    raw_read_partial_packet,
+    flac_read_packet,
     .flags= AVFMT_GENERIC_INDEX,
     .extensions = "flac",
     .value = CODEC_ID_FLAC,



More information about the ffmpeg-devel mailing list