1 /* 2 * THEORA Plugin codec for OpenH323/OPAL 3 * 4 * Copyright (C) Matthias Schneider, All Rights Reserved 5 * 6 * This code is based on the file h261codec.cxx from the OPAL project released 7 * under the MPL 1.0 license which contains the following: 8 * 9 * Copyright (c) 1998-2000 Equivalence Pty. Ltd. 10 * 11 * The contents of this file are subject to the Mozilla Public License 12 * Version 1.0 (the "License"); you may not use this file except in 13 * compliance with the License. You may obtain a copy of the License at 14 * http://www.mozilla.org/MPL/ 15 * 16 * Software distributed under the License is distributed on an "AS IS" 17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 18 * the License for the specific language governing rights and limitations 19 * under the License. 20 * 21 * The Original Code is Open H323 Library. 22 * 23 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 24 * 25 * Contributor(s): Matthias Schneider (ma30002000@yahoo.de) 26 * Michele Piccini (michele@piccini.com) 27 * Derek Smithies (derek@indranet.co.nz) 28 * 29 * 30 */ 31 32 /* 33 Notes 34 ----- 35 36 */ 37 38 #ifndef __THEORA_PLUGIN_H__ 39 #define __THEORA_PLUGIN_H__ 1 40 41 #include "plugin-config.h" 42 #include <stdarg.h> 43 #include <stdint.h> 44 #include <codec/opalplugin.h> 45 #include "theora_frame.h" 46 #include "critsect.h" 47 48 extern "C" { 49 #include <theora/theora.h> 50 }; 51 52 #define CIF4_WIDTH 704 53 #define CIF4_HEIGHT 576 54 #define CIF_WIDTH 352 55 #define CIF_HEIGHT 288 56 #define QCIF_WIDTH 176 57 #define QCIF_HEIGHT 144 58 #define IT_QCIF 0 59 #define IT_CIF 1 60 61 typedef unsigned char u_char; 62 63 class theoraEncoderContext 64 { 65 public: 66 theoraEncoderContext (); 67 ~theoraEncoderContext (); 68 69 void SetMaxRTPFrameSize (unsigned size); 70 void SetMaxKeyFramePeriod (unsigned period); 71 void SetTargetBitrate (unsigned rate); 72 void SetFrameRate (unsigned rate); 73 void SetFrameWidth (unsigned width); 74 void SetFrameHeight (unsigned height); 75 void ApplyOptions (); 76 void Lock (); 77 void Unlock (); 78 79 int EncodeFrames (const u_char * src, unsigned & srcLen, u_char * dst, unsigned & dstLen, unsigned int & flags); 80 81 protected: 82 void ApplyOptionsInternal (); 83 CriticalSection _mutex; 84 85 theora_info _theoraInfo; 86 theora_state _theoraState; 87 88 int _frameCounter; 89 theoraFrame* _txTheoraFrame; 90 }; 91 92 class theoraDecoderContext 93 { 94 public: 95 theoraDecoderContext(); 96 ~theoraDecoderContext(); 97 int DecodeFrames(const u_char * src, unsigned & srcLen, u_char * dst, unsigned & dstLen, unsigned int & flags); 98 99 protected: 100 CriticalSection _mutex; 101 102 theora_info _theoraInfo; 103 theora_state _theoraState; 104 theoraFrame* _rxTheoraFrame; 105 106 bool _gotIFrame; 107 bool _gotAGoodFrame; 108 bool _gotHeader; 109 bool _gotTable; 110 int _frameCounter; 111 }; 112 113 const char* theoraErrorMessage(int code); 114 115 static int valid_for_protocol ( const struct PluginCodec_Definition *, void *, const char *, 116 void * parm, unsigned * parmLen); 117 static int get_codec_options ( const struct PluginCodec_Definition * codec, void *, const char *, 118 void * parm, unsigned * parmLen); 119 static int free_codec_options ( const struct PluginCodec_Definition *, void *, const char *, 120 void * parm, unsigned * parmLen); 121 122 123 static void * create_encoder ( const struct PluginCodec_Definition *); 124 static void destroy_encoder ( const struct PluginCodec_Definition *, void * _context); 125 static int codec_encoder ( const struct PluginCodec_Definition *, void * _context, 126 const void * from, unsigned * fromLen, 127 void * to, unsigned * toLen, 128 unsigned int * flag); 129 static int to_normalised_options ( const struct PluginCodec_Definition *, void *, const char *, 130 void * parm, unsigned * parmLen); 131 static int to_customised_options ( const struct PluginCodec_Definition *, void *, const char *, 132 void * parm, unsigned * parmLen); 133 static int encoder_set_options ( const struct PluginCodec_Definition *, void * _context, const char *, 134 void * parm, unsigned * parmLen); 135 static int encoder_get_output_data_size ( const PluginCodec_Definition *, void *, const char *, 136 void *, unsigned *); 137 138 static void * create_decoder ( const struct PluginCodec_Definition *); 139 static void destroy_decoder ( const struct PluginCodec_Definition *, void * _context); 140 static int codec_decoder ( const struct PluginCodec_Definition *, void * _context, 141 const void * from, unsigned * fromLen, 142 void * to, unsigned * toLen, 143 unsigned int * flag); 144 static int decoder_get_output_data_size ( const PluginCodec_Definition * codec, void *, const char *, 145 void *, unsigned *); 146 147 /////////////////////////////////////////////////////////////////////////////// 148 149 150 static struct PluginCodec_information licenseInfo = { 151 1143692893, // timestamp = Thu 30 Mar 2006 04:28:13 AM UTC 152 153 "Matthias Schneider", // source code author 154 "1.0", // source code version 155 "ma30002000@yahoo.de", // source code email 156 "", // source code URL 157 "Copyright (C) 2007 by Matthias Schneider", // source code copyright 158 "MPL 1.0", // source code license 159 PluginCodec_License_MPL, // source code license 160 161 "libtheora", // codec description 162 "", // codec author 163 "1.0 alpha7", // codec version 164 "theora@xiph.org", // codec email 165 "http://www.theora.org/", // codec URL 166 "Xiph.Org Foundation http://www.xiph.org", // codec copyright information 167 "BSD-style", // codec license 168 PluginCodec_License_BSD // codec license code 169 }; 170 171 ///////////////////////////////////////////////////////////////////////////// 172 173 static const char YUV420PDesc[] = { "YUV420P" }; 174 static const char theoraDesc[] = { "theora" }; 175 static const char sdpTHEORA[] = { "theora" }; 176 #define THEORA_CLOCKRATE 90000 177 #define THEORA_BITRATE 768000 178 #define THEORA_PAYLOAD_SIZE 1400 179 #define THEORA_FRAME_RATE 25 180 #define THEORA_KEY_FRAME_INTERVAL 125 181 182 ///////////////////////////////////////////////////////////////////////////// 183 184 PLUGINCODEC_CONTROL_LOG_FUNCTION_DEF 185 186 static PluginCodec_ControlDefn EncoderControls[] = { 187 { PLUGINCODEC_CONTROL_VALID_FOR_PROTOCOL, valid_for_protocol }, 188 { PLUGINCODEC_CONTROL_GET_CODEC_OPTIONS, get_codec_options }, 189 { PLUGINCODEC_CONTROL_FREE_CODEC_OPTIONS, free_codec_options }, 190 { PLUGINCODEC_CONTROL_TO_NORMALISED_OPTIONS, to_normalised_options }, 191 { PLUGINCODEC_CONTROL_TO_CUSTOMISED_OPTIONS, to_customised_options }, 192 { PLUGINCODEC_CONTROL_SET_CODEC_OPTIONS, encoder_set_options }, 193 { PLUGINCODEC_CONTROL_GET_OUTPUT_DATA_SIZE, encoder_get_output_data_size }, 194 PLUGINCODEC_CONTROL_LOG_FUNCTION_INC 195 { NULL } 196 }; 197 198 static PluginCodec_ControlDefn DecoderControls[] = { 199 { PLUGINCODEC_CONTROL_GET_CODEC_OPTIONS, get_codec_options }, 200 { PLUGINCODEC_CONTROL_GET_OUTPUT_DATA_SIZE, decoder_get_output_data_size }, 201 { NULL } 202 }; 203 204 static struct PluginCodec_Option const samplingOption = 205 { PluginCodec_StringOption, "CAP Sampling", false, PluginCodec_EqualMerge, "YCbCr-4:2:0", "sampling", "YCbCr-4:2:0"}; 206 207 static struct PluginCodec_Option const widthOption = 208 { PluginCodec_IntegerOption, "CAP Width", false, PluginCodec_MinMerge, "704", "width", "15", 0, "15", "1280" }; 209 210 static struct PluginCodec_Option const heightOption = 211 { PluginCodec_IntegerOption, "CAP Height", false, PluginCodec_MinMerge, "576", "height", "15", 0, "15", "720" }; 212 213 static struct PluginCodec_Option const deliveryOption = 214 { PluginCodec_StringOption, "CAP Delivery", false, PluginCodec_EqualMerge, "in_band", "delivery-method", "in_band"}; 215 216 static struct PluginCodec_Option const minRxFrameWidth = 217 { PluginCodec_IntegerOption, PLUGINCODEC_OPTION_MIN_RX_FRAME_WIDTH, true, PluginCodec_NoMerge, "176", NULL, NULL, 0, "16", "1280" }; 218 static struct PluginCodec_Option const minRxFrameHeight = 219 { PluginCodec_IntegerOption, PLUGINCODEC_OPTION_MIN_RX_FRAME_HEIGHT, true, PluginCodec_NoMerge, "144", NULL, NULL, 0, "16", "720" }; 220 static struct PluginCodec_Option const maxRxFrameWidth = 221 { PluginCodec_IntegerOption, PLUGINCODEC_OPTION_MAX_RX_FRAME_WIDTH, true, PluginCodec_NoMerge, "1280", NULL, NULL, 0, "16", "1280" }; 222 static struct PluginCodec_Option const maxRxFrameHeight = 223 { PluginCodec_IntegerOption, PLUGINCODEC_OPTION_MAX_RX_FRAME_HEIGHT, true, PluginCodec_NoMerge, "720", NULL, NULL, 0, "16", "720" }; 224 225 226 //configuration 227 228 static struct PluginCodec_Option const * const optionTable[] = { 229 &samplingOption, 230 &widthOption, 231 &heightOption, 232 &deliveryOption, 233 &minRxFrameWidth, 234 &minRxFrameHeight, 235 &maxRxFrameWidth, 236 &maxRxFrameHeight, 237 NULL 238 }; 239 240 ///////////////////////////////////////////////////////////////////////////// 241 242 static struct PluginCodec_Definition theoraCodecDefn[2] = { 243 { 244 // SIP encoder#define NUM_DEFNS (sizeof(theoraCodecDefn) / sizeof(struct PluginCodec_Definition)) 245 PLUGIN_CODEC_VERSION_OPTIONS, // codec API version 246 &licenseInfo, // license information 247 248 PluginCodec_MediaTypeVideo | // audio codec 249 PluginCodec_RTPTypeShared | // specified RTP type 250 PluginCodec_RTPTypeDynamic, // specified RTP type 251 252 theoraDesc, // text decription 253 YUV420PDesc, // source format 254 theoraDesc, // destination format 255 256 optionTable, // user data 257 258 THEORA_CLOCKRATE, // samples per second 259 THEORA_BITRATE, // raw bits per second 260 20000, // nanoseconds per frame 261 262 {{ 263 CIF4_WIDTH, // frame width 264 CIF4_HEIGHT, // frame height 265 10, // recommended frame rate 266 60, // maximum frame rate 267 }}, 268 269 0, // IANA RTP payload code 270 sdpTHEORA, // RTP payload name 271 272 create_encoder, // create codec function 273 destroy_encoder, // destroy codec 274 codec_encoder, // encode/decode 275 EncoderControls, // codec controls 276 277 PluginCodec_H323Codec_NoH323, // h323CapabilityType 278 NULL // h323CapabilityData 279 }, 280 { 281 // SIP decoder 282 PLUGIN_CODEC_VERSION_OPTIONS, // codec API version 283 &licenseInfo, // license information 284 285 PluginCodec_MediaTypeVideo | // audio codec 286 PluginCodec_RTPTypeShared | // specified RTP type 287 PluginCodec_RTPTypeDynamic, // specified RTP type 288 289 theoraDesc, // text decription 290 theoraDesc, // source format 291 YUV420PDesc, // destination format 292 293 optionTable, // user data 294 295 THEORA_CLOCKRATE, // samples per second 296 THEORA_BITRATE, // raw bits per second 297 20000, // nanoseconds per frame 298 299 {{ 300 CIF4_WIDTH, // frame width 301 CIF4_HEIGHT, // frame height 302 10, // recommended frame rate 303 60, // maximum frame rate 304 }}, 305 0, // IANA RTP payload code 306 sdpTHEORA, // RTP payload name 307 308 create_decoder, // create codec function 309 destroy_decoder, // destroy codec 310 codec_decoder, // encode/decode 311 DecoderControls, // codec controls 312 313 PluginCodec_H323Codec_NoH323, // h323CapabilityType 314 NULL // h323CapabilityData 315 }, 316 }; 317 318 #endif /* __THEORA_H__ */ 319