diff --git a/lib/flv_tag.cpp b/lib/flv_tag.cpp index 939a96c6..520929e5 100644 --- a/lib/flv_tag.cpp +++ b/lib/flv_tag.cpp @@ -933,11 +933,14 @@ char * FLV::Tag::getData(){ /// Returns the length of the raw media data for this packet. unsigned int FLV::Tag::getDataLen(){ if (data[0] == 0x08 && (data[11] & 0xF0) == 0xA0) { + if (len < 17){return 0;} return len - 17; } if (data[0] == 0x09 && (data[11] & 0x0F) == 7) { + if (len < 20){return 0;} return len - 20; } + if (len < 16){return 0;} return len - 16; } @@ -993,10 +996,8 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata, AMF::Object & amf_storage, u char audiodata = data[11]; metadata.tracks[reTrack].trackID = reTrack; metadata.tracks[reTrack].type = "audio"; - if (metadata.tracks[reTrack].codec == "") { + if (metadata.tracks[reTrack].codec == "" || metadata.tracks[reTrack].codec != getAudioCodec()) { metadata.tracks[reTrack].codec = getAudioCodec(); - } - if (!metadata.tracks[reTrack].rate) { switch (audiodata & 0x0C) { case 0x0: metadata.tracks[reTrack].rate = 5512; @@ -1014,8 +1015,6 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata, AMF::Object & amf_storage, u if (amf_storage.getContentP("audiosamplerate")) { metadata.tracks[reTrack].rate = (long long int)amf_storage.getContentP("audiosamplerate")->NumValue(); } - } - if (!metadata.tracks[reTrack].size) { switch (audiodata & 0x02) { case 0x0: metadata.tracks[reTrack].size = 8; @@ -1027,8 +1026,6 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata, AMF::Object & amf_storage, u if (amf_storage.getContentP("audiosamplesize")) { metadata.tracks[reTrack].size = (long long int)amf_storage.getContentP("audiosamplesize")->NumValue(); } - } - if (!metadata.tracks[reTrack].channels) { switch (audiodata & 0x01) { case 0x0: metadata.tracks[reTrack].channels = 1; @@ -1124,6 +1121,11 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata, AMF::Object & amf_storage, u break; //the video info byte we just throw away - useless to us... } pack_out["time"] = tagTime(); + if (!getDataLen()){ + //empty packet + pack_out["data"] = ""; + return pack_out; + } if ((videodata & 0x0F) == 7) { switch (data[12]) { case 1: diff --git a/src/input/input_flv.cpp b/src/input/input_flv.cpp index b6163aa7..6b0d9b59 100644 --- a/src/input/input_flv.cpp +++ b/src/input/input_flv.cpp @@ -105,6 +105,9 @@ namespace Mist { thisPacket.null(); return; } + if (!tmpTag.getDataLen()){ + return getNext(); + } thisPacket.genericFill(tmpTag.tagTime(), tmpTag.offset(), tmpTag.getTrackID(), tmpTag.getData(), tmpTag.getDataLen(), lastBytePos, tmpTag.isKeyframe); //init packet from tmpTags data } diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index 387a3aac..68936ad3 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -198,6 +198,35 @@ namespace Mist { } if (track.codec == "MP3"){ dataheader[0] += 0x20; + if (track.rate == 8000){ + dataheader[0] |= 0xE0; + }else{ + dataheader[0] |= 0x20; + } + } + if (track.codec == "ADPCM") { + dataheader[0] |= 0x10; + } + if (track.codec == "PCM") { + dataheader[0] |= 0x30; + } + if (track.codec == "Nellymoser") { + if (track.rate == 8000){ + dataheader[0] |= 0x50; + }else if(track.rate == 16000){ + dataheader[0] |= 0x40; + }else{ + dataheader[0] |= 0x60; + } + } + if (track.codec == "G711a") { + dataheader[0] |= 0x70; + } + if (track.codec == "G711mu") { + dataheader[0] |= 0x80; + } + if (track.codec == "Speex") { + dataheader[0] |= 0xB0; } if (track.rate >= 44100){ dataheader[0] |= 0x0C; @@ -824,6 +853,7 @@ namespace Mist { break; } F.ChunkLoader(next); + if (!F.getDataLen()){break;}//ignore empty packets AMF::Object * amf_storage = 0; if (F.data[0] == 0x12 || pushMeta.count(next.cs_id) || !pushMeta.size()){ amf_storage = &(pushMeta[next.cs_id]);