[Ffmpeg-devel] Patch to add header info to flv format
Philipp Klaus
ffmpegdevel
Thu Jul 13 18:56:34 CEST 2006
Benjamin Larsson wrote:
>> Here it is, hope it's possible to integrate with the current source
>> code but as I looked a the CVS there wasn't much change in the
>> flvenc.c file in the last months.
>
> Check out a new version from svn and rediff.
I will do that and fix the tab issues below.
>> ------------------------------------------------------------------------
>>
>> diff -ruN ffmpeg-20060317/ffmpeg.c ffmpeg-20060317_pylon/ffmpeg.c
>> --- ffmpeg-20060317/ffmpeg.c 2006-03-17 14:23:28.000000000 +0100
>> +++ ffmpeg-20060317_pylon/ffmpeg.c 2006-07-12 13:58:27.000000000 +0200
>> @@ -1485,6 +1485,7 @@
>> AVInputStream *ist, **ist_table = NULL;
>> AVInputFile *file_table;
>> AVFormatContext *stream_no_data;
>> + int64_t total_duration = 0;
>
> Tabs are not allowed, use whitespaces. And I'm not sure it is correct to
> pass this from ffmpeg.c. I think this should be calculated inside the
> flvmuxer.
I missed the ffmpeg.c file when converting my tabs to spaces. Sorry
about that.
>> int key;
>>
>> file_table= (AVInputFile*) av_mallocz(nb_input_files *
>> sizeof(AVInputFile));
>> @@ -1514,6 +1515,7 @@
>> j = 0;
>> for(i=0;i<nb_input_files;i++) {
>> is = input_files[i];
>> + total_duration += is->duration;
>
> Tabs.
>
>> for(k=0;k<is->nb_streams;k++) {
>> ist = ist_table[j++];
>> ist->st = is->streams[k];
>> @@ -1533,6 +1535,7 @@
>> nb_ostreams = 0;
>> for(i=0;i<nb_output_files;i++) {
>> os = output_files[i];
>> + os->duration = total_duration;
>
> Tabs.
>
>> nb_ostreams += os->nb_streams;
>> }
>> if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {
>> diff -ruN ffmpeg-20060317/libavformat/flvenc.c
>> ffmpeg-20060317_pylon/libavformat/flvenc.c
>> --- ffmpeg-20060317/libavformat/flvenc.c 2006-01-13
>> 11:22:22.000000000 +0100
>> +++ ffmpeg-20060317_pylon/libavformat/flvenc.c 2006-07-12
>> 18:03:11.000000000 +0200
>> @@ -79,11 +79,44 @@
>> return flags;
>> }
>>
>> +#define AMF_DOUBLE 0
>> +#define AMF_BOOLEAN 1
>> +#define AMF_STRING 2
>> +#define AMF_OBJECT 3
>> +#define AMF_MIXED_ARRAY 8
>> +#define AMF_ARRAY 10
>> +#define AMF_DATE 11
>> +
>> +void put_amf_string(ByteIOContext *pb, const char *str)
>> +{
>> + size_t len = strlen(str);
>> + put_be16(pb, len);
>> + put_buffer(pb, str, len);
>> +}
>> +
>> +void put_amf_double(ByteIOContext *pb, double d)
>> +{
>> + unsigned char *llp = (uint64_t *)&d;
>> + unsigned char nllp[8];
>> + int i;
>> + for (i = 0; i < 8; i++) {
>> + nllp[i] = llp[7-i];
>> + }
>> + put_byte(pb, AMF_DOUBLE);
>> + put_buffer(pb, nllp, 8);
>> +}
>> +
>> +
>> static int flv_write_header(AVFormatContext *s)
>> {
>> ByteIOContext *pb = &s->pb;
>> FLVContext *flv = s->priv_data;
>> int i;
>> + double d;
>> + int width = 0;
>> + int height = 0;
>> + double framerate = 0.0;
>> + int audiosamplerate = 0;
>>
>> flv->hasAudio = 0;
>> flv->hasVideo = 0;
>> @@ -96,6 +129,17 @@
>>
>> for(i=0; i<s->nb_streams; i++){
>> AVCodecContext *enc = s->streams[i]->codec;
>> + if (enc->codec_type == CODEC_TYPE_VIDEO) {
>> + width = enc->width;
>> + height = enc->height;
>> + if (s->streams[i]->r_frame_rate.den &&
>> s->streams[i]->r_frame_rate.num) {
>> + framerate = av_q2d(s->streams[i]->r_frame_rate);
>> + } else {
>> + framerate = 1/av_q2d(s->streams[i]->codec->time_base);
>> + }
>> + } else {
>> + audiosamplerate = enc->sample_rate;
>> + }
>> av_set_pts_info(s->streams[i], 24, 1, 1000); /* 24 bit pts in
>> ms */
>> if(enc->codec_tag == 5){
>> put_byte(pb,8); // message type
>> @@ -108,10 +152,61 @@
>> if(enc->codec_type == CODEC_TYPE_AUDIO &&
>> get_audio_flags(enc)<0)
>> return -1;
>> }
>> + + /* write meta_tag */
>> + #define DATA_SIZE 162
>> + put_byte(pb, 18); // tag type META
>> + put_be24(pb, DATA_SIZE); // size of data part (sum of all
>> parts below)
>> + put_be24(pb, 0); // time stamp
>> + put_be32(pb, 0); // reserved
>> + + /* now data of data_size size */
>> + + /* first event name as a string */
>> + put_byte(pb, AMF_STRING); // 1 byte
>> + put_amf_string(pb, "onMetaData"); // 12 bytes
>> + + /* mixed array (hash) with size and string/type/data tuples */
>> + put_byte(pb, AMF_MIXED_ARRAY); // 1 byte +
>> put_be32(pb, 7); // number of entries in the hash (4 bytes)
>> + + put_amf_string(pb, "duration"); // 10 bytes
>> + if (s->duration != AV_NOPTS_VALUE) {
>> + d = (double) s->duration;
>> + d /= AV_TIME_BASE;
>> + } else {
>> + d = 0.0;
>> + }
>> + put_amf_double(pb, d); // 9 bytes
>> + + put_amf_string(pb, "width"); // 7 bytes
>> + put_amf_double(pb, (double) width); // 9 bytes
>> + + put_amf_string(pb, "height"); // 8 bytes
>> + put_amf_double(pb, (double) height); // 9 bytes
> Any special reason to not use enc->height and enc->width here ?
I use enc->height and enc->width but I get the values above.
>> + + put_amf_string(pb, "videodatarate"); // 15 bytes
>> + put_amf_double(pb, (double) s->bit_rate / 1024.0); // 9 bytes
>> + + put_amf_string(pb, "filesize"); // 10 bytes
>> + put_amf_double(pb, (double) s->file_size); // 9 bytes
>> + + put_amf_string(pb, "framerate"); // 11 bytes
>> + put_amf_double(pb, framerate); // 9 bytes
>> + + put_amf_string(pb, "audiosamplerate"); // 17 bytes
>> + put_amf_double(pb, (double) audiosamplerate); // 9 bytes
>> + + put_amf_string(pb, ""); // 2 bytes
>> + put_byte(pb, 9); // end marker 1 byte
>> + + /* write total size of tag */
>> + put_be32(pb, DATA_SIZE + 11);
>>
>> return 0;
>> }
>>
>> +
>
> Cosmetics, non needed line.
Correct, I will remove that line.
>> static int flv_write_trailer(AVFormatContext *s)
>> {
>> int64_t file_size;
>>
More information about the ffmpeg-devel
mailing list