[asterisk-commits] oej: branch oej/videocaps r47955 - in
/team/oej/videocaps: include/asterisk/ ...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Nov 23 03:04:27 MST 2006
Author: oej
Date: Thu Nov 23 04:04:26 2006
New Revision: 47955
URL: http://svn.digium.com/view/asterisk?view=rev&rev=47955
Log:
Formatting fixes, documentation corrections, additional information in doxygen
Modified:
team/oej/videocaps/include/asterisk/capability.h
team/oej/videocaps/main/capability.c
Modified: team/oej/videocaps/include/asterisk/capability.h
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/include/asterisk/capability.h?view=diff&rev=47955&r1=47954&r2=47955
==============================================================================
--- team/oej/videocaps/include/asterisk/capability.h (original)
+++ team/oej/videocaps/include/asterisk/capability.h Thu Nov 23 04:04:26 2006
@@ -19,8 +19,44 @@
/*! \file
* \brief General Asterisk PBX capability definitions.
* \par See also:
+ * \arg \ref AstVideoCaps
* \arg \ref Def_Channel
* \arg \ref channel_drivers
+ * \author John Martin, Aupix LTD
+ */
+
+/* \page AstVideoCaps Asterisk Video Capability Handling
+ * \title Asterisk video capabilities
+ *
+ * When setting up a video call, but also some audio calls, specifying the
+ * codec as the only capability is not enough. Therefore, we need to complement
+ * the codec negotiation with capabilities for each codec.
+ * For video, this is often format, framerate, bandwidth and variant.
+ * Some audio codecs have various bitrates and modes.
+ *
+ * In order to sort this out, you need to read each RFC with a specification
+ * of the SDP payload format as well as the actual specification of the codec.
+ *
+ * In order to handle this we need
+ * - Functions to parse configuration file settings for each codec
+ * - Function to compare settings during negotiation
+ * - Structures to store the settings
+ *
+ * In this file, we specify attributes structures to handle a range of video
+ * codecs
+ *
+ * - H.261
+ * - only handled in passthrough mode in Asterisk, no codec module
+ * - \ref format_h261.c
+ * - H.263
+ * - only handled in passthrough mode in Asterisk, no codec module
+ * - \ref format_h263.c
+ * - H.264
+ * - only handled in passthrough mode in Asterisk, no codec module
+ * - \ref format_h264.c
+ *
+ * In protocols that use SDP, the Session Description Protocol, we negotiate
+ * these attributes according to the SDP offer/answer model.
*/
#ifndef _ASTERISK_CAPABILITY_H
@@ -58,45 +94,45 @@
#define AST_VIDEO_XGA (9)
#define AST_VIDEO_CIF16 (10)
+#define MAX_VIDEO_SIZES 11
+
#define AST_VIDEO_LEVEL_BASELINE (1 << 0)
#define AST_VIDEO_LEVEL_MAIN (1 << 1)
#define AST_VIDEO_LEVEL_EXTENDED (1 << 2)
-#define MAX_VIDEO_SIZES 11
-
#define DEFAULT_MAX_CALL_BITRATE (256000) /*!< Max bitrate for video */
-// The profile level is the profile (eg 1.1 x 10)
+/*! The h.264 profile level is the profile (eg 1.1 x 10) */
typedef enum
{
- level_1 = 10, // 0x0A
- level_1_1 = 11, // 0x0B
- level_1_2 = 12, // 0x0C
- level_1_3 = 13, // 0x0D
- level_2 = 20, // 0x14
- level_2_1 = 21, // 0x15
- level_2_2 = 22, // 0x16
- level_3 = 30, // 0x1E
- level_3_1 = 31, // 0x1F
- level_3_2 = 32, // 0x20
- level_4 = 40, // 0x28
- level_4_1 = 41, // 0x29
- level_4_2 = 42, // 0x2A
- level_5 = 50, // 0x32
- level_5_1 = 51, // 0x33
+ level_1 = 10, /* 0x0A */
+ level_1_1 = 11, /* 0x0B */
+ level_1_2 = 12, /* 0x0C */
+ level_1_3 = 13, /* 0x0D */
+ level_2 = 20, /* 0x14 */
+ level_2_1 = 21, /* 0x15 */
+ level_2_2 = 22, /* 0x16 */
+ level_3 = 30, /* 0x1E */
+ level_3_1 = 31, /* 0x1F */
+ level_3_2 = 32, /* 0x20 */
+ level_4 = 40, /* 0x28 */
+ level_4_1 = 41, /* 0x29 */
+ level_4_2 = 42, /* 0x2A */
+ level_5 = 50, /* 0x32 */
+ level_5_1 = 51, /* 0x33 */
} ast_h264_profile_level;
-/* The following array defines the video sizes we know about */
-struct videoSize{
+/*!The following array defines the video sizes we know about */
+struct videoSize {
char* type;
unsigned int num_mbs;
unsigned char maxframerate;
};
-extern struct videoSize videoSizes[];
-extern struct ast_capabilities ast_default_caps;
-
-/*! \brief ast_video_cap: Struct holding video capabilities */
+extern struct videoSize videoSizes[]; /*! Declared in capability.c */
+extern struct ast_capabilities ast_default_caps; /*! Declared in capability.c */
+
+/*! \brief ast_video_cap: Struct holding video capabilities for h.261, h.263*/
struct ast_h2613_video_cap {
int valid; /*!< 1 = This codec is specified, 0 = not specified */
unsigned int annexes; /*!< Video annexes - stored as bitfield 2^(annex-ascii(A))*/
@@ -104,19 +140,19 @@
unsigned int maxbr; /*!< Maximum supported bitrate for this capability */
};
-/*! \brief ast_h264_video_cap: Struct holding video capabilities */
+/*! \brief ast_h264_video_cap: Struct holding video capabilities for h.264 */
struct ast_h264_video_cap {
unsigned char valid; /*!< 1 = This codec is specified, 0 = not specified */
- unsigned char rtpnum; /*!< The rtp number used in this cap */
+ unsigned char rtpnum; /*!< The rtp payload number used in this cap */
unsigned char profile; /*!< Video flags */
unsigned char level; /*!< Profile level */
- unsigned char constraint; /*!< Constraint flags */
+ unsigned char constraint; /*!< Constraint flags */
unsigned int maxmbps; /*!< Maximum number of macroblocks per second */
unsigned int packet_mode; /*!< Packetisation mode */
unsigned int maxbr; /*!< Maximum supported bitrate for this capability */
};
-/*! \brief ast_video_capabilities: Struct holding all video capabilities */
+/*! \brief ast_capabilities: Struct holding all video capabilities */
struct ast_capabilities {
unsigned int cap; /*!< Simple capability used to speed up search */
unsigned char prefs[32]; /*!< Audio preference order */
@@ -126,6 +162,7 @@
struct ast_h2613_video_cap h263; /*!< H263 video capabilities */
struct ast_h264_video_cap h264; /*!< H264 video capabilities */
unsigned char t140; /*!< T140 text capabilities */
+ struct ast_variable *x_settings; /*!< Settings outside of the specification received in SDP */
};
/*! \brief Set video capabilities of a channel
@@ -135,19 +172,33 @@
* \return Returns 0 on success, -1 on failure
*/
int ast_set_capabilities(struct ast_channel *chan, struct ast_capabilities *chancaps);
+
struct ast_capabilities *ast_alloc_capabilities(void);
+
void ast_dump_caps(struct ast_capabilities *caps);
+
void ast_dump_h2613_video_cap(struct ast_h2613_video_cap *vidcap);
+
void ast_dump_h264_video_cap(struct ast_h264_video_cap *vidcap);
+
void ast_resolve_h2613_video_cap(struct ast_h2613_video_cap *dstcap, struct ast_h2613_video_cap *s1cap, struct ast_h2613_video_cap *s2cap);
+
void ast_resolve_h264_video_cap(struct ast_h264_video_cap *dstcap, struct ast_h264_video_cap *s1cap, struct ast_h264_video_cap *s2cap);
+
int ast_copy_capabilities(struct ast_capabilities *dstcap, struct ast_capabilities *srccap);
+
int ast_resolve_capabilities(struct ast_capabilities *dst, struct ast_capabilities *s1caps, struct ast_capabilities *s2caps, int debug);
+
int ast_are_caps_zero(struct ast_capabilities *caps);
+
int ast_set_capabilities_from_int(struct ast_capabilities *caps, int simplecap);
+
int ast_get_int_from_capabilities(struct ast_capabilities *caps);
+
int check_set_video_bitrates(struct ast_capabilities *caps, int debug);
+
int parse_h2613_conf_line(const char *fmtstr, struct ast_h2613_video_cap *vidcap, unsigned int framerate);
+
int parse_h264_conf_line(const char *fmtstr, struct ast_h264_video_cap *vidcap, int framerate);
#if 0 /* Need to move these functions from rtp to here... */
Modified: team/oej/videocaps/main/capability.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/main/capability.c?view=diff&rev=47955&r1=47954&r2=47955
==============================================================================
--- team/oej/videocaps/main/capability.c (original)
+++ team/oej/videocaps/main/capability.c Thu Nov 23 04:04:26 2006
@@ -20,7 +20,7 @@
*
* \brief Capabilty Management
*
- * \author Mark Spencer <markster at digium.com>
+ * \author John Martin, Aupix
*/
#include "asterisk.h"
@@ -30,6 +30,7 @@
#include "asterisk/capability.h"
#include "asterisk/channel.h"
+/*! Definitions of common video sizes */
struct videoSize videoSizes[MAX_VIDEO_SIZES] = {
{"SQCIF", 48, 0},
{"QSIF", 75, 0},
@@ -44,18 +45,23 @@
{"CIF16", 6336, 0},
};
+/*! Default capabilities to start with */
struct ast_capabilities ast_default_caps =
{
0,
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
DEFAULT_MAX_CALL_BITRATE,
DEFAULT_MAX_CALL_BITRATE,
- {0, 0, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE},
- {0, 0, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE},
- {0, 0, 0x42, 0x0c, 0x80, 7128, 0, DEFAULT_MAX_CALL_BITRATE},
+ {0, 0, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE}, /* H.261 */
+ {0, 0, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE}, /* H.263 */
+ {0, 0, 0x42, 0x0c, 0x80, 7128, 0, DEFAULT_MAX_CALL_BITRATE}, /* H.264 */
0,
+ NULL, /* X-variables */
};
+/*! Allocate a capability structure
+ \note Need to make sure these are de-allocated */
+*/
struct ast_capabilities *ast_alloc_capabilities()
{
struct ast_capabilities *cap = ast_calloc(1, sizeof(struct ast_capabilities));
@@ -66,11 +72,10 @@
{
int res = 0;
- if ((caps->maxcallbitrate == 0) &&
- (caps->maxvideobitrate == 0) &&
+ if ((caps->maxcallbitrate == 0) && (caps->maxvideobitrate == 0) &&
(caps->h261.valid == 0) &&
(caps->h263.valid == 0))
- res = 1;
+ res = 1;
return res;
}
@@ -87,8 +92,7 @@
}
if (vidcap->annexes)
ast_verbose(" Annexes: 0x%08x\n",vidcap->annexes);
- }
- else
+ } else
ast_verbose("\n");
}
@@ -102,9 +106,8 @@
ast_verbose(" PMode %d\n", vidcap->packet_mode);
ast_verbose(" MaxBR: %dkbps\n", vidcap->maxbr/1000);
ast_verbose(" MaxMBPS: %d\n", vidcap->maxmbps);
- }
- else
- ast_verbose("\n");
+ } else
+ ast_verbose("\n");
}
void ast_dump_caps(struct ast_capabilities *caps)
@@ -131,11 +134,12 @@
int ast_copy_capabilities(struct ast_capabilities *dstcap, struct ast_capabilities *srccap)
{
memcpy(dstcap, srccap, sizeof(struct ast_capabilities));
+ /*! \todo Copy x-settings too */
return 0;
}
-/*! \brief Finds the highest common capability between the two source caps and applies it to the destination cap */
-/* Can be called with dst same as one of the src caps */
+/*! \brief Finds the highest common capability between the two source caps and applies it to the destination cap
+ * Can be called with dst same as one of the src caps */
void ast_resolve_h2613_video_cap(struct ast_h2613_video_cap *dstcap, struct ast_h2613_video_cap *s1cap, struct ast_h2613_video_cap *s2cap)
{
int i;
@@ -158,9 +162,10 @@
dstcap->annexes = s1cap->annexes & s2cap->annexes;
/* Resolve bitrates */
- dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
-
-}
+ dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
+
+}
+
/*! \brief Finds the highest common capability between the two source caps and applies it to the destination cap */
/* Can be called with dst same as one of the src caps */
void ast_resolve_h264_video_cap(struct ast_h264_video_cap *dstcap, struct ast_h264_video_cap *s1cap, struct ast_h264_video_cap *s2cap)
@@ -180,13 +185,13 @@
}
/* Resolve profiles */
- dstcap->profile = MIN(s1cap->profile, s2cap->profile);
+ dstcap->profile = MIN(s1cap->profile, s2cap->profile);
/* Resolve levels */
- dstcap->level = MIN(s1cap->level, s2cap->level);
+ dstcap->level = MIN(s1cap->level, s2cap->level);
/* Resolve constraints */
- dstcap->constraint = MIN(s1cap->constraint, s2cap->constraint);
+ dstcap->constraint = MIN(s1cap->constraint, s2cap->constraint);
/* Resolve bitrates */
- dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
+ dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
if (s1cap->rtpnum > 0)
dstcap->rtpnum = s1cap->rtpnum;
@@ -273,27 +278,25 @@
int maxh264 = caps->h264.valid ? caps->h264.maxbr : 0;
int maxmedia = MAX(maxh261, MAX(maxh263, maxh264));
- if(debug){
+ f(debug) {
ast_verbose ("CHECK SET BITRATES (IN): ct=%d, vbr=%d, h261=%d, h263=%d, h264=%d, maxmedia=%d\n",
maxctbr, maxvbr, maxh261, maxh263, maxh264, maxmedia);
}
/* Make sure ct and vbr are set to something sensible */
if (maxctbr) {
- if (maxvbr && maxvbr > maxctbr) {
- maxvbr = maxctbr;
- } else {
+ if (maxvbr && maxvbr > maxctbr)
+ maxvbr = maxctbr; /*!!!! JOHN, Something is wrong here !!!!! XXX */
+ else
maxvbr = maxctbr;
- }
- } else {
- if (maxvbr) {
+ } else {
+ if (maxvbr)
maxctbr = maxvbr;
- } else {
+ else
maxvbr = maxctbr = maxmedia;
- }
- }
-
- if (!maxvbr || !maxctbr) {
+ }
+
+ if (!maxvbr || !maxctbr) {
if(debug)
ast_verbose("CHECK SET BITRATES Haven't got any video bitrates set\n");
return -1;
@@ -313,7 +316,7 @@
caps->maxvideobitrate = maxvbr;
caps->maxcallbitrate = maxctbr;
- if(debug) {
+ if(debug) {
maxmedia = MAX(maxh261, MAX(maxh263, maxh264));
ast_verbose ("CHECK SET BITRATES (OUT): ct=%d, vbr=%d, h261=%d, h263=%d, h264=%d, maxmedia=%d\n",
@@ -323,7 +326,10 @@
return 0;
}
-/* Returns bitrate if found else -1 */
+/*! Parse configuration file item for H.261/H.263
+ \note syntax is as follows:
+ <Free space to fill in a syntax >
+ */
int parse_h2613_conf_line(const char *fmtstr, struct ast_h2613_video_cap *vidcap, unsigned int framerate)
{
char *parse, *loop_str, *equals, *value_str;
@@ -349,14 +355,13 @@
vidcap->maxbr = tmp*1000; /* Convert from *100 to *1 */
vidcap->valid = 1;
/* ast_verbose("MaxBR=%d\n", vidcap->maxbr); */
- }
- else
+ } else
ast_verbose("Failed to parse maxbr in process_h261_h261_fmtp()\n");
} else if (len == 1 && loop_str[0] >= 'A' && loop_str[0] <= 'Z') { /* this is an annex */
vidcap->annexes |= (1 << (loop_str[0] - 'A'));
found = 1;
ast_verbose("Found annex %c, we now have %08x\n", loop_str[0], vidcap->annexes);
- } else { /* Check video sizes */
+ } else { /* Check video sizes */
for (i = 0; i < MAX_VIDEO_SIZES; i++) {
if (strlen(videoSizes[i].type) == len && !strncasecmp(loop_str, videoSizes[i].type, len)) {
if (sscanf(value_str, "%d", &tmp)){
@@ -447,12 +452,30 @@
/* Work out picture sizes from supplied level */
switch (level) {
- case level_1 : level_maxbr = 64000; level_maxmbps = 1485; break;
- case level_1_1 : level_maxbr = 64000; level_maxmbps = 3000; break;
- case level_1_2 : level_maxbr = 128000; level_maxmbps = 6000; break;
- case level_1_3 : level_maxbr = 384000; level_maxmbps = 11880; break;
- case level_2 : level_maxbr = 768000; level_maxmbps = 11880; break;
- default : level_maxbr = 2000000; level_maxmbps = 11880; break;
+ case level_1 :
+ level_maxbr = 64000;
+ level_maxmbps = 1485;
+ break;
+ case level_1_1 :
+ level_maxbr = 64000;
+ level_maxmbps = 3000;
+ break;
+ case level_1_2 :
+ level_maxbr = 128000;
+ level_maxmbps = 6000;
+ break;
+ case level_1_3:
+ level_maxbr = 384000;
+ level_maxmbps = 11880;
+ break;
+ case level_2:
+ level_maxbr = 768000;
+ level_maxmbps = 11880;
+ break;
+ default:
+ level_maxbr = 2000000;
+ level_maxmbps = 11880;
+ break;
}
maxbr = maxbr * 1000;
More information about the asterisk-commits
mailing list