demux_mkv.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,147 行 · 第 1/5 页

C
2,147
字号
      track->num_cached_dps = 0;      track->num_allocated_dps = 0;      track->max_pts = 0;    }}static intdemux_mkv_parse_idx (mkv_track_t *t){  int things_found, last;  char *buf, *pos, *start;  if ((t->private_data == NULL) || (t->private_size == 0))    return 0;  things_found = 0;  buf = malloc(t->private_size + 1);  if (buf == NULL)    return 0;  memcpy(buf, t->private_data, t->private_size);  buf[t->private_size] = 0;  t->sh_sub->has_palette = 0;  pos = buf;  start = buf;  last = 0;  do    {      if ((*pos == 0) || (*pos == '\r') || (*pos == '\n'))        {          if (*pos == 0)            last = 1;          *pos = 0;          if (!strncasecmp(start, "size: ", 6))            things_found |= vobsub_parse_size(t->sh_sub, start);          else if (!strncasecmp(start, "palette:", 8))            things_found |= vobsub_parse_palette(t->sh_sub, start);          else if (!strncasecmp(start, "custom colors:", 14))            things_found |= vobsub_parse_custom_colors(t->sh_sub, start);          else if (!strncasecmp(start, "forced subs:", 12))            things_found |= vobsub_parse_forced_subs(t->sh_sub, start);          if (last)            break;          do            {              pos++;            }          while ((*pos == '\r') || (*pos == '\n'));          start = pos;        }      else        pos++;    }  while (!last && (*start != 0));  free(buf);  return (things_found & 3) == 3;}static intdemux_mkv_decode (mkv_track_t *track, uint8_t *src, uint8_t **dest,                  uint32_t *size, uint32_t type){  int i, result;  int modified = 0;  *dest = src;  if (track->num_encodings <= 0)    return 0;  for (i=0; i<track->num_encodings; i++)    {      if (!(track->encodings[i].scope & type))        continue;#ifdef HAVE_ZLIB      if (track->encodings[i].comp_algo == 0)        {          /* zlib encoded track */          z_stream zstream;          zstream.zalloc = (alloc_func) 0;          zstream.zfree = (free_func) 0;          zstream.opaque = (voidpf) 0;          if (inflateInit (&zstream) != Z_OK)            {              mp_msg (MSGT_DEMUX, MSGL_WARN,                      MSGTR_MPDEMUX_MKV_ZlibInitializationFailed);              return modified;            }          zstream.next_in = (Bytef *) src;          zstream.avail_in = *size;          modified = 1;          *dest = NULL;          zstream.avail_out = *size;          do {            *size += 4000;            *dest = realloc (*dest, *size);            zstream.next_out = (Bytef *) (*dest + zstream.total_out);            result = inflate (&zstream, Z_NO_FLUSH);            if (result != Z_OK && result != Z_STREAM_END)              {                mp_msg (MSGT_DEMUX, MSGL_WARN,                        MSGTR_MPDEMUX_MKV_ZlibDecompressionFailed);                free(*dest);                *dest = NULL;                inflateEnd (&zstream);                return modified;              }            zstream.avail_out += 4000;          } while (zstream.avail_out == 4000 &&                   zstream.avail_in != 0 && result != Z_STREAM_END);          *size = zstream.total_out;          inflateEnd (&zstream);        }#endif      if (track->encodings[i].comp_algo == 2)        {          /* lzo encoded track */          int dstlen = *size * 3;          *dest = NULL;          while (1)            {              int srclen = *size;              if (dstlen > SIZE_MAX - LZO_OUTPUT_PADDING) goto lzo_fail;              *dest = realloc (*dest, dstlen + LZO_OUTPUT_PADDING);              result = lzo1x_decode (*dest, &dstlen, src, &srclen);              if (result == 0)                break;              if (!(result & LZO_OUTPUT_FULL))                {lzo_fail:                  mp_msg (MSGT_DEMUX, MSGL_WARN,                          MSGTR_MPDEMUX_MKV_LzoDecompressionFailed);                  free(*dest);                  *dest = NULL;                  return modified;                }              mp_msg (MSGT_DEMUX, MSGL_DBG2,                      "[mkv] lzo decompression buffer too small.\n");              dstlen *= 2;            }          *size = dstlen;        }    }  return modified;}static intdemux_mkv_read_info (demuxer_t *demuxer){  mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;  stream_t *s = demuxer->stream;  uint64_t length, l;  int il;  uint64_t tc_scale = 1000000;  long double duration = 0.;  length = ebml_read_length (s, NULL);  while (length > 0)    {      switch (ebml_read_id (s, &il))        {        case MATROSKA_ID_TIMECODESCALE:          {            uint64_t num = ebml_read_uint (s, &l);            if (num == EBML_UINT_INVALID)              return 1;            tc_scale = num;            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + timecode scale: %"PRIu64"\n",                    tc_scale);            break;          }        case MATROSKA_ID_DURATION:          {            long double num = ebml_read_float (s, &l);            if (num == EBML_FLOAT_INVALID)              return 1;            duration = num;            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3Lfs\n",                    duration * tc_scale / 1000000000.0);            break;          }        default:          ebml_read_skip (s, &l);           break;        }      length -= l + il;    }  mkv_d->tc_scale = tc_scale;  mkv_d->duration = duration * tc_scale / 1000000000.0;  return 0;}/** * \brief free array of kv_content_encoding_t * \param encodings pointer to array * \param numencodings number of encodings in array */static voiddemux_mkv_free_encodings(mkv_content_encoding_t *encodings, int numencodings){  while (numencodings-- > 0)    free(encodings[numencodings].comp_settings);  free(encodings);}static intdemux_mkv_read_trackencodings (demuxer_t *demuxer, mkv_track_t *track){  stream_t *s = demuxer->stream;  mkv_content_encoding_t *ce, e;  uint64_t len, length, l;  int il, n;  ce = malloc (sizeof (*ce));  n = 0;  len = length = ebml_read_length (s, &il);  len += il;  while (length > 0)    {      switch (ebml_read_id (s, &il))        {        case MATROSKA_ID_CONTENTENCODING:          {            uint64_t len;            int i;            memset (&e, 0, sizeof (e));            e.scope = 1;            len = ebml_read_length (s, &i);            l = len + i;            while (len > 0)              {                uint64_t num, l;                int il;                switch (ebml_read_id (s, &il))                  {                  case MATROSKA_ID_CONTENTENCODINGORDER:                    num = ebml_read_uint (s, &l);                    if (num == EBML_UINT_INVALID)                      goto err_out;                    e.order = num;                    break;                  case MATROSKA_ID_CONTENTENCODINGSCOPE:                    num = ebml_read_uint (s, &l);                    if (num == EBML_UINT_INVALID)                      goto err_out;                    e.scope = num;                    break;                  case MATROSKA_ID_CONTENTENCODINGTYPE:                    num = ebml_read_uint (s, &l);                    if (num == EBML_UINT_INVALID)                      goto err_out;                    e.type = num;                    break;                  case MATROSKA_ID_CONTENTCOMPRESSION:                    {                      uint64_t le;                      le = ebml_read_length (s, &i);                      l = le + i;                      while (le > 0)                        {                          uint64_t l;                          int il;                          switch (ebml_read_id (s, &il))                            {                            case MATROSKA_ID_CONTENTCOMPALGO:                              num = ebml_read_uint (s, &l);                              if (num == EBML_UINT_INVALID)                                goto err_out;                              e.comp_algo = num;                              break;                            case MATROSKA_ID_CONTENTCOMPSETTINGS:                              l = ebml_read_length (s, &i);                              e.comp_settings = malloc (l);                              stream_read (s, e.comp_settings, l);                              e.comp_settings_len = l;                              l += i;                              break;                            default:                              ebml_read_skip (s, &l);                              break;                            }                          le -= l + il;                        }                      if (e.type == 1)                        {                          mp_msg(MSGT_DEMUX, MSGL_WARN,                                 MSGTR_MPDEMUX_MKV_TrackEncrypted, track->tnum);                        }                      else if (e.type != 0)                        {                          mp_msg(MSGT_DEMUX, MSGL_WARN,                                 MSGTR_MPDEMUX_MKV_UnknownContentEncoding, track->tnum);                        }                      if (e.comp_algo != 0 && e.comp_algo != 2)                        {                          mp_msg (MSGT_DEMUX, MSGL_WARN,                                  MSGTR_MPDEMUX_MKV_UnknownCompression,                                  track->tnum, e.comp_algo);                        }#ifndef HAVE_ZLIB                      else if (e.comp_algo == 0)                        {                          mp_msg (MSGT_DEMUX, MSGL_WARN,                                  MSGTR_MPDEMUX_MKV_ZlibCompressionUnsupported,                                  track->tnum);                        }#endif                      break;                    }                  default:                    ebml_read_skip (s, &l);                    break;                  }                len -= l + il;              }            for (i=0; i<n; i++)              if (e.order <= ce[i].order)                break;            ce = realloc (ce, (n+1) *sizeof (*ce));            memmove (ce+i+1, ce+i, (n-i) * sizeof (*ce));            memcpy (ce+i, &e, sizeof (e));            n++;            break;          }        default:          ebml_read_skip (s, &l);          break;        }      length -= l + il;    }  track->encodings = ce;  track->num_encodings = n;  return len;err_out:  demux_mkv_free_encodings(ce, n);  return 0;}static intdemux_mkv_read_trackaudio (demuxer_t *demuxer, mkv_track_t *track){  stream_t *s = demuxer->stream;  uint64_t len, length, l;  int il;  track->a_sfreq = 8000.0;  track->a_channels = 1;  len = length = ebml_read_length (s, &il);  len += il;  while (length > 0)    {      switch (ebml_read_id (s, &il))        {        case MATROSKA_ID_AUDIOSAMPLINGFREQ:          {            long double num = ebml_read_float (s, &l);            if (num == EBML_FLOAT_INVALID)              return 0;            track->a_sfreq = num;            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |   + Sampling frequency: %f\n",                    track->a_sfreq);            break;          }        case MATROSKA_ID_AUDIOBITDEPTH:          {            uint64_t num = ebml_read_uint (s, &l);            if (num == EBML_UINT_INVALID)              return 0;            track->a_bps = num;            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |   + Bit depth: %u\n",                    track->a_bps);            break;          }        case MATROSKA_ID_AUDIOCHANNELS:          {            uint64_t num = ebml_read_uint (s, &l);            if (num == EBML_UINT_INVALID)              return 0;            track->a_channels = num;            mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |   + Channels: %u\n",                    track->a_channels);            break;          }        default:            ebml_read_skip (s, &l);            break;        }      length -= l + il;    }  return len;}

⌨️ 快捷键说明

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