1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11ca0e88afdbb0ba88c4dc035cfa17e9c8956a74b1mikhal@webrtc.org#include "webrtc/modules/video_coding/main/source/codec_database.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <assert.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
15ca0e88afdbb0ba88c4dc035cfa17e9c8956a74b1mikhal@webrtc.org#include "webrtc/engine_configurations.h"
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_I420
17ca0e88afdbb0ba88c4dc035cfa17e9c8956a74b1mikhal@webrtc.org#include "webrtc/modules/video_coding/codecs/i420/main/interface/i420.h"
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_VP8
20ca0e88afdbb0ba88c4dc035cfa17e9c8956a74b1mikhal@webrtc.org#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
22ca0e88afdbb0ba88c4dc035cfa17e9c8956a74b1mikhal@webrtc.org#include "webrtc/modules/video_coding/main/source/internal_defines.h"
238edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
276b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.orgVideoCodecVP8 VideoEncoder::GetDefaultVp8Settings() {
286b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  VideoCodecVP8 vp8_settings;
296b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  memset(&vp8_settings, 0, sizeof(vp8_settings));
306b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org
316b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  vp8_settings.resilience = kResilientStream;
326b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  vp8_settings.numberOfTemporalLayers = 1;
336b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  vp8_settings.denoisingOn = true;
346b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  vp8_settings.errorConcealmentOn = false;
356b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  vp8_settings.automaticResizeOn = false;
366b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  vp8_settings.frameDroppingOn = true;
376b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  vp8_settings.keyFrameInterval = 3000;
386b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org
396b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  return vp8_settings;
406b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org}
416b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org
426b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.orgVideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
436b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  VideoCodecH264 h264_settings;
446b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  memset(&h264_settings, 0, sizeof(h264_settings));
456b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org
466b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  h264_settings.profile = kProfileBase;
476b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  h264_settings.frameDroppingOn = true;
486b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  h264_settings.keyFrameInterval = 3000;
496b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  h264_settings.spsData = NULL;
506b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  h264_settings.spsLen = 0;
516b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  h264_settings.ppsData = NULL;
526b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  h264_settings.ppsLen = 0;
536b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org
546b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org  return h264_settings;
556b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org}
566b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings,
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     int number_of_cores,
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     bool require_key_frame)
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : settings(settings),
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      number_of_cores(number_of_cores),
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      require_key_frame(require_key_frame) {
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(number_of_cores >= 0);
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMExtDecoderMapItem::VCMExtDecoderMapItem(
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoDecoder* external_decoder_instance,
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type,
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool internal_render_timing)
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : payload_type(payload_type),
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      external_decoder_instance(external_decoder_instance),
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      internal_render_timing(internal_render_timing) {
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
758edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.orgVCMCodecDataBase::VCMCodecDataBase()
768edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org    : number_of_cores_(0),
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      max_payload_size_(kDefaultPayloadSize),
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      periodic_key_frames_(false),
79f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      pending_encoder_reset_(true),
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      current_enc_is_external_(false),
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      send_codec_(),
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      receive_codec_(),
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      external_payload_type_(0),
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      external_encoder_(NULL),
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      internal_source_(false),
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ptr_encoder_(NULL),
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ptr_decoder_(NULL),
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      current_dec_is_external_(false),
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      dec_map_(),
908edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org      dec_external_map_() {}
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMCodecDataBase::~VCMCodecDataBase() {
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ResetSender();
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ResetReceiver();
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VCMCodecDataBase::NumberOfCodecs() {
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return VCM_NUM_VIDEO_CODECS_AVAILABLE;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::Codec(int list_id,
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             VideoCodec* settings) {
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!settings) {
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (list_id >= VCM_NUM_VIDEO_CODECS_AVAILABLE) {
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memset(settings, 0, sizeof(VideoCodec));
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  switch (list_id) {
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_VP8
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    case VCM_VP8_IDX: {
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      strncpy(settings->plName, "VP8", 4);
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->codecType = kVideoCodecVP8;
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // 96 to 127 dynamic payload types for video codecs.
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->plType = VCM_VP8_PAYLOAD_TYPE;
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->startBitrate = 100;
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->minBitrate = VCM_MIN_BITRATE;
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->maxBitrate = 0;
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->width = VCM_DEFAULT_CODEC_WIDTH;
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->height = VCM_DEFAULT_CODEC_HEIGHT;
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->numberOfSimulcastStreams = 0;
1240c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org      settings->qpMax = 56;
1256b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org      settings->codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings();
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
1292d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org#ifdef VIDEOCODEC_H264
1302d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org    case VCM_H264_IDX: {
1312d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      strncpy(settings->plName, "H264", 5);
1322d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->codecType = kVideoCodecH264;
1332d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      // 96 to 127 dynamic payload types for video codecs.
1342d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->plType = VCM_H264_PAYLOAD_TYPE;
1352d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->startBitrate = 100;
1362d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->minBitrate = VCM_MIN_BITRATE;
1372d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->maxBitrate = 0;
1382d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
1392d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->width = VCM_DEFAULT_CODEC_WIDTH;
1402d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->height = VCM_DEFAULT_CODEC_HEIGHT;
1412d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->numberOfSimulcastStreams = 0;
1422d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      settings->qpMax = 56;
1436b97015d433f126e835178e2b59bc847d1af85a5pbos@webrtc.org      settings->codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings();
1442d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      return true;
1452d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org    }
1462d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org#endif
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_I420
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    case VCM_I420_IDX: {
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      strncpy(settings->plName, "I420", 5);
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->codecType = kVideoCodecI420;
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // 96 to 127 dynamic payload types for video codecs.
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->plType = VCM_I420_PAYLOAD_TYPE;
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // Bitrate needed for this size and framerate.
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->startBitrate = 3 * VCM_DEFAULT_CODEC_WIDTH *
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               VCM_DEFAULT_CODEC_HEIGHT * 8 *
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               VCM_DEFAULT_FRAME_RATE / 1000 / 2;
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->maxBitrate = settings->startBitrate;
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->width = VCM_DEFAULT_CODEC_WIDTH;
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->height = VCM_DEFAULT_CODEC_HEIGHT;
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->minBitrate = VCM_MIN_BITRATE;
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      settings->numberOfSimulcastStreams = 0;
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    default: {
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return false;
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::Codec(VideoCodecType codec_type,
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             VideoCodec* settings) {
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (int i = 0; i < VCMCodecDataBase::NumberOfCodecs(); i++) {
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const bool ret = VCMCodecDataBase::Codec(i, settings);
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!ret) {
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return false;
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (codec_type == settings->codecType) {
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return false;
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMCodecDataBase::ResetSender() {
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeleteEncoder();
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  periodic_key_frames_ = false;
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Assuming only one registered encoder - since only one used, no need for more.
192f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.orgbool VCMCodecDataBase::SetSendCodec(
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const VideoCodec* send_codec,
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int number_of_cores,
195f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    int max_payload_size,
196f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    VCMEncodedFrameCallback* encoded_frame_callback) {
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!send_codec) {
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (max_payload_size <= 0) {
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    max_payload_size = kDefaultPayloadSize;
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
203bc55f91693c7aa050f6420dae22f651ef7b03f6dmflodman@webrtc.org  if (number_of_cores <= 0) {
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (send_codec->plType <= 0) {
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Make sure the start bit rate is sane...
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (send_codec->startBitrate > 1000000) {
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (send_codec->codecType == kVideoCodecUnknown) {
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
216f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  bool reset_required = pending_encoder_reset_;
217f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (number_of_cores_ != number_of_cores) {
218f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    number_of_cores_ = number_of_cores;
219f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    reset_required = true;
220f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  }
221f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (max_payload_size_ != max_payload_size) {
222f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    max_payload_size_ = max_payload_size;
223f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    reset_required = true;
224f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  }
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
226f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  VideoCodec new_send_codec;
227f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  memcpy(&new_send_codec, send_codec, sizeof(new_send_codec));
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
229f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (new_send_codec.maxBitrate == 0) {
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // max is one bit per pixel
231f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    new_send_codec.maxBitrate = (static_cast<int>(send_codec->height) *
232f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org        static_cast<int>(send_codec->width) *
233f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org        static_cast<int>(send_codec->maxFramerate)) / 1000;
234f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    if (send_codec->startBitrate > new_send_codec.maxBitrate) {
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // But if the user tries to set a higher start bit rate we will
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // increase the max accordingly.
237f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.maxBitrate = send_codec->startBitrate;
238f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    }
239f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  }
240f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
241f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (!reset_required) {
242f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    reset_required = RequiresEncoderReset(new_send_codec);
243f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  }
244f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
245f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  memcpy(&send_codec_, &new_send_codec, sizeof(send_codec_));
246f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
247f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (!reset_required) {
248f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    encoded_frame_callback->SetPayloadType(send_codec->plType);
249f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    if (ptr_encoder_->RegisterEncodeCallback(encoded_frame_callback) < 0) {
250f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      return false;
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
252f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    return true;
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
255f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  // If encoder exists, will destroy it and create new one.
256f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  DeleteEncoder();
257f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (send_codec->plType == external_payload_type_) {
258f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    // External encoder.
259f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    ptr_encoder_ = new VCMGenericEncoder(*external_encoder_, internal_source_);
260f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    current_enc_is_external_ = true;
261f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  } else {
262f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    ptr_encoder_ = CreateEncoder(send_codec->codecType);
263f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    current_enc_is_external_ = false;
2648edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org    if (!ptr_encoder_) {
2658edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org      return false;
2668edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org    }
267f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  }
268f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  encoded_frame_callback->SetPayloadType(send_codec->plType);
269f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (ptr_encoder_->InitEncode(send_codec,
270f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org                               number_of_cores_,
271f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org                               max_payload_size_) < 0) {
272f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    DeleteEncoder();
273f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    return false;
274f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  } else if (ptr_encoder_->RegisterEncodeCallback(encoded_frame_callback) < 0) {
275f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    DeleteEncoder();
276f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    return false;
277f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  }
278f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
279f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  // Intentionally don't check return value since the encoder registration
280f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  // shouldn't fail because the codec doesn't support changing the periodic key
281f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  // frame setting.
282f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_);
283f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
284f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  pending_encoder_reset_ = false;
285f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::SendCodec(VideoCodec* current_send_codec) const {
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ptr_encoder_) {
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memcpy(current_send_codec, &send_codec_, sizeof(VideoCodec));
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoCodecType VCMCodecDataBase::SendCodec() const {
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ptr_encoder_) {
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return kVideoCodecUnknown;
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return send_codec_.codecType;
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::DeregisterExternalEncoder(
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type, bool* was_send_codec) {
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(was_send_codec);
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  *was_send_codec = false;
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (external_payload_type_ != payload_type) {
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (send_codec_.plType == payload_type) {
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // De-register as send codec if needed.
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DeleteEncoder();
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&send_codec_, 0, sizeof(VideoCodec));
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    current_enc_is_external_ = false;
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *was_send_codec = true;
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  external_payload_type_ = 0;
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  external_encoder_ = NULL;
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  internal_source_ = false;
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMCodecDataBase::RegisterExternalEncoder(
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoEncoder* external_encoder,
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type,
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool internal_source) {
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Since only one encoder can be used at a given time, only one external
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // encoder can be registered/used.
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  external_encoder_ = external_encoder;
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  external_payload_type_ = payload_type;
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  internal_source_ = internal_source;
333f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  pending_encoder_reset_ = true;
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
336f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.orgbool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) {
337f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (ptr_encoder_ == NULL) {
338f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    return true;
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
340f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
341f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  // Does not check startBitrate or maxFramerate
342f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (new_send_codec.codecType != send_codec_.codecType ||
343f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      strcmp(new_send_codec.plName, send_codec_.plName) != 0 ||
344f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.plType != send_codec_.plType ||
345f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.width != send_codec_.width ||
346f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.height != send_codec_.height ||
347f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.maxBitrate != send_codec_.maxBitrate ||
348f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.minBitrate != send_codec_.minBitrate ||
349f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.qpMax != send_codec_.qpMax ||
350f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.numberOfSimulcastStreams !=
351f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org          send_codec_.numberOfSimulcastStreams ||
352f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.mode != send_codec_.mode ||
353f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      new_send_codec.extra_options != send_codec_.extra_options) {
354f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    return true;
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
356f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
357f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  switch (new_send_codec.codecType) {
358f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    case kVideoCodecVP8:
359f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      if (memcmp(&new_send_codec.codecSpecific.VP8,
360f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org                 &send_codec_.codecSpecific.VP8,
3612d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 sizeof(new_send_codec.codecSpecific.VP8)) != 0) {
362f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org        return true;
363f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      }
364f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      break;
3652d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org    case kVideoCodecH264:
3662d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      if (memcmp(&new_send_codec.codecSpecific.H264,
3672d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 &send_codec_.codecSpecific.H264,
3682d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 sizeof(new_send_codec.codecSpecific.H264)) != 0) {
3692d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org        return true;
3702d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      }
371f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      break;
3727376819aeefb9e7468f8c98bd6f3218e35165c89stefan@webrtc.org    case kVideoCodecGeneric:
3737376819aeefb9e7468f8c98bd6f3218e35165c89stefan@webrtc.org      break;
3747376819aeefb9e7468f8c98bd6f3218e35165c89stefan@webrtc.org    // Known codecs without payload-specifics
3757376819aeefb9e7468f8c98bd6f3218e35165c89stefan@webrtc.org    case kVideoCodecI420:
3767376819aeefb9e7468f8c98bd6f3218e35165c89stefan@webrtc.org    case kVideoCodecRED:
3777376819aeefb9e7468f8c98bd6f3218e35165c89stefan@webrtc.org    case kVideoCodecULPFEC:
3787376819aeefb9e7468f8c98bd6f3218e35165c89stefan@webrtc.org      break;
379f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    // Unknown codec type, reset just to be sure.
380f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    case kVideoCodecUnknown:
381f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      return true;
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
383f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
384f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  if (new_send_codec.numberOfSimulcastStreams > 0) {
385f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams;
386f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org         ++i) {
387f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      if (memcmp(&new_send_codec.simulcastStream[i],
388f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org                 &send_codec_.simulcastStream[i],
389f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org                 sizeof(new_send_codec.simulcastStream[i])) !=
390f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org          0) {
391f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org        return true;
392f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org      }
393f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org    }
394f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  }
395f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org  return false;
396f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org}
397f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.org
398f6cb4b6ef77844d6fe2ab75fc6ec67218dffff3apbos@webrtc.orgVCMGenericEncoder* VCMCodecDataBase::GetEncoder() {
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ptr_encoder_;
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) {
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  periodic_key_frames_ = enable;
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ptr_encoder_) {
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0);
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMCodecDataBase::ResetReceiver() {
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ReleaseDecoder(ptr_decoder_);
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ptr_decoder_ = NULL;
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memset(&receive_codec_, 0, sizeof(VideoCodec));
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  while (!dec_map_.empty()) {
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DecoderMap::iterator it = dec_map_.begin();
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete (*it).second;
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    dec_map_.erase(it);
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  while (!dec_external_map_.empty()) {
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ExternalDecoderMap::iterator external_it = dec_external_map_.begin();
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete (*external_it).second;
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    dec_external_map_.erase(external_it);
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  current_dec_is_external_ = false;
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) {
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type);
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (it == dec_external_map_.end()) {
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Not found
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
4336cae2c807aa702303d578dde383398fb2d978c80fischman@webrtc.org  // We can't use payload_type to check if the decoder is currently in use,
4346cae2c807aa702303d578dde383398fb2d978c80fischman@webrtc.org  // because payload type may be out of date (e.g. before we decode the first
4356cae2c807aa702303d578dde383398fb2d978c80fischman@webrtc.org  // frame after RegisterReceiveCodec)
4366cae2c807aa702303d578dde383398fb2d978c80fischman@webrtc.org  if (ptr_decoder_ != NULL &&
4376cae2c807aa702303d578dde383398fb2d978c80fischman@webrtc.org      &ptr_decoder_->_decoder == (*it).second->external_decoder_instance) {
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Release it if it was registered and in use.
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ReleaseDecoder(ptr_decoder_);
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ptr_decoder_ = NULL;
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeregisterReceiveCodec(payload_type);
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  delete (*it).second;
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  dec_external_map_.erase(it);
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Add the external encoder object to the list of external decoders.
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Won't be registered as a receive codec until RegisterReceiveCodec is called.
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::RegisterExternalDecoder(
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoDecoder* external_decoder,
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type,
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool internal_render_timing) {
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Check if payload value already exists, if so  - erase old and insert new.
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VCMExtDecoderMapItem* ext_decoder = new VCMExtDecoderMapItem(
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      external_decoder, payload_type, internal_render_timing);
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ext_decoder) {
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeregisterExternalDecoder(payload_type);
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  dec_external_map_[payload_type] = ext_decoder;
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::DecoderRegistered() const {
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return !dec_map_.empty();
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::RegisterReceiveCodec(
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const VideoCodec* receive_codec,
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int number_of_cores,
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool require_key_frame) {
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (number_of_cores < 0) {
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Check if payload value already exists, if so  - erase old and insert new.
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeregisterReceiveCodec(receive_codec->plType);
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (receive_codec->codecType == kVideoCodecUnknown) {
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoCodec* new_receive_codec = new VideoCodec(*receive_codec);
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  dec_map_[receive_codec->plType] = new VCMDecoderMapItem(new_receive_codec,
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                          number_of_cores,
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                          require_key_frame);
485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::DeregisterReceiveCodec(
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type) {
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DecoderMap::iterator it = dec_map_.find(payload_type);
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (it == dec_map_.end()) {
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VCMDecoderMapItem* dec_item = (*it).second;
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  delete dec_item;
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  dec_map_.erase(it);
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (receive_codec_.plType == payload_type) {
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // This codec is currently in use.
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&receive_codec_, 0, sizeof(VideoCodec));
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    current_dec_is_external_ = false;
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::ReceiveCodec(VideoCodec* current_receive_codec) const {
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(current_receive_codec);
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ptr_decoder_) {
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memcpy(current_receive_codec, &receive_codec_, sizeof(VideoCodec));
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoCodecType VCMCodecDataBase::ReceiveCodec() const {
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ptr_decoder_) {
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return kVideoCodecUnknown;
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return receive_codec_.codecType;
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMGenericDecoder* VCMCodecDataBase::GetDecoder(
522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type, VCMDecodedFrameCallback* decoded_frame_callback) {
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (payload_type == receive_codec_.plType || payload_type == 0) {
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ptr_decoder_;
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Check for exisitng decoder, if exists - delete.
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ptr_decoder_) {
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ReleaseDecoder(ptr_decoder_);
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ptr_decoder_ = NULL;
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&receive_codec_, 0, sizeof(VideoCodec));
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ptr_decoder_ = CreateAndInitDecoder(payload_type, &receive_codec_,
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      &current_dec_is_external_);
534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ptr_decoder_) {
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
537d893b3fbd858898bd280f94a74854a86a6b91888wuchengli@chromium.org  VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
538d893b3fbd858898bd280f94a74854a86a6b91888wuchengli@chromium.org  if (callback) callback->IncomingCodecChanged(receive_codec_);
539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback)
540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      < 0) {
541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ReleaseDecoder(ptr_decoder_);
542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ptr_decoder_ = NULL;
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&receive_codec_, 0, sizeof(VideoCodec));
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ptr_decoder_;
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMGenericDecoder* VCMCodecDataBase::CreateDecoderCopy() const {
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ptr_decoder_) {
551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoDecoder* decoder_copy = ptr_decoder_->_decoder.Copy();
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!decoder_copy) {
555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
5578edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org  return new VCMGenericDecoder(*decoder_copy, ptr_decoder_->External());
558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const {
561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (decoder) {
562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert(&decoder->_decoder);
563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    decoder->Release();
564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!decoder->External()) {
565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      delete &decoder->_decoder;
566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete decoder;
568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMCodecDataBase::CopyDecoder(const VCMGenericDecoder& decoder) {
572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoDecoder* decoder_copy = decoder._decoder.Copy();
573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (decoder_copy) {
574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VCMDecodedFrameCallback* cb = ptr_decoder_->_callback;
575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ReleaseDecoder(ptr_decoder_);
5768edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org    ptr_decoder_ = new VCMGenericDecoder(*decoder_copy, decoder.External());
577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (cb && ptr_decoder_->RegisterDecodeCompleteCallback(cb)) {
578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      assert(false);
579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMCodecDataBase::SupportsRenderScheduling() const {
584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool render_timing = true;
585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (current_dec_is_external_) {
586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem(
587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        receive_codec_.plType);
588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    render_timing = ext_item->internal_render_timing;
589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return render_timing;
591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder(
594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type,
595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoCodec* new_codec,
596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool* external) const {
597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(external);
598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(new_codec);
599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type);
600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!decoder_item) {
6018edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org    LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
6028edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org                  << payload_type;
603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VCMGenericDecoder* ptr_decoder = NULL;
606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const VCMExtDecoderMapItem* external_dec_item = FindExternalDecoderItem(
607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                              payload_type);
608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (external_dec_item) {
609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // External codec.
610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ptr_decoder = new VCMGenericDecoder(
6118edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org        *external_dec_item->external_decoder_instance, true);
612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *external = true;
613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else {
614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Create decoder.
615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ptr_decoder = CreateDecoder(decoder_item->settings->codecType);
616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    *external = false;
617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!ptr_decoder) {
619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ptr_decoder->InitDecode(decoder_item->settings.get(),
623e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org                              decoder_item->number_of_cores) < 0) {
624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ReleaseDecoder(ptr_decoder);
625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec));
628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ptr_decoder;
629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMGenericEncoder* VCMCodecDataBase::CreateEncoder(
632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const VideoCodecType type) const {
633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  switch (type) {
634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_VP8
635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    case kVideoCodecVP8:
636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return new VCMGenericEncoder(*(VP8Encoder::Create()));
637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_I420
639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    case kVideoCodecI420:
640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return new VCMGenericEncoder(*(new I420Encoder));
641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    default:
6438edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org      LOG(LS_WARNING) << "No internal encoder of this type exists.";
644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return NULL;
645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMCodecDataBase::DeleteEncoder() {
649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ptr_encoder_) {
650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ptr_encoder_->Release();
651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!current_enc_is_external_) {
652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      delete &ptr_encoder_->_encoder;
653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete ptr_encoder_;
655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ptr_encoder_ = NULL;
656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const {
660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  switch (type) {
661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_VP8
662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    case kVideoCodecVP8:
6638edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org      return new VCMGenericDecoder(*(VP8Decoder::Create()));
664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_I420
666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    case kVideoCodecI420:
6678edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org      return new VCMGenericDecoder(*(new I420Decoder));
668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    default:
6702d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org      LOG(LS_WARNING) << "No internal decoder of this type exists.";
671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return NULL;
672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem(
676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type) const {
677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DecoderMap::const_iterator it = dec_map_.find(payload_type);
678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (it != dec_map_.end()) {
679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (*it).second;
680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return NULL;
682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem(
685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    uint8_t payload_type) const {
686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type);
687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (it != dec_external_map_.end()) {
688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return (*it).second;
689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return NULL;
691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
693