Sat Apr 26 2014 22:03:10

Asterisk developer's documentation


res_format_attr_h264.c File Reference

H.264 Format Attribute Module. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/format.h"
Include dependency graph for res_format_attr_h264.c:

Go to the source code of this file.

Defines

#define H264_ATTR_KEY_UNSET   UINT8_MAX
 Value that indicates an attribute is actually unset.
#define H264_MAX_SPS_PPS_SIZE   16
 Maximum size for SPS / PPS values in sprop-parameter-sets attribute if you change this value then you must change H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT as well.
#define H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT   "15"
 This is used when executing sscanf on buffers of H264_MAX_SPS_PPS_SIZE length. It must ALWAYS be a string literal representation of one less than H264_MAX_SPS_PPS_SIZE.

Enumerations

enum  h264_attr_keys {
  H264_ATTR_KEY_PROFILE_IDC, H264_ATTR_KEY_PROFILE_IOP, H264_ATTR_KEY_LEVEL, H264_ATTR_KEY_MAX_MBPS,
  H264_ATTR_KEY_MAX_FS, H264_ATTR_KEY_MAX_CPB, H264_ATTR_KEY_MAX_DPB, H264_ATTR_KEY_MAX_BR,
  H264_ATTR_KEY_MAX_SMBPS, H264_ATTR_KEY_MAX_FPS, H264_ATTR_KEY_REDUNDANT_PIC_CAP, H264_ATTR_KEY_PARAMETER_ADD,
  H264_ATTR_KEY_PACKETIZATION_MODE, H264_ATTR_KEY_SPROP_INTERLEAVING_DEPTH, H264_ATTR_KEY_SPROP_DEINT_BUF_REQ, H264_ATTR_KEY_DEINT_BUF_CAP,
  H264_ATTR_KEY_SPROP_INIT_BUF_TIME, H264_ATTR_KEY_SPROP_MAX_DON_DIFF, H264_ATTR_KEY_MAX_RCMD_NALU_SIZE, H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED,
  H264_ATTR_KEY_SPS_LEN, H264_ATTR_KEY_PPS_LEN, H264_ATTR_KEY_SPS, H264_ATTR_KEY_PPS = H264_ATTR_KEY_SPS + H264_MAX_SPS_PPS_SIZE,
  H264_ATTR_KEY_END = H264_ATTR_KEY_PPS + H264_MAX_SPS_PPS_SIZE
}

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int h264_attr_key_addable (const struct ast_format_attr *format_attr, enum h264_attr_keys key)
 Helper function which determines if the value of an attribute can be placed into the SDP.
static const char * h264_attr_key_to_str (enum h264_attr_keys key)
 Helper function which converts a key enum into a string value for SDP.
static enum ast_format_cmp_res h264_format_attr_cmp (const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
static int h264_format_attr_get_joint (const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
static void h264_format_attr_sdp_generate (const struct ast_format_attr *format_attr, unsigned int payload, struct ast_str **str)
static int h264_format_attr_sdp_parse (struct ast_format_attr *format_attr, const char *attributes)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "H.264 Format Attribute Module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static struct ast_module_infoast_module_info = &__mod_info
static struct
ast_format_attr_interface 
h264_format_attr_interface

Detailed Description

H.264 Format Attribute Module.

Author:
Joshua Colp <jcolp@digium.com> 

This is a format attribute module for the H.264 codec.

Definition in file res_format_attr_h264.c.


Define Documentation

Value that indicates an attribute is actually unset.

Definition at line 42 of file res_format_attr_h264.c.

Referenced by h264_attr_key_addable(), and h264_format_attr_sdp_parse().

#define H264_MAX_SPS_PPS_SIZE   16

Maximum size for SPS / PPS values in sprop-parameter-sets attribute if you change this value then you must change H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT as well.

Definition at line 47 of file res_format_attr_h264.c.

Referenced by h264_format_attr_sdp_generate(), and h264_format_attr_sdp_parse().

This is used when executing sscanf on buffers of H264_MAX_SPS_PPS_SIZE length. It must ALWAYS be a string literal representation of one less than H264_MAX_SPS_PPS_SIZE.

Definition at line 51 of file res_format_attr_h264.c.

Referenced by h264_format_attr_sdp_parse().


Enumeration Type Documentation

Enumerator:
H264_ATTR_KEY_PROFILE_IDC 
H264_ATTR_KEY_PROFILE_IOP 
H264_ATTR_KEY_LEVEL 
H264_ATTR_KEY_MAX_MBPS 
H264_ATTR_KEY_MAX_FS 
H264_ATTR_KEY_MAX_CPB 
H264_ATTR_KEY_MAX_DPB 
H264_ATTR_KEY_MAX_BR 
H264_ATTR_KEY_MAX_SMBPS 
H264_ATTR_KEY_MAX_FPS 
H264_ATTR_KEY_REDUNDANT_PIC_CAP 
H264_ATTR_KEY_PARAMETER_ADD 
H264_ATTR_KEY_PACKETIZATION_MODE 
H264_ATTR_KEY_SPROP_INTERLEAVING_DEPTH 
H264_ATTR_KEY_SPROP_DEINT_BUF_REQ 
H264_ATTR_KEY_DEINT_BUF_CAP 
H264_ATTR_KEY_SPROP_INIT_BUF_TIME 
H264_ATTR_KEY_SPROP_MAX_DON_DIFF 
H264_ATTR_KEY_MAX_RCMD_NALU_SIZE 
H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED 
H264_ATTR_KEY_SPS_LEN 
H264_ATTR_KEY_PPS_LEN 
H264_ATTR_KEY_SPS 
H264_ATTR_KEY_PPS 
H264_ATTR_KEY_END 

Definition at line 53 of file res_format_attr_h264.c.


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 323 of file res_format_attr_h264.c.

static void __unreg_module ( void  ) [static]

Definition at line 323 of file res_format_attr_h264.c.

static int h264_attr_key_addable ( const struct ast_format_attr format_attr,
enum h264_attr_keys  key 
) [static]

Helper function which determines if the value of an attribute can be placed into the SDP.

Definition at line 227 of file res_format_attr_h264.c.

References ast_format_attr::format_attr, H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED, H264_ATTR_KEY_PACKETIZATION_MODE, H264_ATTR_KEY_PARAMETER_ADD, H264_ATTR_KEY_REDUNDANT_PIC_CAP, and H264_ATTR_KEY_UNSET.

Referenced by h264_format_attr_sdp_generate().

{
   switch (key) {
   case H264_ATTR_KEY_REDUNDANT_PIC_CAP:
   case H264_ATTR_KEY_PARAMETER_ADD:
   case H264_ATTR_KEY_PACKETIZATION_MODE:
   case H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED:
      return (format_attr->format_attr[key] != H264_ATTR_KEY_UNSET) ? 1 : 0;
   default:
      return format_attr->format_attr[key] ? 1 : 0;
   }

   return 1;
}
static const char* h264_attr_key_to_str ( enum h264_attr_keys  key) [static]

Helper function which converts a key enum into a string value for SDP.

Definition at line 182 of file res_format_attr_h264.c.

References H264_ATTR_KEY_DEINT_BUF_CAP, H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED, H264_ATTR_KEY_MAX_BR, H264_ATTR_KEY_MAX_CPB, H264_ATTR_KEY_MAX_DPB, H264_ATTR_KEY_MAX_FPS, H264_ATTR_KEY_MAX_FS, H264_ATTR_KEY_MAX_MBPS, H264_ATTR_KEY_MAX_RCMD_NALU_SIZE, H264_ATTR_KEY_MAX_SMBPS, H264_ATTR_KEY_PACKETIZATION_MODE, H264_ATTR_KEY_PARAMETER_ADD, H264_ATTR_KEY_REDUNDANT_PIC_CAP, H264_ATTR_KEY_SPROP_DEINT_BUF_REQ, H264_ATTR_KEY_SPROP_INIT_BUF_TIME, H264_ATTR_KEY_SPROP_INTERLEAVING_DEPTH, and H264_ATTR_KEY_SPROP_MAX_DON_DIFF.

Referenced by h264_format_attr_sdp_generate().

{
   switch (key) {
   case H264_ATTR_KEY_MAX_MBPS:
      return "max-mbps";
   case H264_ATTR_KEY_MAX_FS:
      return "max-fs";
   case H264_ATTR_KEY_MAX_CPB:
      return "max-cpb";
   case H264_ATTR_KEY_MAX_DPB:
      return "max-dpb";
   case H264_ATTR_KEY_MAX_BR:
      return "max-br";
   case H264_ATTR_KEY_MAX_SMBPS:
      return "max-smbps";
   case H264_ATTR_KEY_MAX_FPS:
      return "max-fps";
   case H264_ATTR_KEY_REDUNDANT_PIC_CAP:
      return "redundant-pic-cap";
   case H264_ATTR_KEY_PARAMETER_ADD:
      return "parameter-add";
   case H264_ATTR_KEY_PACKETIZATION_MODE:
      return "packetization-mode";
   case H264_ATTR_KEY_SPROP_INTERLEAVING_DEPTH:
      return "sprop-interleaving-depth";
   case H264_ATTR_KEY_SPROP_DEINT_BUF_REQ:
      return "sprop-deint-buf-req";
   case H264_ATTR_KEY_DEINT_BUF_CAP:
      return "deint-buf-cap";
   case H264_ATTR_KEY_SPROP_INIT_BUF_TIME:
      return "sprop-init-buf-time";
   case H264_ATTR_KEY_SPROP_MAX_DON_DIFF:
      return "sprop-max-don-diff";
   case H264_ATTR_KEY_MAX_RCMD_NALU_SIZE:
      return "max-rcmd-nalu-size";
   case H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED:
      return "level-asymmetry-allowed";
   default:
      return NULL;
   }

   return NULL;
}
static int h264_format_attr_get_joint ( const struct ast_format_attr fattr1,
const struct ast_format_attr fattr2,
struct ast_format_attr result 
) [static]

Definition at line 91 of file res_format_attr_h264.c.

References ast_format_attr::format_attr, H264_ATTR_KEY_END, and H264_ATTR_KEY_PROFILE_IDC.

{
   int i;

   for (i = H264_ATTR_KEY_PROFILE_IDC; i < H264_ATTR_KEY_END; i++) {
      result->format_attr[i] = fattr1->format_attr[i] ? fattr1->format_attr[i] : fattr2->format_attr[i];
   }

   return 0;
}
static void h264_format_attr_sdp_generate ( const struct ast_format_attr format_attr,
unsigned int  payload,
struct ast_str **  str 
) [static]

Definition at line 242 of file res_format_attr_h264.c.

References ast_base64encode(), ast_str_append(), ast_format_attr::format_attr, h264_attr_key_addable(), H264_ATTR_KEY_END, H264_ATTR_KEY_LEVEL, H264_ATTR_KEY_PPS, H264_ATTR_KEY_PPS_LEN, H264_ATTR_KEY_PROFILE_IDC, H264_ATTR_KEY_PROFILE_IOP, H264_ATTR_KEY_SPS, H264_ATTR_KEY_SPS_LEN, h264_attr_key_to_str(), H264_MAX_SPS_PPS_SIZE, and name.

{
   int i, added = 0;

        for (i = H264_ATTR_KEY_PROFILE_IDC; i < H264_ATTR_KEY_END; i++) {
                const char *name;

      if (i == H264_ATTR_KEY_SPS && format_attr->format_attr[H264_ATTR_KEY_SPS] && format_attr->format_attr[H264_ATTR_KEY_PPS]) {
         unsigned char spsdecoded[H264_MAX_SPS_PPS_SIZE] = { 0, }, ppsdecoded[H264_MAX_SPS_PPS_SIZE] = { 0, };
         int pos;
         char sps[H264_MAX_SPS_PPS_SIZE], pps[H264_MAX_SPS_PPS_SIZE];

         for (pos = 0; pos < H264_MAX_SPS_PPS_SIZE; pos++) {
            spsdecoded[pos] = format_attr->format_attr[H264_ATTR_KEY_SPS + pos];
            ppsdecoded[pos] = format_attr->format_attr[H264_ATTR_KEY_PPS + pos];
         }

         ast_base64encode(sps, spsdecoded, format_attr->format_attr[H264_ATTR_KEY_SPS_LEN], H264_MAX_SPS_PPS_SIZE);
         ast_base64encode(pps, ppsdecoded, format_attr->format_attr[H264_ATTR_KEY_PPS_LEN], H264_MAX_SPS_PPS_SIZE);

         if (!added) {
            ast_str_append(str, 0, "a=fmtp:%d sprop-parameter-sets=%s,%s", payload, sps, pps);
            added = 1;
         } else {
            ast_str_append(str, 0, ";sprop-parameter-sets=%s,%s", sps, pps);
         }
      } else if (i == H264_ATTR_KEY_PROFILE_IDC && format_attr->format_attr[H264_ATTR_KEY_PROFILE_IDC] &&
          format_attr->format_attr[H264_ATTR_KEY_PROFILE_IOP] && format_attr->format_attr[H264_ATTR_KEY_LEVEL]) {
         if (!added) {
            ast_str_append(str, 0, "a=fmtp:%d profile-level-id=%X%X%X", payload, format_attr->format_attr[H264_ATTR_KEY_PROFILE_IDC],
                      format_attr->format_attr[H264_ATTR_KEY_PROFILE_IOP], format_attr->format_attr[H264_ATTR_KEY_LEVEL]);
            added = 1;
         } else {
            ast_str_append(str, 0, ";profile-level-id=%X%X%X", format_attr->format_attr[H264_ATTR_KEY_PROFILE_IDC],
                      format_attr->format_attr[H264_ATTR_KEY_PROFILE_IOP], format_attr->format_attr[H264_ATTR_KEY_LEVEL]);
         }
      } else if ((name = h264_attr_key_to_str(i)) && h264_attr_key_addable(format_attr, i)) {
         if (!added) {
            ast_str_append(str, 0, "a=fmtp:%d %s=%u", payload, name, format_attr->format_attr[i]);
            added = 1;
         } else {
            ast_str_append(str, 0, ";%s=%u", name, format_attr->format_attr[i]);
         }
      }
   }
   
   if (added) {
      ast_str_append(str, 0, "\r\n");
   }

   return;
}
static int h264_format_attr_sdp_parse ( struct ast_format_attr format_attr,
const char *  attributes 
) [static]

Definition at line 102 of file res_format_attr_h264.c.

References ast_base64decode(), ast_format_attr::format_attr, H264_ATTR_KEY_DEINT_BUF_CAP, H264_ATTR_KEY_LEVEL, H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED, H264_ATTR_KEY_MAX_BR, H264_ATTR_KEY_MAX_CPB, H264_ATTR_KEY_MAX_DPB, H264_ATTR_KEY_MAX_FPS, H264_ATTR_KEY_MAX_FS, H264_ATTR_KEY_MAX_MBPS, H264_ATTR_KEY_MAX_RCMD_NALU_SIZE, H264_ATTR_KEY_MAX_SMBPS, H264_ATTR_KEY_PACKETIZATION_MODE, H264_ATTR_KEY_PARAMETER_ADD, H264_ATTR_KEY_PPS, H264_ATTR_KEY_PPS_LEN, H264_ATTR_KEY_PROFILE_IDC, H264_ATTR_KEY_PROFILE_IOP, H264_ATTR_KEY_REDUNDANT_PIC_CAP, H264_ATTR_KEY_SPROP_DEINT_BUF_REQ, H264_ATTR_KEY_SPROP_INIT_BUF_TIME, H264_ATTR_KEY_SPROP_INTERLEAVING_DEPTH, H264_ATTR_KEY_SPROP_MAX_DON_DIFF, H264_ATTR_KEY_SPS, H264_ATTR_KEY_SPS_LEN, H264_ATTR_KEY_UNSET, H264_MAX_SPS_PPS_SIZE, and H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT.

{
   char *attribs = ast_strdupa(attributes), *attrib;

   format_attr->format_attr[H264_ATTR_KEY_REDUNDANT_PIC_CAP] = H264_ATTR_KEY_UNSET;
   format_attr->format_attr[H264_ATTR_KEY_PARAMETER_ADD] = H264_ATTR_KEY_UNSET;
   format_attr->format_attr[H264_ATTR_KEY_PACKETIZATION_MODE] = H264_ATTR_KEY_UNSET;
   format_attr->format_attr[H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED] = H264_ATTR_KEY_UNSET;

   while ((attrib = strsep(&attribs, ";"))) {
      unsigned int val;
      unsigned long int val2;
      char sps[H264_MAX_SPS_PPS_SIZE], pps[H264_MAX_SPS_PPS_SIZE];

      if (sscanf(attrib, "profile-level-id=%lx", &val2) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_PROFILE_IDC] = ((val2 >> 16) & 0xFF);
         format_attr->format_attr[H264_ATTR_KEY_PROFILE_IOP] = ((val2 >> 8) & 0xFF);
         format_attr->format_attr[H264_ATTR_KEY_LEVEL] = (val2 & 0xFF);
      } else if (sscanf(attrib, "sprop-parameter-sets=%" H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT "[^','],%" H264_MAX_SPS_PPS_SIZE_SCAN_LIMIT "s", sps, pps) == 2) {
         /* XXX sprop-parameter-sets can actually be of unlimited length. This may need to be addressed later. */
         unsigned char spsdecoded[H264_MAX_SPS_PPS_SIZE] = { 0, }, ppsdecoded[H264_MAX_SPS_PPS_SIZE] = { 0, };
         int i;

         ast_base64decode(spsdecoded, sps, sizeof(spsdecoded));
         ast_base64decode(ppsdecoded, pps, sizeof(ppsdecoded));

         format_attr->format_attr[H264_ATTR_KEY_SPS_LEN] = 0;
         format_attr->format_attr[H264_ATTR_KEY_PPS_LEN] = 0;

         for (i = 0; i < H264_MAX_SPS_PPS_SIZE; i++) {
            if (spsdecoded[i]) {
               format_attr->format_attr[H264_ATTR_KEY_SPS + i] = spsdecoded[i];
               format_attr->format_attr[H264_ATTR_KEY_SPS_LEN]++;
            }
            if (ppsdecoded[i]) {
               format_attr->format_attr[H264_ATTR_KEY_PPS + i] = ppsdecoded[i];
               format_attr->format_attr[H264_ATTR_KEY_PPS_LEN]++;
            }
         }
      } else if (sscanf(attrib, "max-mbps=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_MBPS] = val;
      } else if (sscanf(attrib, "max-fs=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_FS] = val;
      } else if (sscanf(attrib, "max-cpb=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_CPB] = val;
      } else if (sscanf(attrib, "max-dpb=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_DPB] = val;
      } else if (sscanf(attrib, "max-br=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_BR] = val;
      } else if (sscanf(attrib, "max-smbps=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_SMBPS] = val;
      } else if (sscanf(attrib, "max-fps=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_FPS] = val;
      } else if (sscanf(attrib, "redundant-pic-cap=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_REDUNDANT_PIC_CAP] = val;
      } else if (sscanf(attrib, "parameter-add=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_PARAMETER_ADD] = val;
      } else if (sscanf(attrib, "packetization-mode=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_PACKETIZATION_MODE] = val;
      } else if (sscanf(attrib, "sprop-interleaving-depth=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_SPROP_INTERLEAVING_DEPTH] = val;
      } else if (sscanf(attrib, "sprop-deint-buf-req=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_SPROP_DEINT_BUF_REQ] = val;
      } else if (sscanf(attrib, "deint-buf-cap=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_DEINT_BUF_CAP] = val;
      } else if (sscanf(attrib, "sprop-init-buf-time=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_SPROP_INIT_BUF_TIME] = val;
      } else if (sscanf(attrib, "sprop-max-don-diff=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_SPROP_MAX_DON_DIFF] = val;
      } else if (sscanf(attrib, "max-rcmd-nalu-size=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_MAX_RCMD_NALU_SIZE] = val;
      } else if (sscanf(attrib, "level-asymmetry-allowed=%30u", &val) == 1) {
         format_attr->format_attr[H264_ATTR_KEY_LEVEL_ASYMMETRY_ALLOWED] = val;
      }
   }

   return 0;
}
static int unload_module ( void  ) [static]

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "H.264 Format Attribute Module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 323 of file res_format_attr_h264.c.

Definition at line 323 of file res_format_attr_h264.c.