Propagate codec specific info to decoder

Add explicit use of CodecSpecificInfo to VCMGenericDecoder and
the codecs (VP8 and I420). Propagate information from
WebRtcRTPHeader in VCM (IncomingPacket) to GenericDecoder.
Review URL: http://webrtc-codereview.appspot.com/109011

git-svn-id: http://webrtc.googlecode.com/svn/trunk@390 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org 2011-08-17 09:47:33 +00:00
parent 7049389794
commit 473bac8582
11 changed files with 75 additions and 22 deletions

View File

@ -127,8 +127,10 @@ public:
// //
// Return value : WEBRTC_VIDEO_CODEC_OK if OK // Return value : WEBRTC_VIDEO_CODEC_OK if OK
// <0 - Error // <0 - Error
virtual WebRtc_Word32 Decode(const EncodedImage& inputImage, bool missingFrames, virtual WebRtc_Word32 Decode(const EncodedImage& inputImage,
const void* /*codecSpecificInfo */, WebRtc_Word64 /*renderTimeMs*/); bool missingFrames,
const CodecSpecificInfo* /*codecSpecificInfo*/,
WebRtc_Word64 /*renderTimeMs*/);
// Register a decode complete callback object. // Register a decode complete callback object.
// //

View File

@ -208,7 +208,10 @@ I420Decoder::InitDecode(const VideoCodec* codecSettings, WebRtc_Word32 /*numberO
} }
WebRtc_Word32 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) if (inputImage._buffer == NULL)
{ {

View File

@ -21,6 +21,8 @@ namespace webrtc
class RTPFragmentationHeader; // forward declaration 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 struct CodecSpecificInfoVP8
{ {
bool hasReceivedSLI; bool hasReceivedSLI;
@ -36,6 +38,9 @@ union CodecSpecificInfoUnion
CodecSpecificInfoVP8 VP8; 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 struct CodecSpecificInfo
{ {
VideoCodecType codecType; VideoCodecType codecType;
@ -201,7 +206,11 @@ public:
// used by decoders with internal rendering. // used by decoders with internal rendering.
// //
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise. // 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. // Register an decode complete callback object.
// //

View File

@ -203,7 +203,7 @@ public:
// WEBRTC_VIDEO_CODEC_ERR_PARAMETER // WEBRTC_VIDEO_CODEC_ERR_PARAMETER
virtual WebRtc_Word32 Decode(const EncodedImage& inputImage, virtual WebRtc_Word32 Decode(const EncodedImage& inputImage,
bool missingFrames, bool missingFrames,
const void* /*codecSpecificInfo*/, const CodecSpecificInfo* /*codecSpecificInfo*/,
WebRtc_Word64 /*renderTimeMs*/); WebRtc_Word64 /*renderTimeMs*/);
// Register a decode complete callback object. // Register a decode complete callback object.

View File

@ -689,7 +689,7 @@ VP8Decoder::InitDecode(const VideoCodec* inst,
WebRtc_Word32 WebRtc_Word32
VP8Decoder::Decode(const EncodedImage& inputImage, VP8Decoder::Decode(const EncodedImage& inputImage,
bool missingFrames, bool missingFrames,
const void* /*codecSpecificInfo*/, const CodecSpecificInfo* /*codecSpecificInfo*/,
WebRtc_Word64 /*renderTimeMs*/) WebRtc_Word64 /*renderTimeMs*/)
{ {
if (!_inited) if (!_inited)

View File

@ -21,10 +21,9 @@ webrtc::EncodedImage(),
_renderTimeMs(-1), _renderTimeMs(-1),
_payloadType(0), _payloadType(0),
_missingFrame(false), _missingFrame(false),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(kVideoCodecUnknown) _codec(kVideoCodecUnknown)
{ {
_codecSpecificInfo.codecType = kVideoCodecUnknown;
} }
VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs) VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
@ -33,10 +32,9 @@ webrtc::EncodedImage(rhs),
_renderTimeMs(-1), _renderTimeMs(-1),
_payloadType(0), _payloadType(0),
_missingFrame(false), _missingFrame(false),
_codecSpecificInfo(NULL),
_codecSpecificInfoLength(0),
_codec(kVideoCodecUnknown) _codec(kVideoCodecUnknown)
{ {
_codecSpecificInfo.codecType = kVideoCodecUnknown;
_buffer = NULL; _buffer = NULL;
_size = 0; _size = 0;
_length = 0; _length = 0;
@ -53,8 +51,7 @@ webrtc::EncodedImage(rhs),
_renderTimeMs(rhs._renderTimeMs), _renderTimeMs(rhs._renderTimeMs),
_payloadType(rhs._payloadType), _payloadType(rhs._payloadType),
_missingFrame(rhs._missingFrame), _missingFrame(rhs._missingFrame),
_codecSpecificInfo(NULL), _codecSpecificInfo(rhs._codecSpecificInfo),
_codecSpecificInfoLength(0),
_codec(rhs._codec) _codec(rhs._codec)
{ {
_buffer = NULL; _buffer = NULL;
@ -87,17 +84,48 @@ void VCMEncodedFrame::Reset()
_renderTimeMs = -1; _renderTimeMs = -1;
_timeStamp = 0; _timeStamp = 0;
_payloadType = 0; _payloadType = 0;
_codecSpecificInfo = NULL;
_codecSpecificInfoLength = 0;
_frameType = kDeltaFrame; _frameType = kDeltaFrame;
_encodedWidth = 0; _encodedWidth = 0;
_encodedHeight = 0; _encodedHeight = 0;
_completeFrame = false; _completeFrame = false;
_missingFrame = false; _missingFrame = false;
_length = 0; _length = 0;
_codecSpecificInfo.codecType = kVideoCodecUnknown;
_codec = 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 WebRtc_Word32
VCMEncodedFrame::Store(VCMFrameStorageCallback& storeCallback) const VCMEncodedFrame::Store(VCMFrameStorageCallback& storeCallback) const
{ {

View File

@ -13,6 +13,7 @@
#include "module_common_types.h" #include "module_common_types.h"
#include "common_types.h" #include "common_types.h"
#include "video_codec_interface.h"
#include "video_coding_defines.h" #include "video_coding_defines.h"
#include "video_image.h" #include "video_image.h"
@ -79,9 +80,12 @@ public:
*/ */
WebRtc_UWord8 PayloadType() const { return _payloadType; } 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; WebRtc_Word32 Store(VCMFrameStorageCallback& storeCallback) const;
@ -99,11 +103,12 @@ protected:
void Reset(); void Reset();
void CopyCodecSpecific(const RTPVideoHeader* header);
WebRtc_Word64 _renderTimeMs; WebRtc_Word64 _renderTimeMs;
WebRtc_UWord8 _payloadType; WebRtc_UWord8 _payloadType;
bool _missingFrame; bool _missingFrame;
void* _codecSpecificInfo; CodecSpecificInfo _codecSpecificInfo;
WebRtc_UWord32 _codecSpecificInfoLength;
webrtc::VideoCodecType _codec; webrtc::VideoCodecType _codec;
}; };

View File

@ -154,6 +154,9 @@ VCMFrameBuffer::InsertPacket(const VCMPacket& packet, WebRtc_Word64 timeInMs)
return kSizeError; return kSizeError;
} }
} }
CopyCodecSpecific(packet.codecSpecificHeader);
WebRtc_Word64 retVal = _sessionInfo.InsertPacket(packet, _buffer); WebRtc_Word64 retVal = _sessionInfo.InsertPacket(packet, _buffer);
if (retVal == -1) if (retVal == -1)
{ {

View File

@ -157,7 +157,7 @@ WebRtc_Word32 VCMGenericDecoder::Decode(const VCMEncodedFrame& frame)
WebRtc_Word32 ret = _decoder.Decode(frame.EncodedImage(), WebRtc_Word32 ret = _decoder.Decode(frame.EncodedImage(),
frame.MissingFrame(), frame.MissingFrame(),
frame.CodecSpecificInfo(), frame.CodecSpecific(),
frame.RenderTimeMs()); frame.RenderTimeMs());
if (ret < WEBRTC_VIDEO_CODEC_OK) if (ret < WEBRTC_VIDEO_CODEC_OK)
@ -200,4 +200,4 @@ bool VCMGenericDecoder::External() const
return _isExternal; return _isExternal;
} }
} } // namespace

View File

@ -30,7 +30,8 @@ VCMPacket::VCMPacket(const WebRtc_UWord8* ptr,
isFirstPacket(rtpHeader.type.Video.isFirstPacket), isFirstPacket(rtpHeader.type.Video.isFirstPacket),
completeNALU(kNaluComplete), completeNALU(kNaluComplete),
insertStartCode(false), insertStartCode(false),
bits(false) bits(false),
codecSpecificHeader(&rtpHeader.type.Video)
{ {
CopyCodecSpecifics(rtpHeader.type.Video); CopyCodecSpecifics(rtpHeader.type.Video);
} }
@ -48,7 +49,8 @@ VCMPacket::VCMPacket(const WebRtc_UWord8* ptr, WebRtc_UWord32 size, WebRtc_UWord
isFirstPacket(false), isFirstPacket(false),
completeNALU(kNaluComplete), completeNALU(kNaluComplete),
insertStartCode(false), insertStartCode(false),
bits(false) bits(false),
codecSpecificHeader(NULL)
{} {}
void VCMPacket::CopyCodecSpecifics(const RTPVideoHeader& videoHeader) void VCMPacket::CopyCodecSpecifics(const RTPVideoHeader& videoHeader)

View File

@ -48,6 +48,7 @@ public:
// first // first
// byte should be ORed with the last packet of the // byte should be ORed with the last packet of the
// previous frame. // previous frame.
const RTPVideoHeader *codecSpecificHeader;
protected: protected:
void CopyCodecSpecifics(const RTPVideoHeader& videoHeader); void CopyCodecSpecifics(const RTPVideoHeader& videoHeader);