From 939924439d3dce9cbfae97cd34b004aee01ac043 Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Fri, 8 Apr 2016 10:03:38 +0200 Subject: [PATCH] Nasty hack for fixing H264 init data on FLV --- lib/bitfields.h | 2 +- lib/flv_tag.cpp | 13 +++++++++++++ lib/h264.cpp | 6 ++++++ lib/h264.h | 3 ++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/bitfields.h b/lib/bitfields.h index 0ca119a4..8fb8dc98 100644 --- a/lib/bitfields.h +++ b/lib/bitfields.h @@ -15,7 +15,7 @@ namespace Bit{ //Host to binary/binary to host functions - similar to kernel ntoh/hton functions. /// Retrieves a short in network order from the pointer p. - inline unsigned short btohs(char * p) { + inline unsigned short btohs(const char * p) { return ((unsigned short)p[0] << 8) | p[1]; } diff --git a/lib/flv_tag.cpp b/lib/flv_tag.cpp index 9d2289e5..d4f5cf18 100644 --- a/lib/flv_tag.cpp +++ b/lib/flv_tag.cpp @@ -11,6 +11,9 @@ #include //memcpy #include + +#include "h264.h" //Needed for init data parsing in case of invalid values from FLV init + /// Holds the last FLV header parsed. /// Defaults to a audio+video header on FLV version 0x01 if no header received yet. char FLV::Header[13] = {'F', 'L', 'V', 0x01, 0x05, 0, 0, 0, 0x09, 0, 0, 0, 0}; @@ -1099,6 +1102,16 @@ JSON::Value FLV::Tag::toJSON(DTSC::Meta & metadata, AMF::Object & amf_storage, u } metadata.tracks[reTrack].init = std::string((char *)data + 12, (size_t)len - 16); } + ///this is a hacky way around invalid FLV data (since it gets ignored nearly everywhere, but we do need correct data... + if (!metadata.tracks[reTrack].width || !metadata.tracks[reTrack].height || !metadata.tracks[reTrack].fpks){ + h264::sequenceParameterSet sps; + sps.fromDTSCInit(metadata.tracks[reTrack].init); + h264::SPSMeta spsChar = sps.getCharacteristics(); + metadata.tracks[reTrack].width = spsChar.width; + metadata.tracks[reTrack].height = spsChar.height; + metadata.tracks[reTrack].fpks = spsChar.fps * 1000; + + } pack_out.null(); return pack_out; //skip rest of parsing, get next tag. } diff --git a/lib/h264.cpp b/lib/h264.cpp index 6d6efd3b..591cf725 100644 --- a/lib/h264.cpp +++ b/lib/h264.cpp @@ -81,6 +81,12 @@ namespace h264 { sequenceParameterSet::sequenceParameterSet(const char * _data, unsigned long _dataLen) : data(_data), dataLen(_dataLen) {} + //DTSC Initdata is the payload for an avcc box. init[8+] is data, init[6-7] is a network-encoded length + void sequenceParameterSet::fromDTSCInit(const std::string & dtscInit){ + data = dtscInit.data() + 8; + dataLen = Bit::btohs(dtscInit.data() + 6); + } + SPSMeta sequenceParameterSet::getCharacteristics() const { SPSMeta result; diff --git a/lib/h264.h b/lib/h264.h index 28cc693b..23dec794 100644 --- a/lib/h264.h +++ b/lib/h264.h @@ -50,7 +50,8 @@ namespace h264 { class sequenceParameterSet { public: - sequenceParameterSet(const char * _data, unsigned long _dataLen); + sequenceParameterSet(const char * _data = NULL, unsigned long _dataLen = 0); + void fromDTSCInit(const std::string & dtscInit); SPSMeta getCharacteristics() const; private: const char * data;