[FFmpeg-devel] Make FLV decoder expose meta-data
Art Clarke
aclarke
Sun Jul 5 23:24:23 CEST 2009
On Sun, Jul 5, 2009 at 7:21 AM, Aurelien Jacobs <aurel at gnuage.org> wrote:
> str_val is a 256 bytes buffer so copying "true" or "false" into it won't
> overflow. You could simply use strcpy(). But if you want to keep bound
> checking, please use av_strlcpy() instead of strncpy().
>
Good point. I changed it to av_strlcpy
>
> > [...]
> > } else if(amf_type == AMF_DATA_TYPE_NUMBER) {
> > + snprintf(str_val, sizeof(str_val)-1, "%0.lf", num_val);
> > + str_val[sizeof(str_val)-1] = 0;
>
> snprintf() guaranty that the generated string will be null terminated.
> So no need for the -1 and no need to explicitely add null byte.
> Also your format string is a bit strange. First, the l modifier seems
> useless and not even defined in my printf man page.
> And the 0 seems useless to.
>
Way back in the day I recall not all snprintf implementations actually
guaranteed they would null-terminate if the string filled the input buffer.
I guess that's changed, and so I updated the patch as suggested. As for
"%0.lf", I also replace with "%.f"
> > @@ -375,7 +382,7 @@
> > if ((flags & 0xf0) == 0x50) /* video info / command frame */
> > goto skip;
> > } else {
> > - if (type == FLV_TAG_TYPE_META && size > 13+1+4 && 0)
> > + if (type == FLV_TAG_TYPE_META && size > 13+1+4)
> > flv_read_metabody(s, next);
>
> This code was disabled in r18460 as a way to fix issue977 [1].
> So this would re-open this issue. The audiosamplerate interpreting
> code should probably be disabled/removed... (this belong in a
> separate patch)
>
> Aurel
>
> [1] https://roundup.ffmpeg.org/roundup/ffmpeg/issue977
>
I wasn't aware of that issue, and it's a good catch. I started a separate
patch, but it ended up being (1) remove pretty much all the AMF parsing code
that was there (like Michael did) and then (2) add most of it back in so as
to set up the av_metadata stuff. This seems silly since the old version of
the code I'm patching already had removed it via Michael's && 0 check.
So instead, I submit a combined patch that I hope is simple enough I nuked
every piece of AVCodecContext and AVFormatContext data that the AMF parsing
data was setting except for bit_rate and duration -- all others are
correctly parsed from the FLV audio and video headers, and the onMetaData
versions should be ignored. Bit-rate and duration are needed because
Michael's patch (r18460) had the undesirable side-effect that for
network-streamed FLV files we lost these settings (but they are quite useful
to have), and outside of reading the entire stream, those two items cannot
be computed from the packet headers in FLV.
- Art
--
http://www.xuggle.com/
xu?ggle (z?' gl) v. To freely encode, decode, and experience audio and
video.
Use Xuggle to get the power of FFmpeg in Java.
-------------- next part --------------
Index: libavformat/flvdec.c
===================================================================
--- libavformat/flvdec.c (revision 19352)
+++ libavformat/flvdec.c (working copy)
@@ -218,36 +218,17 @@
vcodec = vstream ? vstream->codec : NULL;
if(amf_type == AMF_DATA_TYPE_BOOL) {
- if(!strcmp(key, "stereo") && acodec) acodec->channels = num_val > 0 ? 2 : 1;
+ av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
+ av_metadata_set(&s->metadata, key, str_val);
} else if(amf_type == AMF_DATA_TYPE_NUMBER) {
+ snprintf(str_val, sizeof(str_val), "%.f", num_val);
+ av_metadata_set(&s->metadata, key, str_val);
if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE;
-// else if(!strcmp(key, "width") && vcodec && num_val > 0) vcodec->width = num_val;
-// else if(!strcmp(key, "height") && vcodec && num_val > 0) vcodec->height = num_val;
else if(!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
vcodec->bit_rate = num_val * 1024.0;
- else if(!strcmp(key, "audiocodecid") && acodec && 0 <= (int)num_val)
- flv_set_audio_codec(s, astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET);
- else if(!strcmp(key, "videocodecid") && vcodec && 0 <= (int)num_val)
- flv_set_video_codec(s, vstream, (int)num_val);
- else if(!strcmp(key, "audiosamplesize") && acodec && 0 < (int)num_val) {
- acodec->bits_per_coded_sample = num_val;
- //we may have to rewrite a previously read codecid because FLV only marks PCM endianness.
- if(num_val == 8 && (acodec->codec_id == CODEC_ID_PCM_S16BE || acodec->codec_id == CODEC_ID_PCM_S16LE))
- acodec->codec_id = CODEC_ID_PCM_S8;
- }
- else if(!strcmp(key, "audiosamplerate") && acodec && num_val >= 0) {
- //some tools, like FLVTool2, write consistently approximate metadata sample rates
- if (!acodec->sample_rate) {
- switch((int)num_val) {
- case 44000: acodec->sample_rate = 44100 ; break;
- case 22000: acodec->sample_rate = 22050 ; break;
- case 11000: acodec->sample_rate = 11025 ; break;
- case 5000 : acodec->sample_rate = 5512 ; break;
- default : acodec->sample_rate = num_val;
- }
- }
- }
- }
+ } else if (amf_type == AMF_DATA_TYPE_STRING)
+ av_metadata_set(&s->metadata, key, str_val);
+
}
return 0;
@@ -375,7 +356,7 @@
if ((flags & 0xf0) == 0x50) /* video info / command frame */
goto skip;
} else {
- if (type == FLV_TAG_TYPE_META && size > 13+1+4 && 0)
+ if (type == FLV_TAG_TYPE_META && size > 13+1+4)
flv_read_metabody(s, next);
else /* skip packet */
av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
More information about the ffmpeg-devel
mailing list