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;
105 unsigned m_headerSize;
106 unsigned m_payloadSize;
110 : m_packet((unsigned char *)packet)
113 , m_payloadSize(size - m_headerSize)
118 __inline
unsigned 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) }
312 static size_t const LastMaxVideoResolutions =
sizeof(MaxVideoResolutions)/
sizeof(MaxVideoResolutions[0]) - 1;
316 if (maxFrameSize > 0) {
317 static unsigned const MinWidth = 4*16;
318 static unsigned const MinHeight = 3*16;
320 unsigned maxWidth = maxFrameSize*16*16/MinHeight;
321 unsigned maxHeight = maxFrameSize*16*16/MinWidth;
325 if (macroBlocks <= maxFrameSize &&
326 width >= MinWidth && width <= maxWidth &&
327 height >= MinHeight && height <= maxHeight)
330 while (index < LastMaxVideoResolutions &&
331 (MaxVideoResolutions[index].m_macroblocks > maxFrameSize ||
332 MaxVideoResolutions[index].m_width > maxWidth ||
333 MaxVideoResolutions[index].m_height > maxHeight))
337 width = MaxVideoResolutions[index].m_width;
338 height = MaxVideoResolutions[index].m_height;
339 maxFrameSize = MaxVideoResolutions[index].m_macroblocks;
350 if (options != NULL) {
351 for (
const char *
const * option = *options; *option != NULL; option += 2)
352 insert(value_type(option[0], option[1]));
359 const_iterator it = find(key);
371 char ** options = (
char **)calloc(size()*2+1,
sizeof(
char *));
372 if (options == NULL) {
373 PTRACE(1,
"Plugin",
"Could not allocate new option lists.");
377 char ** opt = options;
378 for (const_iterator it = begin(); it != end(); ++it) {
379 *opt++ = strdup(it->first.c_str());
380 *opt++ = strdup(it->second.c_str());
388 template<
typename NAME>
408 const char * formatName,
409 const char * payloadName,
410 const char * description,
411 unsigned maxBandwidth,
452 if (parmLen == NULL || parm == NULL || *parmLen !=
sizeof(
char ***)) {
453 PTRACE(1,
"Plugin",
"Invalid parameters to AdjustOptions.");
457 OptionMap originalOptions((
const char *
const * *)parm);
459 if (!(this->*adjuster)(originalOptions, changedOptions)) {
460 PTRACE(1,
"Plugin",
"Could not normalise/customise options.");
464 return (*(
char ***)parm = changedOptions.
GetOptions()) != NULL;
507 template<
typename NAME>
522 const char * formatName,
523 const char * payloadName,
524 const char * description,
525 unsigned samplesPerFrame,
526 unsigned bytesPerFrame,
529 ) :
Parent(formatName, payloadName, description, bytesPerFrame*8 * samplesPerFrame*1000000/sampleRate, options)
552 template<
typename NAME>
564 const char * formatName,
565 const char * payloadName,
566 const char * description,
567 unsigned maxBandwidth,
569 ) :
Parent(formatName, payloadName, description, maxBandwidth, options)
586 template<
typename NAME>
594 ,
m_frameTime((defn->sampleRate/1000*defn->usPerFrame)/1000)
596 PTRACE(3,
"Plugin",
"Codec created: \"" << defn->
descr
625 virtual bool Transcode(
const void * fromPtr,
629 unsigned & flags) = 0;
671 for (
const char *
const * option = options; *option != NULL; option += 2) {
672 if (!this->
SetOption(option[0], option[1])) {
673 PTRACE(1,
"Plugin",
"Could not set option \"" << option[0] <<
"\" to \"" << option[1] <<
'"');
693 virtual bool SetOption(
const char * optionName,
const char * optionValue)
706 template <
typename T>
707 bool SetOptionUnsigned(T & oldValue,
const char * optionValue,
unsigned minimum,
unsigned maximum = UINT_MAX)
709 unsigned newValue = oldValue;
712 oldValue = (T)newValue;
717 bool SetOptionUnsigned(
unsigned & oldValue,
const char * optionValue,
unsigned minimum,
unsigned maximum = UINT_MAX)
720 unsigned newValue = strtoul(optionValue, &end, 10);
724 if (newValue < minimum)
726 else if (newValue > maximum)
729 if (oldValue != newValue) {
738 template <
typename T>
741 bool opt = oldValue != 0;
752 if ( strcasecmp(optionValue,
"0") == 0 ||
753 strcasecmp(optionValue,
"n") == 0 ||
754 strcasecmp(optionValue,
"f") == 0 ||
755 strcasecmp(optionValue,
"no") == 0 ||
756 strcasecmp(optionValue,
"false") == 0)
758 else if (strcasecmp(optionValue,
"1") == 0 ||
759 strcasecmp(optionValue,
"y") == 0 ||
760 strcasecmp(optionValue,
"t") == 0 ||
761 strcasecmp(optionValue,
"yes") == 0 ||
762 strcasecmp(optionValue,
"true") == 0)
767 if (oldValue != newValue) {
776 bool SetOptionBit(
int & oldValue,
unsigned bit,
const char * optionValue)
778 return this->
SetOptionBit((
unsigned &)oldValue, bit, optionValue);
782 bool SetOptionBit(
unsigned & oldValue,
unsigned bit,
const char * optionValue)
785 if (strcmp(optionValue,
"0") == 0)
787 else if (strcmp(optionValue,
"1") == 0)
792 if (((oldValue&bit) != 0) != newValue) {
806 CodecClass * codec =
new CodecClass(defn);
807 if (codec != NULL && codec->Construct())
810 PTRACE(1,
"Plugin",
"Could not open codec, no context being returned.");
824 const void * fromPtr,
828 unsigned int * flags)
830 if (context != NULL && fromPtr != NULL && fromLen != NULL && toPtr != NULL && toLen != NULL && flags != NULL)
831 return ((
PluginCodec *)context)->Transcode(fromPtr, *fromLen, toPtr, *toLen, *flags);
833 PTRACE(1,
"Plugin",
"Invalid parameter to Transcode.");
840 return context != NULL ? ((
PluginCodec *)context)->GetOutputDataSize() : 0;
859 if (context == NULL || parmLen == NULL || parm == NULL || *parmLen !=
sizeof(
char ***)) {
860 PTRACE(1,
"Plugin",
"Invalid parameters to GetActiveOptions.");
868 return (*(
char ***)parm = activeOptions.
GetOptions()) != NULL;
874 if (parm == NULL || len == NULL || *len !=
sizeof(
char ***))
877 char ** strings = (
char **)parm;
878 for (
char **
string = strings; *
string != NULL;
string++)
899 return len != NULL && *len ==
sizeof(
const char **) && parm != NULL &&
900 codec != NULL && codec->
SetOptions((
const char *
const *)parm);
905 return len != NULL && *len ==
sizeof(
const char *) && parm != NULL && defn->
userData != NULL &&
912 return len != NULL && parm != NULL &&
913 codec != NULL && codec->
SetInstanceID((
const char *)parm, *len);
919 return len != NULL && parm != NULL &&
926 return codec != NULL && codec->
Terminate();
946 return ControlsTable;
960 template<
typename NAME>
982 return width*height*3/2;
989 template<
typename NAME>
1013 virtual bool SetOption(
const char * optionName,
const char * optionValue)
1058 template<
typename NAME>
1092 videoHeader->
width = width;
1093 videoHeader->
height = height;
1111 for (
unsigned y = 0; y <
m_height; ++y) {
1119 virtual unsigned OutputImage(
unsigned char * planes[3],
int raster[3],
1120 unsigned width,
unsigned height,
PluginCodec_RTP & rtp,
unsigned & flags)
1125 size_t ySize = width*height;
1126 size_t uvSize = ySize/4;
1127 if (planes[1] == planes[0]+ySize && planes[2] == planes[1]+uvSize)
1132 { width/2, height/2, raster[1], planes[1], planeInfo[0].
m_destination + ySize },
1133 { width/2, height/2, raster[2], planes[2], planeInfo[1].
m_destination + uvSize }
1136 for (
unsigned plane = 0; plane < 3; ++plane)
1137 planeInfo[plane].Copy();
1148 #define PLUGINCODEC_AUDIO_CODEC_CXX(MediaFormat, \
1152 PLUGINCODEC_CODEC_PAIR(MediaFormat.GetFormatName(), \
1153 MediaFormat.GetPayloadName(), \
1154 MediaFormat.GetDescription(), \
1155 MediaFormat.GetSampleRate(), \
1156 MediaFormat.GetMaxBandwidth(), \
1157 MediaFormat.GetFrameTime(), \
1158 MediaFormat.GetSamplesPerFrame(), \
1159 MediaFormat.GetBytesPerFrame(), \
1160 MediaFormat.GetRecommendedFramesPerPacket(), \
1161 MediaFormat.GetMaxFramesPerPacket(), \
1162 MediaFormat.GetPayloadType(), \
1163 MediaFormat.GetH323CapabilityType(), \
1164 MediaFormat.GetH323CapabilityData(), \
1165 EncoderClass::Create_s<EncoderClass>, \
1166 EncoderClass::Destroy_s, \
1167 EncoderClass::Transcode_s, \
1168 DecoderClass::Create_s<DecoderClass>, \
1169 DecoderClass::Destroy_s, \
1170 DecoderClass::Transcode_s, \
1171 DecoderClass::GetControls(), \
1172 MediaFormat.GetFlags(), \
1173 PLUGINCODEC_RAW_AUDIO, \
1177 #define PLUGINCODEC_VIDEO_CODEC_CXX(MediaFormat, \
1181 PLUGINCODEC_CODEC_PAIR(MediaFormat.GetFormatName(), \
1182 MediaFormat.GetPayloadName(), \
1183 MediaFormat.GetDescription(), \
1184 PLUGINCODEC_VIDEO_CLOCK, \
1185 MediaFormat.GetMaxBandwidth(), \
1186 1000000/PLUGINCODEC_MAX_FRAME_RATE, \
1187 MediaFormat.GetMaxWidth(), \
1188 MediaFormat.GetMaxHeight(), \
1189 0,PLUGINCODEC_MAX_FRAME_RATE, \
1190 MediaFormat.GetPayloadType(), \
1191 MediaFormat.GetH323CapabilityType(), \
1192 MediaFormat.GetH323CapabilityData(), \
1193 EncoderClass::Create_s<EncoderClass>, \
1194 EncoderClass::Destroy_s, \
1195 EncoderClass::Transcode_s, \
1196 DecoderClass::Create_s<DecoderClass>, \
1197 DecoderClass::Destroy_s, \
1198 DecoderClass::Transcode_s, \
1199 DecoderClass::GetControls(), \
1200 MediaFormat.GetFlags(), \
1201 PLUGINCODEC_RAW_VIDEO, \
1205 #define PLUGIN_CODEC_IMPLEMENT_CXX(NAME, table) \
1207 PLUGIN_CODEC_IMPLEMENT(NAME) \
1208 PLUGIN_CODEC_DLL_API struct PluginCodec_Definition * PLUGIN_CODEC_GET_CODEC_FN(unsigned * count, unsigned version) { \
1209 if (version < PLUGIN_CODEC_VERSION_OPTIONS) return NULL; \
1210 *count = sizeof(table)/sizeof(struct PluginCodec_Definition); \
1211 PluginCodec_MediaFormat<NAME>::AdjustAllForVersion(version, table, *count); \
1217 #endif // OPAL_CODEC_OPALPLUGIN_HPP