⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ebml.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
字号:
/* * native ebml reader for the Matroska demuxer * Written by Aurelien Jacobs <aurel@gnuage.org> * Based on the one written by Ronald Bultje for gstreamer * Licence: GPL */#include "config.h"#ifdef HAVE_MATROSKA#include <stdlib.h>#include "stream.h"#include "ebml.h"/* * Read: the element content data ID. * Return: the ID. */uint32_tebml_read_id (stream_t *s, int *length){  int i, len_mask = 0x80;  uint32_t id;  for (i=0, id=stream_read_char (s); i<4 && !(id & len_mask); i++)    len_mask >>= 1;  if (i >= 4)    return EBML_ID_INVALID;  if (length)    *length = i + 1;  while (i--)    id = (id << 8) | stream_read_char (s);  return id;}/* * Read a variable length unsigned int. */uint64_tebml_read_vlen_uint (uint8_t *buffer, int *length){  int i, j, num_ffs = 0, len_mask = 0x80;  uint64_t num;  for (i=0, num=*buffer++; i<8 && !(num & len_mask); i++)    len_mask >>= 1;  if (i >= 8)    return EBML_UINT_INVALID;  j = i+1;  if (length)    *length = j;  if ((int)(num &= (len_mask - 1)) == len_mask - 1)    num_ffs++;  while (i--)    {      num = (num << 8) | *buffer++;      if ((num & 0xFF) == 0xFF)        num_ffs++;    }  if (j == num_ffs)    return EBML_UINT_INVALID;  return num;}/* * Read a variable length signed int. */int64_tebml_read_vlen_int (uint8_t *buffer, int *length){  uint64_t unum;  int l;  /* read as unsigned number first */  unum = ebml_read_vlen_uint (buffer, &l);  if (unum == EBML_UINT_INVALID)    return EBML_INT_INVALID;  if (length)    *length = l;  return unum - ((1 << ((7 * l) - 1)) - 1);}/* * Read: element content length. */uint64_tebml_read_length (stream_t *s, int *length){  int i, j, num_ffs = 0, len_mask = 0x80;  uint64_t len;  for (i=0, len=stream_read_char (s); i<8 && !(len & len_mask); i++)    len_mask >>= 1;  if (i >= 8)    return EBML_UINT_INVALID;  j = i+1;  if (length)    *length = j;  if ((int)(len &= (len_mask - 1)) == len_mask - 1)    num_ffs++;  while (i--)    {      len = (len << 8) | stream_read_char (s);      if ((len & 0xFF) == 0xFF)        num_ffs++;    }  if (j == num_ffs)    return EBML_UINT_INVALID;  return len;}/* * Read the next element as an unsigned int. */uint64_tebml_read_uint (stream_t *s, uint64_t *length){  uint64_t len, value = 0;  int l;  len = ebml_read_length (s, &l);  if (len == EBML_UINT_INVALID || len < 1 || len > 8)    return EBML_UINT_INVALID;  if (length)    *length = len + l;  while (len--)    value = (value << 8) | stream_read_char (s);  return value;}/* * Read the next element as a signed int. */int64_tebml_read_int (stream_t *s, uint64_t *length){  int64_t value = 0;  uint64_t len;  int l;  len = ebml_read_length (s, &l);  if (len == EBML_UINT_INVALID || len < 1 || len > 8)    return EBML_INT_INVALID;  if (length)    *length = len + l;  len--;  l = stream_read_char (s);  if (l & 0x80)    value = -1;  value = (value << 8) | l;  while (len--)    value = (value << 8) | stream_read_char (s);  return value;}/* * Read the next element as a float. */long doubleebml_read_float (stream_t *s, uint64_t *length){  long double value;  uint64_t len;  int l;  len = ebml_read_length (s, &l);  switch (len)    {    case 4:      {        uint32_t i;        float *f;        i = stream_read_dword (s);        f = (float *) (void *) &i;        value = *f;        break;      }    case 8:      {        uint64_t i;        double *d;        i = stream_read_qword (s);        d = (double *) (void *) &i;        value = *d;        break;      }    case 10:      {        uint8_t data[10];        if (stream_read (s, data, 10) != 10)          return EBML_FLOAT_INVALID;        value = * (long double *) data;        break;      }    default:      return EBML_FLOAT_INVALID;    }  if (length)    *length = len + l;  return value;}/* * Read the next element as an ASCII string. */char *ebml_read_ascii (stream_t *s, uint64_t *length){  uint64_t len;  char *str;  int l;  len = ebml_read_length (s, &l);  if (len == EBML_UINT_INVALID)    return NULL;  if (length)    *length = len + l;  str = (char *) malloc (len+1);  if (stream_read(s, str, len) != (int) len)    {      free (str);      return NULL;    }  str[len] = '\0';  return str;}/* * Read the next element as a UTF-8 string. */char *ebml_read_utf8 (stream_t *s, uint64_t *length){  return ebml_read_ascii (s, length);}/* * Skip the next element. */intebml_read_skip (stream_t *s, uint64_t *length){  uint64_t len;  int l;  len = ebml_read_length (s, &l);  if (len == EBML_UINT_INVALID)    return 1;  if (length)    *length = len + l;  stream_skip(s, len);  return 0;}/* * Read the next element, but only the header. The contents * are supposed to be sub-elements which can be read separately. */uint32_tebml_read_master (stream_t *s, uint64_t *length){  uint64_t len;  uint32_t id;  id = ebml_read_id (s, NULL);  if (id == EBML_ID_INVALID)    return id;  len = ebml_read_length (s, NULL);  if (len == EBML_UINT_INVALID)    return EBML_ID_INVALID;  if (length)    *length = len;  return id;}/* * Read an EBML header. */char *ebml_read_header (stream_t *s, int *version){  uint64_t length, l, num;  uint32_t id;  char *str = NULL;  if (ebml_read_master (s, &length) != EBML_ID_HEADER)    return 0;  if (version)    *version = 1;  while (length > 0)    {      id = ebml_read_id (s, NULL);      if (id == EBML_ID_INVALID)        return NULL;      length -= 2;      switch (id)        {          /* is our read version uptodate? */        case EBML_ID_EBMLREADVERSION:          num = ebml_read_uint (s, &l);          if (num != EBML_VERSION)            return NULL;          break;          /* we only handle 8 byte lengths at max */        case EBML_ID_EBMLMAXSIZELENGTH:          num = ebml_read_uint (s, &l);          if (num != sizeof (uint64_t))            return NULL;          break;          /* we handle 4 byte IDs at max */        case EBML_ID_EBMLMAXIDLENGTH:          num = ebml_read_uint (s, &l);          if (num != sizeof (uint32_t))            return NULL;          break;        case EBML_ID_DOCTYPE:          str = ebml_read_ascii (s, &l);          if (str == NULL)            return NULL;          break;        case EBML_ID_DOCTYPEREADVERSION:          num = ebml_read_uint (s, &l);          if (num == EBML_UINT_INVALID)            return NULL;          if (version)            *version = num;          break;          /* we ignore these two, they don't tell us anything we care about */        case EBML_ID_VOID:        case EBML_ID_EBMLVERSION:        case EBML_ID_DOCTYPEVERSION:        default:          if (ebml_read_skip (s, &l))            return NULL;          break;        }      length -= l;    }  return str;}#endif /* HAVE_MATROSKA */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -