39 #ifndef OPAL_CODEC_OPALPLUGIN_HPP 
   40 #define OPAL_CODEC_OPALPLUGIN_HPP 
   54 #ifndef PLUGINCODEC_TRACING 
   55   #define PLUGINCODEC_TRACING 1 
   58 #if PLUGINCODEC_TRACING 
   62 #define PLUGINCODEC_CONTROL_LOG_FUNCTION_DEF \ 
   63   PluginCodec_LogFunction PluginCodec_LogFunctionInstance; \ 
   64   int PluginCodec_SetLogFunction(const PluginCodec_Definition *, void *, const char *, void * parm, unsigned * len) \ 
   66     if (len == NULL || *len != sizeof(PluginCodec_LogFunction)) \ 
   69     PluginCodec_LogFunctionInstance = (PluginCodec_LogFunction)parm; \ 
   70     if (PluginCodec_LogFunctionInstance != NULL) \ 
   71       PluginCodec_LogFunctionInstance(4, __FILE__, __LINE__, "Plugin", "Started logging."); \ 
   76   #define PLUGINCODEC_CONTROL_LOG_FUNCTION_INC { PLUGINCODEC_CONTROL_SET_LOG_FUNCTION, PluginCodec_SetLogFunction }, 
   78   #define PLUGINCODEC_CONTROL_LOG_FUNCTION_DEF 
   79   #define PLUGINCODEC_CONTROL_LOG_FUNCTION_INC 
   83   #if PLUGINCODEC_TRACING 
   85     #define PTRACE_CHECK(level) \ 
   86         (PluginCodec_LogFunctionInstance != NULL && PluginCodec_LogFunctionInstance(level, NULL, 0, NULL, NULL)) 
   87     #define PTRACE(level, section, args) \ 
   88       if (PTRACE_CHECK(level)) { \ 
   89         std::ostringstream strm; strm << args; \ 
   90         PluginCodec_LogFunctionInstance(level, __FILE__, __LINE__, section, strm.str().c_str()); \ 
   93     #define PTRACE_CHECK(level) 
   94     #define PTRACE(level, section, expr) 
  103     unsigned char * m_packet;
 
  106     size_t          m_payloadSize;
 
  110       : m_packet((unsigned char *)packet)
 
  113       , m_payloadSize(size - m_headerSize)
 
  118     __inline 
size_t GetPacketSize()
 const        { 
return m_headerSize+m_payloadSize; }
 
  123       if (m_headerSize+size > m_maxSize)
 
  125       m_payloadSize = size;
 
  156           *ptr++ = (
unsigned char)(((
id&0xf) << 4)|(len-1));
 
  163           *ptr++ = (
unsigned char)(
id&0xff);
 
  164           *ptr++ = (
unsigned char)(len&0xff);
 
  173       if ((m_packet[0]&0x10) == 0)
 
  180         id = (0x10000|(ptr[4] >> 4));
 
  181         len = (ptr[4] & 0xf)+1;
 
  185       if ((
id&0xfff0) == 0x1000) {
 
  186         id = 0x20000 | ptr[4];
 
  195     __inline 
unsigned char * 
GetPayloadPtr()
 const   { 
return m_packet + m_headerSize; }
 
  196     __inline 
unsigned char & 
operator[](
size_t offset) { 
return m_packet[m_headerSize + offset]; }
 
  197     __inline 
unsigned const char & 
operator[](
size_t offset)
 const { 
return m_packet[m_headerSize + offset]; }
 
  198     __inline 
bool CopyPayload(
const void * data, 
size_t size, 
size_t offset = 0)
 
  220       return strtoul(str.c_str(), NULL, 10);
 
  229       str += (char)(value%10 + 
'0');
 
  245       PluginCodec_OptionMapBase::iterator it = original.find(option);
 
  246       if (it != original.end() && it->second != value)
 
  247         changed[option] = value;
 
  265                          bool forceIfZero = 
false)
 
  268       if (value > maximum || (forceIfZero && value == 0))
 
  286       return ((width+15)/16) * ((height+15)/16);
 
  293       unsigned & maxFrameSize)
 
  298         unsigned m_macroblocks;
 
  299       } MaxVideoResolutions[] = {
 
  300         #define OPAL_PLUGIN_CLAMPED_RESOLUTION(width, height) { width, height, ((width+15)/16) * ((height+15)/16) } 
  320       static size_t const LastMaxVideoResolutions = 
sizeof(MaxVideoResolutions)/
sizeof(MaxVideoResolutions[0]) - 1;
 
  324       if (maxFrameSize > 0) {
 
  325         static unsigned const MinWidth = 4*16;  
 
  326         static unsigned const MinHeight = 3*16; 
 
  328         unsigned maxWidth  = maxFrameSize*16*16/MinHeight;
 
  329         unsigned maxHeight = maxFrameSize*16*16/MinWidth;
 
  333         if (macroBlocks <= maxFrameSize &&
 
  334             width  >= MinWidth  && width  <= maxWidth &&
 
  335             height >= MinHeight && height <= maxHeight)
 
  338         while (index < LastMaxVideoResolutions &&
 
  339                 (MaxVideoResolutions[index].m_macroblocks > maxFrameSize ||
 
  340                 MaxVideoResolutions[index].m_width > maxWidth ||
 
  341                 MaxVideoResolutions[index].m_height > maxHeight))
 
  345       PTRACE(4, 
"Plugin", 
"ClampResolution: idx=" << index << 
' ' 
  346              << width << 
'x' << height << 
" > " << maxFrameSize << 
"mb reduced to " 
  347              << MaxVideoResolutions[index].m_width << 
'x' << MaxVideoResolutions[index].m_height
 
  348              << 
'=' << MaxVideoResolutions[index].m_macroblocks << 
"mb");
 
  349       width = MaxVideoResolutions[index].m_width;
 
  350       height = MaxVideoResolutions[index].m_height;
 
  351       maxFrameSize = MaxVideoResolutions[index].m_macroblocks;
 
  360       unsigned & maxMacroBlocks,
 
  372       ClampMax(maxWidth,  original, changed, widthKey);
 
  373       ClampMax(maxHeight, original, changed, heightKey);
 
  374       ClampMax(maxWidth,  original, changed, maxWidthKey);
 
  375       ClampMax(maxHeight, original, changed, maxHeightKey);
 
  376       ClampMax(maxWidth,  original, changed, minWidthKey);
 
  377       ClampMax(maxHeight, original, changed, minHeightKey);
 
  388       if (options != NULL) {
 
  389         for (
const char * 
const * option = *options; *option != NULL; option += 2)
 
  390           insert(value_type(option[0], option[1]));
 
  397       const_iterator it = find(key);
 
  409       char ** options = (
char **)calloc(size()*2+1, 
sizeof(
char *));
 
  410       if (options == NULL) {
 
  411         PTRACE(1, 
"Plugin", 
"Could not allocate new option lists.");
 
  415       char ** opt = options;
 
  416       for (const_iterator it = begin(); it != end(); ++it) {
 
  417         *opt++ = strdup(it->first.c_str());
 
  418         *opt++ = strdup(it->second.c_str());
 
  426 template<
typename NAME>
 
  447         const char * rawFormat,
 
  448         const char * formatName,
 
  449         const char * payloadName,
 
  450         const char * description,
 
  451         unsigned     maxBandwidth,
 
  495       if (parmLen == NULL || parm == NULL || *parmLen != 
sizeof(
char ***)) {
 
  496         PTRACE(1, 
"Plugin", 
"Invalid parameters to AdjustOptions.");
 
  500       OptionMap originalOptions((
const char * 
const * *)parm);
 
  502       if (!(this->*adjuster)(originalOptions, changedOptions)) {
 
  503         PTRACE(1, 
"Plugin", 
"Could not normalise/customise options.");
 
  507       return (*(
char ***)parm = changedOptions.
GetOptions()) != NULL;
 
  542 template<
typename NAME>
 
  558       const char * formatName,
 
  559       const char * payloadName,
 
  560       const char * description,
 
  561       unsigned     samplesPerFrame,
 
  562       unsigned     bytesPerFrame,
 
  563       unsigned     sampleRate = 8000,
 
  565     ) : 
Parent(
PLUGINCODEC_RAW_AUDIO, formatName, payloadName, description, bytesPerFrame*8 * samplesPerFrame*1000000/sampleRate, options)
 
  594 template<
typename NAME>
 
  607       const char * formatName,
 
  608       const char * payloadName,
 
  609       const char * description,
 
  610       unsigned     maxBandwidth,
 
  633 template<
typename NAME>
 
  640       , 
m_maxBitRate(defn->bitsPerSec > 0 ? defn->bitsPerSec : 4*1024*1024)
 
  641       , 
m_frameTime((defn->sampleRate/1000*defn->usPerFrame)/1000) 
 
  643       PTRACE(3, 
"Plugin", 
"Codec created: \"" << defn->
descr 
  672     virtual bool Transcode(
const void * fromPtr,
 
  676                              unsigned & flags) = 0;
 
  718       for (
const char * 
const * option = options; *option != NULL; option += 2) {
 
  719         if (!this->
SetOption(option[0], option[1])) {
 
  720           PTRACE(1, 
"Plugin", 
"Could not set option \"" << option[0] << 
"\" to \"" << option[1] << 
'"');
 
  740     virtual bool SetOption(
const char * optionName, 
const char * optionValue)
 
  761     template <
typename T>
 
  762     bool SetOptionUnsigned(T & oldValue, 
const char * optionValue, 
unsigned minimum, 
unsigned maximum = UINT_MAX)
 
  764       unsigned newValue = oldValue;
 
  767       oldValue = (T)newValue;
 
  772     bool SetOptionUnsigned(
unsigned & oldValue, 
const char * optionValue, 
unsigned minimum, 
unsigned maximum = UINT_MAX)
 
  775       unsigned newValue = strtoul(optionValue, &end, 10);
 
  779       if (newValue < minimum)
 
  781       else if (newValue > maximum)
 
  784       if (oldValue != newValue) {
 
  793     template <
typename T>
 
  796       bool opt = oldValue != 0;
 
  807       if (     strcasecmp(optionValue, 
"0") == 0 ||
 
  808                strcasecmp(optionValue, 
"n") == 0 ||
 
  809                strcasecmp(optionValue, 
"f") == 0 ||
 
  810                strcasecmp(optionValue, 
"no") == 0 ||
 
  811                strcasecmp(optionValue, 
"false") == 0)
 
  813       else if (strcasecmp(optionValue, 
"1") == 0 ||
 
  814                strcasecmp(optionValue, 
"y") == 0 ||
 
  815                strcasecmp(optionValue, 
"t") == 0 ||
 
  816                strcasecmp(optionValue, 
"yes") == 0 ||
 
  817                strcasecmp(optionValue, 
"true") == 0)
 
  822       if (oldValue != newValue) {
 
  831     bool SetOptionBit(
int & oldValue, 
unsigned bit, 
const char * optionValue)
 
  833       return this->
SetOptionBit((
unsigned &)oldValue, bit, optionValue);
 
  837     bool SetOptionBit(
unsigned & oldValue, 
unsigned bit, 
const char * optionValue)
 
  840       if (strcmp(optionValue, 
"0") == 0)
 
  842       else if (strcmp(optionValue, 
"1") == 0)
 
  847       if (((oldValue&bit) != 0) != newValue) {
 
  861       CodecClass * codec = 
new CodecClass(defn);
 
  862       if (codec != NULL && codec->Construct())
 
  865       PTRACE(1, 
"Plugin", 
"Could not open codec, no context being returned.");
 
  879                                              const void * fromPtr,
 
  883                                            unsigned int * flags)
 
  885       if (context != NULL && fromPtr != NULL && fromLen != NULL && toPtr != NULL && toLen != NULL && flags != NULL)
 
  886         return ((
PluginCodec *)context)->Transcode(fromPtr, *fromLen, toPtr, *toLen, *flags);
 
  888       PTRACE(1, 
"Plugin", 
"Invalid parameter to Transcode.");
 
  914       if (context == NULL || parmLen == NULL || parm == NULL || *parmLen != 
sizeof(
char ***)) {
 
  915         PTRACE(1, 
"Plugin", 
"Invalid parameters to GetActiveOptions.");
 
  923       return (*(
char ***)parm = activeOptions.
GetOptions()) != NULL;
 
  929       if (parm == NULL || len == NULL || *len != 
sizeof(
char ***))
 
  932       char ** strings = (
char **)parm;
 
  933       for (
char ** 
string = strings; *
string != NULL; 
string++)
 
  954       return len != NULL && *len == 
sizeof(
const char **) && parm != NULL &&
 
  955              codec != NULL && codec->
SetOptions((
const char * 
const *)parm);
 
  960       return len != NULL && *len == 
sizeof(
const char *) && parm != NULL && defn->
userData != NULL &&
 
  967       return len != NULL && parm != NULL &&
 
  968              codec != NULL && codec->
SetInstanceID((
const char *)parm, *len);
 
  974       return len != NULL && parm != NULL &&
 
  981       return codec != NULL && codec->
Terminate();
 
 1001       return ControlsTable;
 
 1015 template<
typename NAME>
 
 1045       return width*height*3/2; 
 
 1058 template<
typename NAME>
 
 1078     virtual bool SetOption(
const char * optionName, 
const char * optionValue)
 
 1123 template<
typename NAME>
 
 1139     virtual bool SetOption(
const char * optionName, 
const char * optionValue)
 
 1160       if (width == 0 || height == 0)
 
 1173       videoHeader->
width = width;
 
 1174       videoHeader->
height = height;
 
 1192         for (
unsigned y = 0; y < 
m_height; ++y) {
 
 1200     virtual unsigned OutputImage(
unsigned char * planes[3], 
int raster[3],
 
 1201                                  unsigned width, 
unsigned height, 
PluginCodec_RTP & rtp, 
unsigned & flags)
 
 1206       size_t ySize = width*height;
 
 1207       size_t uvSize = ySize/4;
 
 1208       if (planes[1] == planes[0]+ySize && planes[2] == planes[1]+uvSize)
 
 1213           { width/2, height/2, raster[1], planes[1], planeInfo[0].
m_destination + ySize  },
 
 1214           { width/2, height/2, raster[2], planes[2], planeInfo[1].
m_destination + uvSize }
 
 1217         for (
unsigned plane = 0; plane < 3; ++plane)
 
 1218           planeInfo[plane].Copy();
 
 1229 #define PLUGINCODEC_KNOWN_CODEC_CXX(MediaType,        \ 
 1235              PLUGINCODEC_CODEC_PAIR(Name, \ 
 1248                                     EncoderClass::Create_s<EncoderClass>, \ 
 1249                                     EncoderClass::Destroy_s, \ 
 1250                                     EncoderClass::Transcode_s, \ 
 1251                                     DecoderClass::Create_s<DecoderClass>, \ 
 1252                                     DecoderClass::Destroy_s, \ 
 1253                                     DecoderClass::Transcode_s, \ 
 1254                                     DecoderClass::GetControls(),  \ 
 1255                                     PluginCodec_MediaTypeKnown, \ 
 1256                                     PLUGINCODEC_RAW_##MediaType, \ 
 1260 #define PLUGINCODEC_AUDIO_CODEC_CXX(MediaFormat,      \ 
 1264              PLUGINCODEC_CODEC_PAIR(MediaFormat.GetFormatName(), \ 
 1265                                     MediaFormat.GetPayloadName(), \ 
 1266                                     MediaFormat.GetDescription(), \ 
 1267                                     MediaFormat.GetSampleRate(), \ 
 1268                                     MediaFormat.GetMaxBandwidth(), \ 
 1269                                     MediaFormat.GetFrameTime(), \ 
 1270                                     MediaFormat.GetSamplesPerFrame(), \ 
 1271                                     MediaFormat.GetBytesPerFrame(), \ 
 1272                                     MediaFormat.GetRecommendedFramesPerPacket(), \ 
 1273                                     MediaFormat.GetMaxFramesPerPacket(), \ 
 1274                                     MediaFormat.GetPayloadType(), \ 
 1275                                     MediaFormat.GetH323CapabilityType(), \ 
 1276                                     MediaFormat.GetH323CapabilityData(), \ 
 1277                                     EncoderClass::Create_s<EncoderClass>, \ 
 1278                                     EncoderClass::Destroy_s, \ 
 1279                                     EncoderClass::Transcode_s, \ 
 1280                                     DecoderClass::Create_s<DecoderClass>, \ 
 1281                                     DecoderClass::Destroy_s, \ 
 1282                                     DecoderClass::Transcode_s, \ 
 1283                                     DecoderClass::GetControls(),  \ 
 1284                                     MediaFormat.GetFlags(), \ 
 1285                                     MediaFormat.GetRawFormat(), \ 
 1289 #define PLUGINCODEC_VIDEO_CODEC_CXX(MediaFormat,      \ 
 1293              PLUGINCODEC_CODEC_PAIR(MediaFormat.GetFormatName(), \ 
 1294                                     MediaFormat.GetPayloadName(), \ 
 1295                                     MediaFormat.GetDescription(), \ 
 1296                                     PLUGINCODEC_VIDEO_CLOCK, \ 
 1297                                     MediaFormat.GetMaxBandwidth(), \ 
 1298                                     1000000/PLUGINCODEC_MAX_FRAME_RATE, \ 
 1299                                     MediaFormat.GetMaxWidth(), \ 
 1300                                     MediaFormat.GetMaxHeight(), \ 
 1301                                     0,PLUGINCODEC_MAX_FRAME_RATE, \ 
 1302                                     MediaFormat.GetPayloadType(), \ 
 1303                                     MediaFormat.GetH323CapabilityType(), \ 
 1304                                     MediaFormat.GetH323CapabilityData(), \ 
 1305                                     EncoderClass::Create_s<EncoderClass>, \ 
 1306                                     EncoderClass::Destroy_s, \ 
 1307                                     EncoderClass::Transcode_s, \ 
 1308                                     DecoderClass::Create_s<DecoderClass>, \ 
 1309                                     DecoderClass::Destroy_s, \ 
 1310                                     DecoderClass::Transcode_s, \ 
 1311                                     DecoderClass::GetControls(),  \ 
 1312                                     MediaFormat.GetFlags(), \ 
 1313                                     MediaFormat.GetRawFormat(), \ 
 1317 #define PLUGIN_CODEC_IMPLEMENT_CXX(NAME, table) \ 
 1319     PLUGIN_CODEC_IMPLEMENT(NAME) \ 
 1320     PLUGIN_CODEC_DLL_API struct PluginCodec_Definition * PLUGIN_CODEC_GET_CODEC_FN(unsigned * count, unsigned version) { \ 
 1321       if (version < PLUGIN_CODEC_VERSION_OPTIONS) return NULL; \ 
 1322       *count = sizeof(table)/sizeof(struct PluginCodec_Definition); \ 
 1323       PluginCodec_MediaFormat<NAME>::AdjustAllForVersion(version, table, *count); \ 
 1329 #endif // OPAL_CODEC_OPALPLUGIN_HPP