978 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			978 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 | 
						|
 *
 | 
						|
 *  Use of this source code is governed by a BSD-style license
 | 
						|
 *  that can be found in the LICENSE file in the root of the source
 | 
						|
 *  tree. An additional intellectual property rights grant can be found
 | 
						|
 *  in the file PATENTS.  All contributing project authors may
 | 
						|
 *  be found in the AUTHORS file in the root of the source tree.
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 * vie_codec_impl.cc
 | 
						|
 */
 | 
						|
 | 
						|
#include "vie_codec_impl.h"
 | 
						|
 | 
						|
// Defines
 | 
						|
#include "engine_configurations.h"
 | 
						|
#include "vie_defines.h"
 | 
						|
 | 
						|
#include "video_coding.h"
 | 
						|
#include "trace.h"
 | 
						|
#include "vie_errors.h"
 | 
						|
#include "vie_impl.h"
 | 
						|
#include "vie_channel.h"
 | 
						|
#include "vie_channel_manager.h"
 | 
						|
#include "vie_encoder.h"
 | 
						|
#include "vie_input_manager.h"
 | 
						|
#include "vie_capturer.h"
 | 
						|
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
namespace webrtc
 | 
						|
{
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// GetInterface
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
ViECodec* ViECodec::GetInterface(VideoEngine* videoEngine)
 | 
						|
{
 | 
						|
#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
 | 
						|
    if (videoEngine == NULL)
 | 
						|
    {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    VideoEngineImpl* vieImpl = reinterpret_cast<VideoEngineImpl*> (videoEngine);
 | 
						|
    ViECodecImpl* vieCodecImpl = vieImpl;
 | 
						|
    (*vieCodecImpl)++; // Increase ref count
 | 
						|
 | 
						|
    return vieCodecImpl;
 | 
						|
#else
 | 
						|
    return NULL;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// Release
 | 
						|
//
 | 
						|
// Releases the interface, i.e. reduces the reference counter. The number of
 | 
						|
// remaining references is returned, -1 if released too many times.
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::Release()
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, _instanceId,
 | 
						|
               "ViECodecImpl::Release()");
 | 
						|
    (*this)--; // Decrease ref count
 | 
						|
 | 
						|
    WebRtc_Word32 refCount = GetCount();
 | 
						|
    if (refCount < 0)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, _instanceId,
 | 
						|
                   "ViECodec released too many times");
 | 
						|
        SetLastError(kViEAPIDoesNotExist);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, _instanceId,
 | 
						|
               "ViECodec reference count: %d", refCount);
 | 
						|
    return refCount;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// Constructor
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
ViECodecImpl::ViECodecImpl()
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, _instanceId,
 | 
						|
               "ViECodecImpl::ViECodecImpl() Ctor");
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// Destructor
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
ViECodecImpl::~ViECodecImpl()
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, _instanceId,
 | 
						|
               "ViECodecImpl::~ViECodecImpl() Dtor");
 | 
						|
}
 | 
						|
 | 
						|
// Available codecs
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// NumberOfCodecs
 | 
						|
//
 | 
						|
// Returns the number of available codecs
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::NumberOfCodecs() const
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
 | 
						|
               __FUNCTION__);
 | 
						|
 | 
						|
    if (!IsInitialized())
 | 
						|
    {
 | 
						|
        SetLastError(kViENotInitialized);
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
 | 
						|
                   "%s - ViE instance %d not initialized", __FUNCTION__,
 | 
						|
                   _instanceId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    // +2 because of FEC(RED and ULPFEC)
 | 
						|
    return (int) (VideoCodingModule::NumberOfCodecs() + 2);
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// GetCodec
 | 
						|
//
 | 
						|
// Return the video codec with listNumber
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::GetCodec(const unsigned char listNumber,
 | 
						|
                           VideoCodec& videoCodec) const
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId),
 | 
						|
               "%s(listNumber: %d, codecType: %d)", __FUNCTION__, listNumber);
 | 
						|
    if (!IsInitialized())
 | 
						|
    {
 | 
						|
        SetLastError(kViENotInitialized);
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
 | 
						|
                   "%s - ViE instance %d not initialized", __FUNCTION__,
 | 
						|
                   _instanceId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (listNumber == VideoCodingModule::NumberOfCodecs())
 | 
						|
    {
 | 
						|
        memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
 | 
						|
        strcpy(videoCodec.plName, "RED");
 | 
						|
        videoCodec.codecType = kVideoCodecRED;
 | 
						|
        videoCodec.plType = VCM_RED_PAYLOAD_TYPE;
 | 
						|
    }
 | 
						|
    else if (listNumber == VideoCodingModule::NumberOfCodecs() + 1)
 | 
						|
    {
 | 
						|
        memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
 | 
						|
        strcpy(videoCodec.plName, "ULPFEC");
 | 
						|
        videoCodec.codecType = kVideoCodecULPFEC;
 | 
						|
        videoCodec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
 | 
						|
    }
 | 
						|
    else if (VideoCodingModule::Codec(listNumber, &videoCodec)
 | 
						|
        != VCM_OK)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId),
 | 
						|
                   "%s: Could not get codec for listNumber: %u", __FUNCTION__,
 | 
						|
                   listNumber);
 | 
						|
        SetLastError(kViECodecInvalidArgument);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// Codec settings
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// SetSendCodec
 | 
						|
//
 | 
						|
// Sets the send codec for videoChannel
 | 
						|
// This call will affect all channels using the same encoder
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::SetSendCodec(const int videoChannel,
 | 
						|
                               const VideoCodec& videoCodec)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId,videoChannel),
 | 
						|
               "%s(videoChannel: %d, codecType: %d)", __FUNCTION__,
 | 
						|
               videoChannel, videoCodec.codecType);
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_instanceId, videoChannel),
 | 
						|
               "%s: codec: %d, plType: %d, width: %d, height: %d, bitrate: %d"
 | 
						|
               "maxBr: %d, minBr: %d, frameRate: %d)", __FUNCTION__,
 | 
						|
               videoCodec.codecType, videoCodec.plType, videoCodec.width,
 | 
						|
               videoCodec.height, videoCodec.startBitrate,
 | 
						|
               videoCodec.maxBitrate, videoCodec.minBitrate,
 | 
						|
               videoCodec.maxFramerate);
 | 
						|
 | 
						|
    if (CodecValid(videoCodec) == false)
 | 
						|
    {
 | 
						|
        // Error logged
 | 
						|
        SetLastError(kViECodecInvalidCodec);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    // Set a maxBitrate if the user hasn't...
 | 
						|
    VideoCodec videoCodecInternal;
 | 
						|
    memcpy(&videoCodecInternal, &videoCodec, sizeof(webrtc::VideoCodec));
 | 
						|
    if (videoCodecInternal.maxBitrate == 0)
 | 
						|
    {
 | 
						|
        // Max is one bit per pixel ...
 | 
						|
        videoCodecInternal.maxBitrate = (videoCodecInternal.width
 | 
						|
            * videoCodecInternal.height * videoCodecInternal.maxFramerate)
 | 
						|
            / 1000;
 | 
						|
        if (videoCodecInternal.startBitrate > videoCodecInternal.maxBitrate)
 | 
						|
        {
 | 
						|
            // ... but should'nt limit the set start bitrate.
 | 
						|
            videoCodecInternal.maxBitrate = videoCodecInternal.startBitrate;
 | 
						|
        }
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_instanceId,
 | 
						|
                                                        videoChannel),
 | 
						|
                   "%s: New max bitrate set to %d kbps", __FUNCTION__,
 | 
						|
                   videoCodecInternal.maxBitrate);
 | 
						|
    }
 | 
						|
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        assert(false);
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: No encoder found for channel %d", __FUNCTION__);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    // We need to check if the codec settings changed,
 | 
						|
    // then we need a new SSRC
 | 
						|
    bool newRtpStream = false;
 | 
						|
 | 
						|
    VideoCodec encoder;
 | 
						|
    vieEncoder->GetEncoder(encoder);
 | 
						|
    if (encoder.codecType != videoCodecInternal.codecType ||
 | 
						|
        encoder.width != videoCodecInternal.width ||
 | 
						|
        encoder.height != videoCodecInternal.height)
 | 
						|
    {
 | 
						|
        if (cs.ChannelUsingViEEncoder(videoChannel))
 | 
						|
        {
 | 
						|
            // We don't allow changing codec type or size when several
 | 
						|
            // channels share encoder.
 | 
						|
            WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
 | 
						|
                       ViEId(_instanceId, videoChannel),
 | 
						|
                       "%s: Settings differs from other channels using encoder",
 | 
						|
                       __FUNCTION__);
 | 
						|
            SetLastError(kViECodecInUse);
 | 
						|
            return -1;
 | 
						|
        }
 | 
						|
        newRtpStream = true;
 | 
						|
    }
 | 
						|
 | 
						|
    ViEInputManagerScoped is(_inputManager);
 | 
						|
    ViEFrameProviderBase* frameProvider = NULL;
 | 
						|
 | 
						|
    // Stop the media flow while reconfiguring
 | 
						|
    vieEncoder->Pause();
 | 
						|
 | 
						|
    // Check if we have a frame provider that is a camera and can provide this
 | 
						|
    // codec for us.
 | 
						|
    bool useCaptureDeviceAsEncoder = false;
 | 
						|
    frameProvider = is.FrameProvider(vieEncoder);
 | 
						|
    if (frameProvider)
 | 
						|
    {
 | 
						|
        ViECapturer* vieCapture = static_cast<ViECapturer *> (frameProvider);
 | 
						|
        // Try to get preencoded. Nothing to do if it is not supported.
 | 
						|
        if (vieCapture && vieCapture->PreEncodeToViEEncoder(videoCodecInternal,
 | 
						|
                                                            *vieEncoder,
 | 
						|
                                                            videoChannel) == 0)
 | 
						|
        {
 | 
						|
            useCaptureDeviceAsEncoder = true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Update the encoder settings if we are not using a capture device capable
 | 
						|
    // of this codec.
 | 
						|
    if (!useCaptureDeviceAsEncoder
 | 
						|
        && vieEncoder->SetEncoder(videoCodecInternal) != 0)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: Could not change encoder for channel %d", __FUNCTION__,
 | 
						|
                   videoChannel);
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    // Give the channel the new information
 | 
						|
    if (vieChannel->SetSendCodec(videoCodecInternal, newRtpStream) != 0)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: Could not set send codec for channel %d", __FUNCTION__,
 | 
						|
                   videoChannel);
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    // Update the protection mode, we might be switching NACK/FEC
 | 
						|
    vieEncoder->UpdateProtectionMethod();
 | 
						|
    // Get new best format for frame provider
 | 
						|
    if (frameProvider)
 | 
						|
    {
 | 
						|
        frameProvider->FrameCallbackChanged();
 | 
						|
    }
 | 
						|
    // Restart the media flow
 | 
						|
    if (newRtpStream)
 | 
						|
    {
 | 
						|
        // Stream settings changed, make sure we get a key frame
 | 
						|
        vieEncoder->SendKeyFrame();
 | 
						|
    }
 | 
						|
    vieEncoder->Restart();
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// GetSendCodec
 | 
						|
//
 | 
						|
// Gets the current send codec
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::GetSendCodec(const int videoChannel,
 | 
						|
                               VideoCodec& videoCodec) const
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel), "%s(videoChannel: %d)",
 | 
						|
               __FUNCTION__, videoChannel);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: No encoder for channel %d", __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    return vieEncoder->GetEncoder(videoCodec);
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// SetReceiveCodec
 | 
						|
//
 | 
						|
// Registers a possible receive codec
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::SetReceiveCodec(const int videoChannel,
 | 
						|
                                  const VideoCodec& videoCodec)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel),
 | 
						|
               "%s(videoChannel: %d, codecType: %d)", __FUNCTION__,
 | 
						|
               videoChannel, videoCodec.codecType);
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_instanceId, videoChannel),
 | 
						|
               "%s: codec: %d, plType: %d, width: %d, height: %d, bitrate: %d,"
 | 
						|
               "maxBr: %d, minBr: %d, frameRate: %d", __FUNCTION__,
 | 
						|
               videoCodec.codecType, videoCodec.plType, videoCodec.width,
 | 
						|
               videoCodec.height, videoCodec.startBitrate,
 | 
						|
               videoCodec.maxBitrate, videoCodec.minBitrate,
 | 
						|
               videoCodec.maxFramerate);
 | 
						|
 | 
						|
    if (CodecValid(videoCodec) == false)
 | 
						|
    {
 | 
						|
        // Error logged
 | 
						|
        SetLastError(kViECodecInvalidCodec);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (vieChannel->SetReceiveCodec(videoCodec) != 0)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId,
 | 
						|
                                                         videoChannel),
 | 
						|
                   "%s: Could not set receive codec for channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// GetReceiveCodec
 | 
						|
//
 | 
						|
// Gets the current receive codec
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::GetReceiveCodec(const int videoChannel,
 | 
						|
                                  VideoCodec& videoCodec) const
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel),
 | 
						|
               "%s(videoChannel: %d, codecType: %d)", __FUNCTION__,
 | 
						|
               videoChannel, videoCodec.codecType);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (vieChannel->GetReceiveCodec(videoCodec) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// GetCodecConfigParameters
 | 
						|
//
 | 
						|
// Gets the codec config parameters to be sent out-of-band.
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::GetCodecConfigParameters(
 | 
						|
    const int videoChannel,
 | 
						|
    unsigned char configParameters[kConfigParameterSize],
 | 
						|
    unsigned char& configParametersSize) const
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel), "%s(videoChannel: %d)",
 | 
						|
               __FUNCTION__, videoChannel);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: No encoder for channel %d", __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (vieEncoder->GetCodecConfigParameters(configParameters,
 | 
						|
                                             configParametersSize) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// SetImageScaleStatus
 | 
						|
//
 | 
						|
// Enables scaling of the encoded image instead of padding black border or
 | 
						|
// cropping
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::SetImageScaleStatus(const int videoChannel, const bool enable)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel),
 | 
						|
               "%s(videoChannel: %d, enable: %d)", __FUNCTION__, videoChannel,
 | 
						|
               enable);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (vieEncoder->ScaleInputImage(enable) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// Codec statistics
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// GetSendCodecStastistics
 | 
						|
//
 | 
						|
// Get codec statistics for outgoing stream
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
 | 
						|
int ViECodecImpl::GetSendCodecStastistics(const int videoChannel,
 | 
						|
                                          unsigned int& keyFrames,
 | 
						|
                                          unsigned int& deltaFrames) const
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel), "%s(videoChannel %d)",
 | 
						|
               __FUNCTION__, videoChannel);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: No send codec for channel %d", __FUNCTION__,
 | 
						|
                   videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (vieEncoder->SendCodecStatistics((WebRtc_UWord32&) keyFrames,
 | 
						|
                                        (WebRtc_UWord32&) deltaFrames) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// GetReceiveCodecStastistics
 | 
						|
//
 | 
						|
// Get codec statistics for incoming stream
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::GetReceiveCodecStastistics(const int videoChannel,
 | 
						|
                                             unsigned int& keyFrames,
 | 
						|
                                             unsigned int& deltaFrames) const
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel),
 | 
						|
               "%s(videoChannel: %d, codecType: %d)", __FUNCTION__,
 | 
						|
               videoChannel);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieChannel->ReceiveCodecStatistics((WebRtc_UWord32&) keyFrames,
 | 
						|
                                           (WebRtc_UWord32&) deltaFrames) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// Callbacks
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// SetKeyFrameRequestCallbackStatus
 | 
						|
//
 | 
						|
// Enables a kecallback for keyframe request instead of using RTCP
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int videoChannel,
 | 
						|
                                                   const bool enable)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel), "%s(videoChannel: %d)",
 | 
						|
               __FUNCTION__, videoChannel);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieChannel->EnableKeyFrameRequestCallback(enable) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// SetSignalKeyPacketLossStatus
 | 
						|
//
 | 
						|
// Triggers a key frame request when there is packet loss in a received key
 | 
						|
// frame
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::SetSignalKeyPacketLossStatus(const int videoChannel,
 | 
						|
                                               const bool enable,
 | 
						|
                                               const bool onlyKeyFrames)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
 | 
						|
               ViEId(_instanceId, videoChannel),
 | 
						|
               "%s(videoChannel: %d, enable: %d, onlyKeyFrames: %d)",
 | 
						|
               __FUNCTION__, videoChannel, enable);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieChannel->SetSignalPacketLossStatus(enable, onlyKeyFrames) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// RegisterEncoderObserver
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::RegisterEncoderObserver(const int videoChannel,
 | 
						|
                                          ViEEncoderObserver& observer)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
 | 
						|
               __FUNCTION__);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: No encoder for channel %d", __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieEncoder->RegisterCodecObserver(&observer) != 0)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: Could not register codec observer at channel",
 | 
						|
                   __FUNCTION__);
 | 
						|
        SetLastError(kViECodecObserverAlreadyRegistered);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// DeregisterEncoderObserver
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::DeregisterEncoderObserver(const int videoChannel)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
 | 
						|
               __FUNCTION__);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: No encoder for channel %d", __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieEncoder->RegisterCodecObserver(NULL) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecObserverNotRegistered);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// RegisterDecoderObserver
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::RegisterDecoderObserver(const int videoChannel,
 | 
						|
                                          ViEDecoderObserver& observer)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
 | 
						|
               __FUNCTION__);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieChannel->RegisterCodecObserver(&observer) != 0)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel),
 | 
						|
                   "%s: Could not register codec observer at channel",
 | 
						|
                   __FUNCTION__);
 | 
						|
        SetLastError(kViECodecObserverAlreadyRegistered);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// DeregisterDecoderObserver
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::DeregisterDecoderObserver(const int videoChannel)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
 | 
						|
               __FUNCTION__);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieChannel->RegisterCodecObserver(NULL) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecObserverNotRegistered);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// Force a key frame
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// SendKeyFrame
 | 
						|
//
 | 
						|
// Force the next frame to be a key frame
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::SendKeyFrame(const int videoChannel)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId),
 | 
						|
               "%s(videoChannel: %d)", __FUNCTION__, videoChannel);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEEncoder* vieEncoder = cs.Encoder(videoChannel);
 | 
						|
    if (vieEncoder == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieEncoder->SendKeyFrame() != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// WaitForFirstKeyFrame
 | 
						|
//
 | 
						|
// Forc the next frame to be a key frame
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::WaitForFirstKeyFrame(const int videoChannel, const bool wait)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId),
 | 
						|
               "%s(videoChannel: %d, wait: %d)", __FUNCTION__, videoChannel,
 | 
						|
               wait);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId, videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieChannel->WaitForKeyFrame(wait) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// H263 Specific
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// SetInverseH263Logic
 | 
						|
//
 | 
						|
// Used to interoperate with old MS H.263 where key frames are marked as delta
 | 
						|
// and the oposite.
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
int ViECodecImpl::SetInverseH263Logic(int videoChannel, bool enable)
 | 
						|
{
 | 
						|
    WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId),
 | 
						|
               "%s(videoChannel: %d)", __FUNCTION__, videoChannel);
 | 
						|
 | 
						|
    ViEChannelManagerScoped cs(_channelManager);
 | 
						|
    ViEChannel* vieChannel = cs.Channel(videoChannel);
 | 
						|
    if (vieChannel == NULL)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
 | 
						|
                   ViEId(_instanceId,videoChannel), "%s: No channel %d",
 | 
						|
                   __FUNCTION__, videoChannel);
 | 
						|
        SetLastError(kViECodecInvalidChannelId);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (vieChannel->SetInverseH263Logic(enable) != 0)
 | 
						|
    {
 | 
						|
        SetLastError(kViECodecUnknownError);
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// CodecValid
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
bool ViECodecImpl::CodecValid(const VideoCodec& videoCodec)
 | 
						|
{
 | 
						|
    // Check plName matches codecType
 | 
						|
    if (videoCodec.codecType == kVideoCodecRED)
 | 
						|
    {
 | 
						|
#if defined(WIN32)
 | 
						|
        if (_strnicmp(videoCodec.plName, "red", 3) == 0)
 | 
						|
#elif defined(WEBRTC_MAC_INTEL) || defined(WEBRTC_LINUX)
 | 
						|
        if (strncasecmp(videoCodec.plName, "red",3) == 0)
 | 
						|
#endif
 | 
						|
        {
 | 
						|
            // We only care about the type and name for red
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Codec type doesn't match plName", videoCodec.plType);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    else if (videoCodec.codecType == kVideoCodecULPFEC)
 | 
						|
    {
 | 
						|
#if defined(WIN32)
 | 
						|
        if (_strnicmp(videoCodec.plName, "ULPFEC", 6) == 0)
 | 
						|
#elif defined(WEBRTC_MAC_INTEL)|| defined(WEBRTC_LINUX)
 | 
						|
        if (strncasecmp(videoCodec.plName, "ULPFEC",6) == 0)
 | 
						|
#endif
 | 
						|
        {
 | 
						|
            // We only care about the type and name for ULPFEC
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Codec type doesn't match plName", videoCodec.plType);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    else if ((videoCodec.codecType == kVideoCodecH263 &&
 | 
						|
             strncmp(videoCodec.plName, "H263", 4) == 0)
 | 
						|
            || (videoCodec.codecType == kVideoCodecH263
 | 
						|
                && strncmp(videoCodec.plName, "H263-1998", 9) == 0)
 | 
						|
            || (videoCodec.codecType == kVideoCodecVP8
 | 
						|
                && strncmp(videoCodec.plName, "VP8", 4) == 0)
 | 
						|
            || (videoCodec.codecType == kVideoCodecI420
 | 
						|
                && strncmp(videoCodec.plName, "I420", 4) == 0)
 | 
						|
            || (videoCodec.codecType == kVideoCodecH264
 | 
						|
                && strncmp(videoCodec.plName, "H264", 4) == 0))
 | 
						|
            // || (videoCodec.codecType == kVideoCodecMPEG4
 | 
						|
            //  && strncmp(videoCodec.plName, "MP4V-ES", 7) == 0)
 | 
						|
    {
 | 
						|
        // ok
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Codec type doesn't match plName", videoCodec.plType);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    // pltype
 | 
						|
    if (videoCodec.plType == 0 && videoCodec.plType > 127)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Invalid codec payload type: %d", videoCodec.plType);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    // Size
 | 
						|
    if (videoCodec.width > kViEMaxCodecWidth || videoCodec.height
 | 
						|
        > kViEMaxCodecHeight)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Invalid codec size: %u x %u", videoCodec.width,
 | 
						|
                   videoCodec.height);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (videoCodec.startBitrate < kViEMinCodecBitrate)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Invalid startBitrate: %u", videoCodec.startBitrate);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    if (videoCodec.minBitrate < kViEMinCodecBitrate)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Invalid minBitrate: %u", videoCodec.minBitrate);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    if (videoCodec.startBitrate < kViEMinCodecBitrate)
 | 
						|
    {
 | 
						|
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                   "Invalid minBitrate: %u", videoCodec.minBitrate);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (videoCodec.codecType == kVideoCodecH263)
 | 
						|
    {
 | 
						|
        if ((videoCodec.width == 704 && videoCodec.height == 576)
 | 
						|
            || (videoCodec.width == 352 && videoCodec.height == 288)
 | 
						|
            || (videoCodec.width == 176 && videoCodec.height == 144)
 | 
						|
            || (videoCodec.width == 128 && videoCodec.height == 96))
 | 
						|
        {
 | 
						|
            // ok
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, -1,
 | 
						|
                       "Invalid size for H.263");
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return true;
 | 
						|
}
 | 
						|
} // namespace webrtc
 |