[Ffmpeg-devel] [PATCH] flv muxer metadata

Allan Hsu allan
Fri Dec 8 01:22:25 CET 2006


>From the secret journal of Baptiste Coudurier:
[...]
> > +static void put_amf_bool(ByteIOContext *pb, int b) {
> > +    put_byte(pb, AMF_DATA_TYPE_BOOL);
> > +    put_byte(pb, (b ? AMF_BOOL_TRUE : AMF_BOOL_FALSE));
> > +}
> > +
> 
> IMHO !!b is simpler, no need to define a BOOL enum for that.

Changed.

> > [...]
> > +
> > +            switch(enc->codec_id) {
> > +                case    CODEC_ID_PCM_S8:
> > +                case CODEC_ID_PCM_S16BE:
> > +                    audiocodecid = FLV_CODECID_PCM_BE >> FLV_AUDIO_CODECID_OFFSET; break;
> > +                case CODEC_ID_ADPCM_SWF:
> > +                    audiocodecid = FLV_CODECID_ADPCM  >> FLV_AUDIO_CODECID_OFFSET; break;
> > +                case       CODEC_ID_MP3:
> > +                    audiocodecid = FLV_CODECID_MP3    >> FLV_AUDIO_CODECID_OFFSET;
> > +                    samplesize = 16;
> > +                    break;
> > +                case CODEC_ID_PCM_S16LE:
> > +                    audiocodecid = FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET; break;
> > +                default:
> > +                    //unsupported format, but the get_audio_flags check below will catch it.
> > +                    break;
> > +            }
> 
> lookup table for CODEC_ID -> FLV_CODEC_ID.

I'm not sure exactly what you mean by this. My interpretation of this
suggestion doesn't make much sense. Please explain?

> Samplesize is not set to 8 for CODEC_ID_PCM_S8 ?

Whoops. I had assumed that sample size was being set in the encoder, but
that doesn't look like the case. I've updated the patch accordingly. I'm
not entirely sure about the samplesize settings I used for CODEC_ID_ADPCM_SWF;
the only example I could find was zeldaHQ.flv from samples.myplayerhq.hu
and the audio tags in that file are marked as 16 bits/sample.

[...]
> >          put_amf_string(pb, "framerate");
> >          put_amf_double(pb, framerate);
> > +
> > +        put_amf_string(pb, "videocodecid");
> > +        put_amf_double(pb, FLV_CODECID_H263);
> >      }
> 
> Even for vp6 ?

I forgot about the "-vcodec copy" case. Fixed for my patch, but the same
bug seems to exist in flv_write_packet() where FLV video tags are
unconditionally marked as h.263. I will write a patch for it after I get
this patch in an acceptable state.

[...]

Here is an updated version of the patch. Please let me know what else
needs to be changed.

	-Allan

-- 
Allan Hsu <allan at counterpop dot net>
1E64 E20F 34D9 CBA7 1300 1457 AC37 CBBB 0E92 C779
-------------- next part --------------
Index: libavformat/flvenc.c
===================================================================
--- libavformat/flvenc.c	(revision 7254)
+++ libavformat/flvenc.c	(working copy)
@@ -99,11 +99,16 @@
     put_be64(pb, av_dbl2int(d));
 }
 
+static void put_amf_bool(ByteIOContext *pb, int b) {
+    put_byte(pb, AMF_DATA_TYPE_BOOL);
+    put_byte(pb, !!b);
+}
+
 static int flv_write_header(AVFormatContext *s)
 {
     ByteIOContext *pb = &s->pb;
     FLVContext *flv = s->priv_data;
-    int i, width, height, samplerate;
+    int i, width, height, samplerate, samplesize, channels, audiocodecid, videocodecid;
     double framerate = 0.0;
     int metadata_size_pos, data_size;
 
@@ -127,9 +132,48 @@
                 framerate = 1/av_q2d(s->streams[i]->codec->time_base);
             }
             flv->hasVideo=1;
+            
+            switch(enc->codec_id) {
+                case    CODEC_ID_FLV1:
+                    videocodecid = FLV_CODECID_H263  ; break;
+                case CODEC_ID_FLASHSV:
+                    videocodecid = FLV_CODECID_SCREEN; break;
+                case    CODEC_ID_VP6F:
+                    videocodecid = FLV_CODECID_VP6   ; break;
+                default:
+                    av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
+                    return -1;
+            }
         } else {
             flv->hasAudio=1;
             samplerate = enc->sample_rate;
+            channels = enc->channels;
+
+            switch(enc->codec_id) {
+                case    CODEC_ID_PCM_S8:
+                    audiocodecid = FLV_CODECID_PCM_BE >> FLV_AUDIO_CODECID_OFFSET;
+                    samplesize = 8;
+                    break;
+                case CODEC_ID_PCM_S16BE:
+                    audiocodecid = FLV_CODECID_PCM_BE >> FLV_AUDIO_CODECID_OFFSET;
+                    samplesize = 16;
+                    break;
+                case CODEC_ID_ADPCM_SWF:
+                    audiocodecid = FLV_CODECID_ADPCM  >> FLV_AUDIO_CODECID_OFFSET;
+                    samplesize = 16; //this seems to be what is reported by ADPCM audio tags.
+                    break;
+                case       CODEC_ID_MP3:
+                    audiocodecid = FLV_CODECID_MP3    >> FLV_AUDIO_CODECID_OFFSET;
+                    samplesize = 16;
+                    break;
+                case CODEC_ID_PCM_S16LE:
+                    audiocodecid = FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET;
+                    samplesize = 16;
+                    break;
+                default:
+                    //unsupported format, but the get_audio_flags check below will catch it.
+                    break;
+            }
         }
         av_set_pts_info(s->streams[i], 24, 1, 1000); /* 24 bit pts in ms */
         if(enc->codec_tag == 5){
@@ -159,7 +203,7 @@
 
     /* mixed array (hash) with size and string/type/data tuples */
     put_byte(pb, AMF_DATA_TYPE_MIXEDARRAY);
-    put_be32(pb, 4*flv->hasVideo + flv->hasAudio + 2); // +2 for duration and file size
+    put_be32(pb, 5*flv->hasVideo + 4*flv->hasAudio + 2); // +2 for duration and file size
 
     put_amf_string(pb, "duration");
     flv->duration_offset= url_ftell(pb);
@@ -177,11 +221,23 @@
 
         put_amf_string(pb, "framerate");
         put_amf_double(pb, framerate);
+
+        put_amf_string(pb, "videocodecid");
+        put_amf_double(pb, videocodecid);
     }
 
     if(flv->hasAudio){
         put_amf_string(pb, "audiosamplerate");
         put_amf_double(pb, samplerate);
+
+        put_amf_string(pb, "audiosamplesize");
+        put_amf_double(pb, samplesize);
+
+        put_amf_string(pb, "stereo");
+        put_amf_bool(pb, (channels == 2));
+
+        put_amf_string(pb, "audiocodecid");
+        put_amf_double(pb, audiocodecid);
     }
 
     put_amf_string(pb, "filesize");



More information about the ffmpeg-devel mailing list