📄 mpeg4_sdp.c
字号:
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2000, 2001. All Rights Reserved.
*
* Contributor(s):
* Bill May wmay@cisco.com
*/
/*
* mpeg4_sdp.c - utilities for handling SDP structures
*/
#include "systems.h"
#include <sdp/sdp.h>
#include "mpeg4_sdp.h"
#define ADV_SPACE(a) {while (isspace(*(a)) && (*(a) != '\0'))(a)++;}
#define TTYPE(a,b) {a, sizeof(a), b}
#define FMTP_PARSE_FUNC(a) static char *(a) (char *ptr, \
fmtp_parse_t *fptr, \
lib_message_func_t message)
static char *fmtp_advance_to_next (char *ptr)
{
while (*ptr != '\0' && *ptr != ';') ptr++;
if (*ptr == ';') ptr++;
return (ptr);
}
static char *fmtp_parse_number (char *ptr, int *ret_value)
{
long int value;
char *ret_ptr;
value = strtol(ptr, &ret_ptr, 0);
if ((ret_ptr != NULL) &&
(*ret_ptr == ';' || *ret_ptr == '\0')) {
if (*ret_ptr == ';') ret_ptr++;
if (value > INT_MAX) value = INT_MAX;
if (value < INT_MIN) value = INT_MIN;
*ret_value = value;
return (ret_ptr);
}
return (NULL);
}
FMTP_PARSE_FUNC(fmtp_streamtype)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->stream_type);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_profile_level_id)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->profile_level_id);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
static unsigned char to_hex (char *ptr)
{
if (isdigit(*ptr)) {
return (*ptr - '0');
}
return (tolower(*ptr) - 'a' + 10);
}
FMTP_PARSE_FUNC(fmtp_config)
{
char *iptr;
uint32_t len;
unsigned char *bptr;
iptr = ptr;
while (isxdigit(*iptr)) iptr++;
len = iptr - ptr;
if (len == 0 || len & 0x1 || !(*iptr == ';' || *iptr == '\0')) {
message(LOG_ERR, "mp4util", "Error in fmtp config statement");
return (fmtp_advance_to_next(ptr));
}
iptr = fptr->config_ascii = (char *)malloc(len + 1);
len /= 2;
bptr = fptr->config_binary = (uint8_t *)malloc(len);
fptr->config_binary_len = len;
while (len > 0) {
*bptr++ = (to_hex(ptr) << 4) | (to_hex(ptr + 1));
*iptr++ = *ptr++;
*iptr++ = *ptr++;
len--;
}
*iptr = '\0';
if (*ptr == ';') ptr++;
return (ptr);
}
FMTP_PARSE_FUNC(fmtp_constant_size)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->constant_size);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_size_length)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->size_length);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_index_length)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->index_length);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_index_delta_length)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->index_delta_length);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_CTS_delta_length)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->CTS_delta_length);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_DTS_delta_length)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->DTS_delta_length);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_auxiliary_data_size_length)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->auxiliary_data_size_length);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_bitrate)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->bitrate);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_profile)
{
char *ret;
ret = fmtp_parse_number(ptr, &fptr->profile);
if (ret == NULL) {
ret = fmtp_advance_to_next(ptr);
}
return (ret);
}
FMTP_PARSE_FUNC(fmtp_mode)
{
return (fmtp_advance_to_next(ptr));
}
struct {
const char *name;
uint32_t namelen;
char *(*routine)(char *, fmtp_parse_t *, lib_message_func_t);
} fmtp_types[] =
{
TTYPE("streamtype", fmtp_streamtype),
TTYPE("profile-level-id", fmtp_profile_level_id),
TTYPE("config", fmtp_config),
TTYPE("constantsize", fmtp_constant_size),
TTYPE("sizelength", fmtp_size_length),
TTYPE("indexlength", fmtp_index_length),
TTYPE("indexdeltalength", fmtp_index_delta_length),
TTYPE("ctsdeltalength", fmtp_CTS_delta_length),
TTYPE("dtsdeltalength", fmtp_DTS_delta_length),
TTYPE("auxiliarydatasizelength", fmtp_auxiliary_data_size_length),
TTYPE("bitrate", fmtp_bitrate),
TTYPE("profile", fmtp_profile),
TTYPE("mode", fmtp_mode),
{NULL, 0, NULL},
};
fmtp_parse_t *parse_fmtp_for_mpeg4 (char *optr, lib_message_func_t message)
{
int ix;
char *bptr;
fmtp_parse_t *ptr;
bptr = optr;
if (bptr == NULL)
return (NULL);
ptr = (fmtp_parse_t *)malloc(sizeof(fmtp_parse_t));
if (ptr == NULL)
return (NULL);
ptr->config_binary = NULL;
ptr->config_ascii = NULL;
ptr->profile_level_id = -1;
ptr->constant_size = 0;
ptr->size_length = 0;
ptr->index_length = 0; // default value...
ptr->index_delta_length = 0;
ptr->CTS_delta_length = 0;
ptr->DTS_delta_length = 0;
ptr->auxiliary_data_size_length = 0;
ptr->bitrate = -1;
ptr->profile = -1;
do {
ADV_SPACE(bptr);
for (ix = 0; fmtp_types[ix].name != NULL; ix++) {
if (strncasecmp(bptr,
fmtp_types[ix].name,
fmtp_types[ix].namelen - 1) == 0) {
bptr += fmtp_types[ix].namelen - 1;
ADV_SPACE(bptr);
if (*bptr != '=') {
message(LOG_ERR, "mp4util", "No = in fmtp %s %s",
fmtp_types[ix].name,
optr);
bptr = fmtp_advance_to_next(bptr);
break;
}
bptr++;
ADV_SPACE(bptr);
bptr = (fmtp_types[ix].routine)(bptr, ptr, message);
break;
}
}
if (fmtp_types[ix].name == NULL) {
message(LOG_ERR, "mp4util", "Illegal name in bptr - skipping %s",
bptr);
bptr = fmtp_advance_to_next(bptr);
}
} while (bptr != NULL && *bptr != '\0');
if (bptr == NULL) {
free_fmtp_parse(ptr);
return (NULL);
}
return (ptr);
}
void free_fmtp_parse (fmtp_parse_t *ptr)
{
if (ptr->config_binary != NULL) {
free(ptr->config_binary);
ptr->config_binary = NULL;
}
if (ptr->config_ascii != NULL) {
free(ptr->config_ascii);
ptr->config_ascii = NULL;
}
free(ptr);
}
/* end file player_sdp.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -