Since the container is relatively simple adding it is straightforward.
---
 libavformat/flvenc.c |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 7ffe995..51180c9 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -173,7 +173,7 @@ static int flv_write_header(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
     FLVContext *flv = s->priv_data;
-    AVCodecContext *audio_enc = NULL, *video_enc = NULL;
+    AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL;
     int i;
     double framerate = 0.0;
     int metadata_size_pos, data_size;
@@ -200,6 +200,14 @@ static int flv_write_header(AVFormatContext *s)
                 audio_enc = enc;
                 if (get_audio_flags(enc)<0) return -1;
             break;
+            case AVMEDIA_TYPE_DATA:
+                if (enc->codec_id != CODEC_ID_TEXT) {
+                    av_log(enc, AV_LOG_ERROR,
+                                "codec not compatible with flv\n");
+                    return -1;
+                }
+                data_enc = enc;
+            break;
             default:
                 av_log(enc, AV_LOG_ERROR, "codec not compatible with flv\n");
                 return -1;
@@ -241,7 +249,7 @@ static int flv_write_header(AVFormatContext *s)
 
     /* mixed array (hash) with size and string/type/data tuples */
     avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
-    avio_wb32(pb, 5*!!video_enc + 5*!!audio_enc + 2); // +2 for duration and 
file size
+    avio_wb32(pb, 5*!!video_enc + 5*!!audio_enc + 2 + 1*!!data_enc); // +2 for 
duration and file size
 
     put_amf_string(pb, "duration");
     flv->duration_offset= avio_tell(pb);
@@ -287,6 +295,11 @@ static int flv_write_header(AVFormatContext *s)
         put_amf_string(pb, tag->value);
     }
 
+    if (data_enc) {
+        put_amf_string(pb, "data-stream");
+        put_amf_double(pb, data_enc->codec_id);
+    }
+
     put_amf_string(pb, "filesize");
     flv->filesize_offset= avio_tell(pb);
     put_amf_double(pb, 0); // delayed write
@@ -404,6 +417,9 @@ static int flv_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 
             avio_w8(pb, FLV_TAG_TYPE_AUDIO);
         break;
+        case AVMEDIA_TYPE_DATA:
+            avio_w8(pb, FLV_TAG_TYPE_META);
+        break;
     }
 
     if (enc->codec_id == CODEC_ID_H264) {
@@ -425,6 +441,28 @@ static int flv_write_packet(AVFormatContext *s, AVPacket 
*pkt)
     avio_wb24(pb,ts);
     avio_w8(pb,(ts >> 24) & 0x7F); // timestamps are 32bits _signed_
     avio_wb24(pb,flv->reserved);
+
+    if (enc->codec_type == AVMEDIA_TYPE_DATA) {
+        int data_size;
+        int metadata_size_pos = avio_tell(pb);
+        avio_w8(pb, AMF_DATA_TYPE_STRING);
+        put_amf_string(pb, "data-stream");
+        avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
+        avio_wb32(pb, 2);
+        put_amf_string(pb, "codecid");
+        put_amf_double(pb, enc->codec_id);
+        put_amf_string(pb, "data");
+        avio_w8(pb, AMF_DATA_TYPE_STRING);
+        put_amf_string(pb, pkt->data);
+        put_amf_string(pb, "");
+        avio_w8(pb, AMF_END_OF_OBJECT);
+        /* write total size of tag */
+        data_size = avio_tell(pb) - metadata_size_pos;
+        avio_seek(pb, metadata_size_pos - 10, SEEK_SET);
+        avio_wb24(pb, data_size);
+        avio_seek(pb, data_size + 10 - 3, SEEK_CUR);
+        avio_wb32(pb, data_size + 11);
+    } else {
     avio_w8(pb,flags);
     if (enc->codec_id == CODEC_ID_VP6)
         avio_w8(pb,0);
@@ -441,6 +479,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 
     avio_wb32(pb,size+flags_size+11); // previous tag size
     flv->duration = FFMAX(flv->duration, pkt->pts + flv->delay + 
pkt->duration);
+    }
 
     avio_flush(pb);
 
-- 
1.7.4.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to