+static int add_info(ByteIOContext *bc, const char *type, const char *value){
+ put_str(bc, type);
+ put_s(bc, -1);
+ put_str(bc, value);
+ return 1;
+}
+
+static int write_globalinfo(NUTContext *nut, ByteIOContext *bc){
+ AVFormatContext *s= nut->avf;
+ AVMetadataTag *title, *author, *copyright;
+ ByteIOContext *dyn_bc;
+ uint8_t *dyn_buf=NULL;
+ int count=0, dyn_size;
+ int ret = url_open_dyn_buf(&dyn_bc);
+ if(ret < 0)
+ return ret;
+
+ title = av_metadata_get(s->metadata, "Title" , NULL, 0);
+ author = av_metadata_get(s->metadata, "Author" , NULL, 0);
+ copyright = av_metadata_get(s->metadata, "Copyright", NULL, 0);
+
+ if(title ) count+= add_info(dyn_bc, "Title" , title->value);
+ if(author ) count+= add_info(dyn_bc, "Author" , author->value);
+ if(copyright) count+= add_info(dyn_bc, "Copyright", copyright->value);
+ if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
+ count+= add_info(dyn_bc, "Encoder" , LIBAVFORMAT_IDENT);
+
+ put_v(bc, 0); //stream_if_plus1
+ put_v(bc, 0); //chapter_id
+ put_v(bc, 0); //timestamp_start
+ put_v(bc, 0); //length
+
+ put_v(bc, count);
+
+ dyn_size= url_close_dyn_buf(dyn_bc, &dyn_buf);
+ put_buffer(bc, dyn_buf, dyn_size);
+ av_free(dyn_buf);
+ return 0;
+}
+
+static int write_streaminfo(NUTContext *nut, ByteIOContext *bc, int stream_id){
+ AVFormatContext *s= nut->avf;
+ AVStream* st = s->streams[stream_id];
+ ByteIOContext *dyn_bc;
+ uint8_t *dyn_buf=NULL;
+ int count=0, dyn_size, i;
+ int ret = url_open_dyn_buf(&dyn_bc);
+ if(ret < 0)
+ return ret;
+
+ for (i=0; ff_nut_dispositions[i].flag; ++i) {
+ if (st->disposition & ff_nut_dispositions[i].flag)
+ count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str);
+ }
+ dyn_size = url_close_dyn_buf(dyn_bc, &dyn_buf);
+
+ if (count) {
+ put_v(bc, stream_id + 1); //stream_id_plus1
+ put_v(bc, 0); //chapter_id
+ put_v(bc, 0); //timestamp_start
+ put_v(bc, 0); //length
+
+ put_v(bc, count);
+
+ put_buffer(bc, dyn_buf, dyn_size);
+ }
+
+ av_free(dyn_buf);
+ return count;
+}
+
+static int write_headers(NUTContext *nut, ByteIOContext *bc){
+ ByteIOContext *dyn_bc;
+ int i, ret;
+
+ ret = url_open_dyn_buf(&dyn_bc);
+ if(ret < 0)
+ return ret;
+ write_mainheader(nut, dyn_bc);
+ put_packet(nut, bc, dyn_bc, 1, MAIN_STARTCODE);
+
+ for (i=0; i < nut->avf->nb_streams; i++){
+ ret = url_open_dyn_buf(&dyn_bc);
+ if(ret < 0)
+ return ret;
+ write_streamheader(nut, dyn_bc, nut->avf->streams[i], i);
+ put_packet(nut, bc, dyn_bc, 1, STREAM_STARTCODE);
+ }
+
+ ret = url_open_dyn_buf(&dyn_bc);
+ if(ret < 0)
+ return ret;
+ write_globalinfo(nut, dyn_bc);
+ put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
+
+ for (i = 0; i < nut->avf->nb_streams; i++) {
+ ret = url_open_dyn_buf(&dyn_bc);
+ if(ret < 0)
+ return ret;
+ ret = write_streaminfo(nut, dyn_bc, i);
+ if (ret < 0)
+ return ret;
+ if (ret > 0)
+ put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE);
+ else {
+ uint8_t* buf;
+ url_close_dyn_buf(dyn_bc, &buf);
+ av_free(buf);
+ }
+ }
+
+ nut->last_syncpoint_pos= INT_MIN;
+ nut->header_count++;
+ return 0;
+}
+