[asterisk-commits] oej: branch oej/videocaps r101195 - in /team/oej/videocaps: include/asterisk/...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jan 30 06:43:51 CST 2008
Author: oej
Date: Wed Jan 30 06:43:50 2008
New Revision: 101195
URL: http://svn.digium.com/view/asterisk?view=rev&rev=101195
Log:
Add missing files.
Added:
team/oej/videocaps/include/asterisk/capability.h (with props)
team/oej/videocaps/main/capability.c (with props)
Added: team/oej/videocaps/include/asterisk/capability.h
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/include/asterisk/capability.h?view=auto&rev=101195
==============================================================================
--- team/oej/videocaps/include/asterisk/capability.h (added)
+++ team/oej/videocaps/include/asterisk/capability.h Wed Jan 30 06:43:50 2008
@@ -1,0 +1,210 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \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
+#define _ASTERISK_CAPABILITY_H
+
+#include "asterisk/abstract_jb.h"
+
+#include <unistd.h>
+#ifdef POLLCOMPAT
+#include "asterisk/poll-compat.h"
+#else
+#include <sys/poll.h>
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "asterisk/compat.h"
+#include "asterisk/frame.h"
+#include "asterisk/config.h"
+#include "asterisk/utils.h"
+#include "asterisk/compiler.h"
+
+/* Defines */
+#define AST_VIDEO_SQCIF (0)
+#define AST_VIDEO_QSIF (1)
+#define AST_VIDEO_QCIF (2)
+#define AST_VIDEO_QVGA (3)
+#define AST_VIDEO_SIF (4)
+#define AST_VIDEO_CIF (5)
+#define AST_VIDEO_VGA (6)
+#define AST_VIDEO_CIF4 (7)
+#define AST_VIDEO_SVGA (8)
+#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 DEFAULT_MAX_CALL_BITRATE (256000) /*!< Max bitrate for video */
+
+/*! 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 */
+} ast_h264_profile_level;
+
+/*!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[]; /*!< 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))*/
+ unsigned char maxfr[MAX_VIDEO_SIZES]; /*!< Maximum framerate (framerate = 30/mpi) */
+ unsigned int maxbr; /*!< Maximum supported bitrate for this capability */
+};
+
+/*! \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 payload number used in this cap */
+ unsigned char profile; /*!< Video flags */
+ unsigned char level; /*!< Profile level */
+ 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_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 */
+ unsigned int maxcallbitrate; /*!< Max allowed bitrate for this channel */
+ unsigned int maxvideobitrate; /*!< Max video bitrate */
+ struct ast_h2613_video_cap h261; /*!< H261 video capabilities */
+ 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
+ * \note When videp caps need to be relayed to another part of call
+ * \param chan channel to change the indication
+ * \param capabilities
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_capabilities(struct ast_channel *chan, struct ast_capabilities *chancaps);
+
+/*! \brief Allocate capability structure for video */
+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 defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif /* _ASTERISK_CAPABILITY_H */
Propchange: team/oej/videocaps/include/asterisk/capability.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/videocaps/include/asterisk/capability.h
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/oej/videocaps/include/asterisk/capability.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/oej/videocaps/main/capability.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/main/capability.c?view=auto&rev=101195
==============================================================================
--- team/oej/videocaps/main/capability.c (added)
+++ team/oej/videocaps/main/capability.c Wed Jan 30 06:43:50 2008
@@ -1,0 +1,499 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Capabilty Management
+ *
+ * \author John Martin, Aupix
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#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},
+ {"QCIF", 99, 0},
+ {"QVGA", 300, 0},
+ {"SIF", 300, 0},
+ {"CIF", 396, 0},
+ {"VGA", 1200, 0},
+ {"CIF4", 1584, 0},
+ {"SVGA", 1875, 0},
+ {"XGA", 2304, 0},
+ {"CIF16", 6336, 0},
+};
+
+/*! \brief 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}, /* 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 */
+};
+
+/*! \brief 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));
+ return cap;
+}
+
+int ast_are_caps_zero(struct ast_capabilities *caps)
+{
+ int res = 0;
+
+ if ((caps->maxcallbitrate == 0) && (caps->maxvideobitrate == 0) &&
+ (caps->h261.valid == 0) &&
+ (caps->h263.valid == 0))
+ res = 1;
+
+ return res;
+}
+
+void ast_dump_h2613_video_cap(struct ast_h2613_video_cap *vidcap)
+{
+ int i;
+
+ if (vidcap->valid) {
+ ast_verbose(" MaxBR: %dkbps\n", vidcap->maxbr/1000);
+ for (i = 0; i < MAX_VIDEO_SIZES; i++) {
+ if (vidcap->maxfr[i] > 0)
+ ast_verbose(" %-11s %1dfps\n", videoSizes[i].type, vidcap->maxfr[i]);
+ }
+ if (vidcap->annexes)
+ ast_verbose(" Annexes: 0x%08x\n",vidcap->annexes);
+ } else
+ ast_verbose("\n");
+}
+
+void ast_dump_h264_video_cap(struct ast_h264_video_cap *vidcap)
+{
+ if (vidcap->valid) {
+ ast_verbose(" RTPnum: %03d\n",vidcap->rtpnum);
+ ast_verbose(" Profile: %02x\n",vidcap->profile);
+ ast_verbose(" Level: %02x\n",vidcap->level);
+ ast_verbose(" Constraint: %02x\n",vidcap->constraint);
+ 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");
+}
+
+void ast_dump_caps(struct ast_capabilities *caps)
+{
+ ast_verbose(" Bitrates:\n MaxCall %dkbps\n MaxVideo %dkbps\n", caps->maxcallbitrate/1000,caps->maxvideobitrate/1000);
+ if (caps->h261.valid) {
+ ast_verbose(" H261:\n");
+ ast_dump_h2613_video_cap(&caps->h261);
+ }
+ if (caps->h263.valid) {
+ ast_verbose(" H263:\n");
+ ast_dump_h2613_video_cap(&caps->h263);
+ }
+ if (caps->h264.valid) {
+ ast_verbose(" H264:\n");
+ ast_dump_h264_video_cap(&caps->h264);
+ }
+ /* if (caps->t140.valid) */
+ ast_verbose(" T140\n");
+
+ ast_verbose("\n");
+}
+
+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 */
+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;
+
+ /*... resolve valids */
+ if (s1cap->valid && s2cap->valid)
+ dstcap->valid = 1;
+ else {
+ dstcap->valid = 0;
+ memset(dstcap->maxfr, 0, sizeof(dstcap->maxfr[0]) * MAX_VIDEO_SIZES);
+ dstcap->maxbr = 0;
+ return;
+ }
+
+ /* Use the lowest frame rate even if zero */
+ for (i = 0; i < MAX_VIDEO_SIZES; i++)
+ dstcap->maxfr[i] = MIN(s1cap->maxfr[i], s2cap->maxfr[i]);
+
+ /* Union of annexes */
+ dstcap->annexes = s1cap->annexes & s2cap->annexes;
+
+ /* Resolve bitrates */
+ 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)
+{
+ /*... resolve valids */
+ if (s1cap->valid && s2cap->valid)
+ dstcap->valid = 1;
+ else {
+ dstcap->valid = 0;
+ dstcap->rtpnum = 0;
+ dstcap->profile = 0;
+ dstcap->constraint = 0;
+ dstcap->level = 0;
+ dstcap->maxbr = 0;
+ dstcap->maxmbps = 0;
+ return;
+ }
+
+ /* Resolve profiles */
+ dstcap->profile = MIN(s1cap->profile, s2cap->profile);
+ /* Resolve levels */
+ dstcap->level = MIN(s1cap->level, s2cap->level);
+ /* Resolve constraints */
+ dstcap->constraint = MIN(s1cap->constraint, s2cap->constraint);
+ /* Resolve bitrates */
+ dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
+
+ if (s1cap->rtpnum > 0)
+ dstcap->rtpnum = s1cap->rtpnum;
+ else if (s2cap->rtpnum > 0)
+ dstcap->rtpnum = s2cap->rtpnum;
+}
+
+/*! \brief ast_resolve_capabilities: called when we need to have dst = MIN(s1cap, s2cap), or in set theory terms s1cap INTERSECT s2cap (s1 n s2) */
+int ast_resolve_capabilities(struct ast_capabilities *dst, struct ast_capabilities *s1caps, struct ast_capabilities *s2caps, int debug)
+{
+ int res = 0;
+
+ if (debug) {
+ ast_verbose("\nResolve: Input Caps1:\n");
+ ast_dump_caps(s1caps);
+ ast_verbose("\nResolve: Input Caps2:\n");
+ ast_dump_caps(s2caps);
+ }
+
+ dst->maxcallbitrate = MIN(s1caps->maxcallbitrate, s2caps->maxcallbitrate);
+ dst->maxvideobitrate = MIN(s1caps->maxvideobitrate, s2caps->maxvideobitrate);
+ ast_resolve_h2613_video_cap(&dst->h261, &s1caps->h261, &s2caps->h261);
+ ast_resolve_h2613_video_cap(&dst->h263, &s1caps->h263, &s2caps->h263);
+ ast_resolve_h264_video_cap(&dst->h264, &s1caps->h264, &s2caps->h264);
+
+ if (debug) {
+ ast_verbose("\nResolve: Output Caps:\n");
+ ast_dump_caps(dst);
+ }
+
+ return res;
+}
+
+/*! \brief ast_set_capabilities_from_int: called when we need to make sure the complex caps are inline with old integer caps */
+int ast_set_capabilities_from_int(struct ast_capabilities *caps, int simplecap)
+{
+ caps->h261.valid = ((simplecap & AST_FORMAT_H261) == AST_FORMAT_H261) ? 1 : 0;
+ caps->h263.valid = ((simplecap & AST_FORMAT_H263) == AST_FORMAT_H263) ? 1 : 0;
+ caps->h264.valid = ((simplecap & AST_FORMAT_H264) == AST_FORMAT_H264) ? 1 : 0;
+
+ return 0;
+}
+
+/*! \brief ast_set_capabilities_from_int: called when we need to make sure the complex caps are inline with old integer caps */
+int ast_get_int_from_capabilities(struct ast_capabilities *caps)
+{
+ int res=0;
+
+ if (caps->h261.valid)
+ res |= AST_FORMAT_H261;
+
+ if (caps->h263.valid)
+ res |= AST_FORMAT_H263;
+
+ if (caps->h264.valid)
+ res |= AST_FORMAT_H264;
+
+ return 0;
+}
+
+int ast_set_capabilities(struct ast_channel *chan, struct ast_capabilities *chancaps)
+{
+ if (!chan)
+ return -1;
+
+ if (chan->tech->set_capabilities)
+ chan->tech->set_capabilities(chan, chancaps);
+
+ return 0;
+}
+
+/*! \brief Checks all the video bitrates to make sure they conform to the following:
+ enforce maxcallbitrate >= maxvideobitrate >= maxbr
+ This will be called when any bitrates can be set (incoming call, reload etc).
+ The maxcallbitrate will override everything
+ Callbitrate overides the media codec bitrates
+*/
+int check_set_video_bitrates(struct ast_capabilities *caps, int debug)
+{
+ int maxctbr = caps->maxcallbitrate;
+ int maxvbr = caps->maxvideobitrate;
+ int maxh261 = caps->h261.valid ? caps->h261.maxbr : 0;
+ int maxh263 = caps->h263.valid ? caps->h263.maxbr : 0;
+ int maxh264 = caps->h264.valid ? caps->h264.maxbr : 0;
+ int maxmedia = MAX(maxh261, MAX(maxh263, maxh264));
+
+ if(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; /*!!!! JOHN, Something is wrong here !!!!! XXX */
+ else
+ maxvbr = maxctbr;
+ } else {
+ if (maxvbr)
+ maxctbr = maxvbr;
+ else
+ maxvbr = maxctbr = maxmedia;
+ }
+
+ if (!maxvbr || !maxctbr) {
+ if(debug)
+ ast_verbose("CHECK SET BITRATES Haven't got any video bitrates set\n");
+ return -1;
+ }
+
+ /* Now make sure all codec bitrates are below the max permissible */
+ if (maxh264 > maxvbr)
+ maxh264 = maxvbr;
+ if (maxh263 > maxvbr)
+ maxh263 = maxvbr;
+ if (maxh261 > maxvbr)
+ maxh261 = maxvbr;
+
+ caps->h264.maxbr = maxh264;
+ caps->h263.maxbr = maxh263;
+ caps->h261.maxbr = maxh261;
+ caps->maxvideobitrate = maxvbr;
+ caps->maxcallbitrate = maxctbr;
+
+ 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",
+ maxctbr, maxvbr, maxh261, maxh263, maxh264, maxmedia);
+ }
+
+ return 0;
+}
+
+/*! 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;
+ char *sep = " ;:/,";
+ int len;
+ int i;
+ unsigned int tmp;
+ int found=0;
+
+ memset(vidcap, 0, sizeof(struct ast_h2613_video_cap));
+
+ parse = ast_strdupa(fmtstr);
+ /* Get the fmtp: and payload type out of the way */
+ for ((loop_str = strsep(&parse, sep)); loop_str; (loop_str = strsep(&parse, sep)) != NULL) {
+ if((equals = strchr(loop_str, '='))==NULL)
+ return -1;
+ found = 0;
+ len = equals - loop_str;
+ value_str = loop_str+len+1;
+ if (!strncasecmp(loop_str, "maxbr", len)){
+ if(sscanf(value_str, "%d", &tmp)) {
+ found = 1;
+ vidcap->maxbr = tmp*1000; /* Convert from *100 to *1 */
+ vidcap->valid = 1;
+ /* ast_verbose("MaxBR=%d\n", vidcap->maxbr); */
+ } 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 */
+ 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)){
+ found = 1;
+ /* vidcap->maxfr[i] = framerate < (30 / tmp) ? framerate : (30 /tmp); */
+ vidcap->maxfr[i] = (tmp > 30) ? 30 : (tmp < 0) ? 0 : tmp;
+ vidcap->valid = 1;
+ }
+ /* ast_verbose("%s->FR=%d, len=%d, string=%s\n", videoSizes[i].type, vidcap->maxfr[i], len, loop_str); */
+ }
+ }
+ }
+ if (!found)
+ ast_verbose("Unable to parse %s in fmtp\n", loop_str);
+ }
+
+ if (vidcap->valid && vidcap->maxbr)
+ return vidcap->maxbr;
+ else
+ return -1;
+}
+
+/*! \brief Returns 0 on success else -1 */
+int parse_h264_conf_line(const char *fmtstr, struct ast_h264_video_cap *vidcap, int framerate)
+{
+ char *parse, *loop_str, *equals, *value_str;
+ char *sep = " ;:/,";
+ int len;
+ struct videoSize myVideoSizes[MAX_VIDEO_SIZES];
+ int found=0;
+ int maxbr = 0;
+ int level_maxbr = 0;
+ int maxmbps = 0;
+ int level_maxmbps = 0;
+ int profile = 0;
+ int level = 0;
+ int constraint = 0;
+ int packetmode = 0;
+ int rtpnum=0;
+
+ /* "a=fmtp:%d profile-level-id=42800C; packetization-mode=0; max-br=384; max-mbps=7128\r\n" */
+
+ memcpy(myVideoSizes, videoSizes, sizeof(myVideoSizes));
+
+ parse = ast_strdupa(fmtstr);
+
+ /* Get the fmtp: and payload type out of the way */
+ for ((loop_str = strsep(&parse, sep)); loop_str; (loop_str = strsep(&parse, sep)) != NULL) {
+ if (loop_str[0] == '\0') {
+ loop_str++;
+ continue;
+ }
+ if((equals = strchr(loop_str, '='))==NULL)
+ return -1;
+ found = 0;
+ len = equals - loop_str;
+ value_str = loop_str+len+1;
+ /* Now check other parameters than can appear in a video fmtp */
+ if (!strncasecmp(loop_str, "max-br", len)) {
+ if(sscanf(value_str, "%d", &maxbr))
+ found = 1;
+ else
+ ast_verbose("Failed to parse max-br in process_h264_fmtp()\n");
+ } else if (!strncasecmp(loop_str, "max-mbps", len)) {
+ if(sscanf(value_str, "%d", &maxmbps))
+ found = 1;
+ else
+ ast_verbose("Failed to parse max-mbps in process_h264_fmtp()\n");
+ } else if (!strncasecmp(loop_str, "profile-level-id", len)) {
+ if(sscanf(value_str, "%02x%02x%02x", &profile, &constraint, &level))
+ found = 1;
+ else
+ ast_verbose("Failed to parse profile-level-id in process_h264_fmtp()\n");
+ } else if (!strncasecmp(loop_str, "packetization-mode", len)) {
+ if(sscanf(value_str, "%d", &packetmode))
+ found = 1;
+ else
+ ast_verbose("Failed to parse packetization-mode in process_h264_fmtp()\n");
+ } else if (!strncasecmp(loop_str, "rtpnum", len)) {
+ if(sscanf(value_str, "%d", &rtpnum))
+ found = 1;
+ else
+ ast_verbose("Failed to parse rtpnum in process_h264_fmtp()\n");
+ }
+ if (!found)
+ ast_verbose("Unable to parse %s in fmtp\n", loop_str);
+ }
+
+ /* 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;
+ }
+
+ maxbr = maxbr * 1000;
+
+ if (maxbr > level_maxbr)
+ vidcap->maxbr = maxbr;
+ else
+ vidcap->maxbr = level_maxbr;
+
+ if (maxmbps > level_maxmbps)
+ vidcap->maxmbps = maxmbps;
+ else
+ vidcap->maxmbps = level_maxmbps;
+
+ vidcap->profile = profile;
+ vidcap->level = level;
+ vidcap->constraint = constraint;
+ vidcap->valid = 1;
+ vidcap->rtpnum = rtpnum;
+
+ return 0;
+}
Propchange: team/oej/videocaps/main/capability.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/videocaps/main/capability.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Propchange: team/oej/videocaps/main/capability.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list