diff --git a/src/modules/video_coding/codecs/i420/main/interface/i420.h b/src/modules/video_coding/codecs/i420/main/interface/i420.h index 75c34d96e..5be42948c 100644 --- a/src/modules/video_coding/codecs/i420/main/interface/i420.h +++ b/src/modules/video_coding/codecs/i420/main/interface/i420.h @@ -127,8 +127,10 @@ public: // // Return value : WEBRTC_VIDEO_CODEC_OK if OK // <0 - Error - virtual WebRtc_Word32 Decode(const EncodedImage& inputImage, bool missingFrames, - const void* /*codecSpecificInfo */, WebRtc_Word64 /*renderTimeMs*/); + virtual WebRtc_Word32 Decode(const EncodedImage& inputImage, + bool missingFrames, + const CodecSpecificInfo* /*codecSpecificInfo*/, + WebRtc_Word64 /*renderTimeMs*/); // Register a decode complete callback object. // diff --git a/src/modules/video_coding/codecs/i420/main/source/i420.cc b/src/modules/video_coding/codecs/i420/main/source/i420.cc index 2f276f0cf..30bea23b2 100644 --- a/src/modules/video_coding/codecs/i420/main/source/i420.cc +++ b/src/modules/video_coding/codecs/i420/main/source/i420.cc @@ -208,7 +208,10 @@ I420Decoder::InitDecode(const VideoCodec* codecSettings, WebRtc_Word32 /*numberO } WebRtc_Word32 -I420Decoder::Decode(const EncodedImage& inputImage, bool /*missingFrames*/, const void* /*codecSpecificInfo*/, WebRtc_Word64 /*renderTimeMs*/) +I420Decoder::Decode(const EncodedImage& inputImage, + bool /*missingFrames*/, + const CodecSpecificInfo* /*codecSpecificInfo*/, + WebRtc_Word64 /*renderTimeMs*/) { if (inputImage._buffer == NULL) { diff --git a/src/modules/video_coding/codecs/interface/video_codec_interface.h b/src/modules/video_coding/codecs/interface/video_codec_interface.h index 106039177..03cec0daf 100644 --- a/src/modules/video_coding/codecs/interface/video_codec_interface.h +++ b/src/modules/video_coding/codecs/interface/video_codec_interface.h @@ -21,6 +21,8 @@ namespace webrtc class RTPFragmentationHeader; // forward declaration +// Note: if any pointers are added to this struct, it must be fitted +// with a copy-constructor. See below. struct CodecSpecificInfoVP8 { bool hasReceivedSLI; @@ -36,6 +38,9 @@ union CodecSpecificInfoUnion CodecSpecificInfoVP8 VP8; }; +// Note: if any pointers are added to this struct or its sub-structs, it +// must be fitted with a copy-constructor. This is because it is copied +// in the copy-constructor of VCMEncodedFrame. struct CodecSpecificInfo { VideoCodecType codecType; @@ -201,7 +206,11 @@ public: // used by decoders with internal rendering. // // Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise. - virtual WebRtc_Word32 Decode(const EncodedImage& inputImage, bool missingFrames, const void* codecSpecificInfo = NULL, WebRtc_Word64 renderTimeMs = -1) = 0; + virtual WebRtc_Word32 + Decode(const EncodedImage& inputImage, + bool missingFrames, + const CodecSpecificInfo* codecSpecificInfo = NULL, + WebRtc_Word64 renderTimeMs = -1) = 0; // Register an decode complete callback object. // diff --git a/src/modules/video_coding/codecs/vp8/main/interface/vp8.h b/src/modules/video_coding/codecs/vp8/main/interface/vp8.h index fb549075a..0213095b6 100644 --- a/src/modules/video_coding/codecs/vp8/main/interface/vp8.h +++ b/src/modules/video_coding/codecs/vp8/main/interface/vp8.h @@ -203,7 +203,7 @@ public: // WEBRTC_VIDEO_CODEC_ERR_PARAMETER virtual WebRtc_Word32 Decode(const EncodedImage& inputImage, bool missingFrames, - const void* /*codecSpecificInfo*/, + const CodecSpecificInfo* /*codecSpecificInfo*/, WebRtc_Word64 /*renderTimeMs*/); // Register a decode complete callback object. diff --git a/src/modules/video_coding/codecs/vp8/main/source/vp8.cc b/src/modules/video_coding/codecs/vp8/main/source/vp8.cc index d7721438f..7383e6d83 100644 --- a/src/modules/video_coding/codecs/vp8/main/source/vp8.cc +++ b/src/modules/video_coding/codecs/vp8/main/source/vp8.cc @@ -689,7 +689,7 @@ VP8Decoder::InitDecode(const VideoCodec* inst, WebRtc_Word32 VP8Decoder::Decode(const EncodedImage& inputImage, bool missingFrames, - const void* /*codecSpecificInfo*/, + const CodecSpecificInfo* /*codecSpecificInfo*/, WebRtc_Word64 /*renderTimeMs*/) { if (!_inited) diff --git a/src/modules/video_coding/main/source/encoded_frame.cc b/src/modules/video_coding/main/source/encoded_frame.cc index 25c362bed..8c6664cda 100644 --- a/src/modules/video_coding/main/source/encoded_frame.cc +++ b/src/modules/video_coding/main/source/encoded_frame.cc @@ -21,10 +21,9 @@ webrtc::EncodedImage(), _renderTimeMs(-1), _payloadType(0), _missingFrame(false), -_codecSpecificInfo(NULL), -_codecSpecificInfoLength(0), _codec(kVideoCodecUnknown) { + _codecSpecificInfo.codecType = kVideoCodecUnknown; } VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs) @@ -33,10 +32,9 @@ webrtc::EncodedImage(rhs), _renderTimeMs(-1), _payloadType(0), _missingFrame(false), -_codecSpecificInfo(NULL), -_codecSpecificInfoLength(0), _codec(kVideoCodecUnknown) { + _codecSpecificInfo.codecType = kVideoCodecUnknown; _buffer = NULL; _size = 0; _length = 0; @@ -53,8 +51,7 @@ webrtc::EncodedImage(rhs), _renderTimeMs(rhs._renderTimeMs), _payloadType(rhs._payloadType), _missingFrame(rhs._missingFrame), -_codecSpecificInfo(NULL), -_codecSpecificInfoLength(0), +_codecSpecificInfo(rhs._codecSpecificInfo), _codec(rhs._codec) { _buffer = NULL; @@ -87,17 +84,48 @@ void VCMEncodedFrame::Reset() _renderTimeMs = -1; _timeStamp = 0; _payloadType = 0; - _codecSpecificInfo = NULL; - _codecSpecificInfoLength = 0; _frameType = kDeltaFrame; _encodedWidth = 0; _encodedHeight = 0; _completeFrame = false; _missingFrame = false; _length = 0; + _codecSpecificInfo.codecType = kVideoCodecUnknown; _codec = kVideoCodecUnknown; } +void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header) +{ + if (header) + { + switch (header->codec) + { + case kRTPVideoVP8: + { + if (_codecSpecificInfo.codecType != kVideoCodecVP8) + { + // This is the first packet for this frame. + _codecSpecificInfo.codecSpecific.VP8.pictureId = -1; + _codecSpecificInfo.codecType = kVideoCodecVP8; + } + _codecSpecificInfo.codecSpecific.VP8.nonReference = + header->codecHeader.VP8.nonReference; + if (header->codecHeader.VP8.pictureId != kNoPictureId) + { + _codecSpecificInfo.codecSpecific.VP8.pictureId = + header->codecHeader.VP8.pictureId; + } + break; + } + default: + { + _codecSpecificInfo.codecType = kVideoCodecUnknown; + break; + } + } + } +} + WebRtc_Word32 VCMEncodedFrame::Store(VCMFrameStorageCallback& storeCallback) const { diff --git a/src/modules/video_coding/main/source/encoded_frame.h b/src/modules/video_coding/main/source/encoded_frame.h index 89cbd5e3d..0262995fd 100644 --- a/src/modules/video_coding/main/source/encoded_frame.h +++ b/src/modules/video_coding/main/source/encoded_frame.h @@ -13,6 +13,7 @@ #include "module_common_types.h" #include "common_types.h" +#include "video_codec_interface.h" #include "video_coding_defines.h" #include "video_image.h" @@ -79,9 +80,12 @@ public: */ WebRtc_UWord8 PayloadType() const { return _payloadType; } /** - * Get codec specific info + * Get codec specific info. + * The returned pointer is only valid as long as the VCMEncodedFrame + * is valid. Also, VCMEncodedFrame owns the pointer and will delete + * the object. */ - const void* CodecSpecificInfo() const {return _codecSpecificInfo;} + const CodecSpecificInfo* CodecSpecific() const {return &_codecSpecificInfo;} WebRtc_Word32 Store(VCMFrameStorageCallback& storeCallback) const; @@ -99,11 +103,12 @@ protected: void Reset(); + void CopyCodecSpecific(const RTPVideoHeader* header); + WebRtc_Word64 _renderTimeMs; WebRtc_UWord8 _payloadType; bool _missingFrame; - void* _codecSpecificInfo; - WebRtc_UWord32 _codecSpecificInfoLength; + CodecSpecificInfo _codecSpecificInfo; webrtc::VideoCodecType _codec; }; diff --git a/src/modules/video_coding/main/source/frame_buffer.cc b/src/modules/video_coding/main/source/frame_buffer.cc index b211ea02a..99fe57696 100644 --- a/src/modules/video_coding/main/source/frame_buffer.cc +++ b/src/modules/video_coding/main/source/frame_buffer.cc @@ -154,6 +154,9 @@ VCMFrameBuffer::InsertPacket(const VCMPacket& packet, WebRtc_Word64 timeInMs) return kSizeError; } } + + CopyCodecSpecific(packet.codecSpecificHeader); + WebRtc_Word64 retVal = _sessionInfo.InsertPacket(packet, _buffer); if (retVal == -1) { diff --git a/src/modules/video_coding/main/source/generic_decoder.cc b/src/modules/video_coding/main/source/generic_decoder.cc index 1fddb5222..b03cb8f3b 100644 --- a/src/modules/video_coding/main/source/generic_decoder.cc +++ b/src/modules/video_coding/main/source/generic_decoder.cc @@ -157,7 +157,7 @@ WebRtc_Word32 VCMGenericDecoder::Decode(const VCMEncodedFrame& frame) WebRtc_Word32 ret = _decoder.Decode(frame.EncodedImage(), frame.MissingFrame(), - frame.CodecSpecificInfo(), + frame.CodecSpecific(), frame.RenderTimeMs()); if (ret < WEBRTC_VIDEO_CODEC_OK) @@ -200,4 +200,4 @@ bool VCMGenericDecoder::External() const return _isExternal; } -} +} // namespace diff --git a/src/modules/video_coding/main/source/packet.cc b/src/modules/video_coding/main/source/packet.cc index 86e4ddebd..1c934d37b 100644 --- a/src/modules/video_coding/main/source/packet.cc +++ b/src/modules/video_coding/main/source/packet.cc @@ -30,7 +30,8 @@ VCMPacket::VCMPacket(const WebRtc_UWord8* ptr, isFirstPacket(rtpHeader.type.Video.isFirstPacket), completeNALU(kNaluComplete), insertStartCode(false), - bits(false) + bits(false), + codecSpecificHeader(&rtpHeader.type.Video) { CopyCodecSpecifics(rtpHeader.type.Video); } @@ -48,7 +49,8 @@ VCMPacket::VCMPacket(const WebRtc_UWord8* ptr, WebRtc_UWord32 size, WebRtc_UWord isFirstPacket(false), completeNALU(kNaluComplete), insertStartCode(false), - bits(false) + bits(false), + codecSpecificHeader(NULL) {} void VCMPacket::CopyCodecSpecifics(const RTPVideoHeader& videoHeader) diff --git a/src/modules/video_coding/main/source/packet.h b/src/modules/video_coding/main/source/packet.h index f1fdfd1ad..d51d6e5d1 100644 --- a/src/modules/video_coding/main/source/packet.h +++ b/src/modules/video_coding/main/source/packet.h @@ -48,6 +48,7 @@ public: // first // byte should be ORed with the last packet of the // previous frame. + const RTPVideoHeader *codecSpecificHeader; protected: void CopyCodecSpecifics(const RTPVideoHeader& videoHeader);