demux_mkv.c

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

C
2,147
字号
          mkv_d->num_indexes++;        }    }  mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n");  return 0;}static intdemux_mkv_read_chapters (demuxer_t *demuxer){  stream_t *s = demuxer->stream;  uint64_t length, l;  int il;  if (demuxer->chapters)    {      ebml_read_skip (s, NULL);      return 0;    }  mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n");  length = ebml_read_length (s, NULL);  while (length > 0)    {      switch (ebml_read_id (s, &il))        {        case MATROSKA_ID_EDITIONENTRY:          {            uint64_t len;            int i;            len = ebml_read_length (s, &i);            l = len + i;            while (len > 0)              {                uint64_t l;                int il;                switch (ebml_read_id (s, &il))                  {                  case MATROSKA_ID_CHAPTERATOM:                    {                      uint64_t len, start=0, end=0;                      char* name = 0;                      int i;                      int cid;                      len = ebml_read_length (s, &i);                      l = len + i;                      while (len > 0)                        {                          uint64_t l;                          int il;                          switch (ebml_read_id (s, &il))                            {                            case MATROSKA_ID_CHAPTERTIMESTART:                              start = ebml_read_uint (s, &l) / 1000000;                              break;                            case MATROSKA_ID_CHAPTERTIMEEND:                              end = ebml_read_uint (s, &l) / 1000000;                              break;                            case MATROSKA_ID_CHAPTERDISPLAY:                              {                                uint64_t len;                                int i;                                len = ebml_read_length (s, &i);                                l = len + i;                                while (len > 0)                                  {                                    uint64_t l;                                    int il;                                    switch (ebml_read_id (s, &il))                                      {                                        case MATROSKA_ID_CHAPSTRING:                                          name = ebml_read_utf8 (s, &l);                                          break;                                        default:                                          ebml_read_skip (s, &l);                                          break;                                      }                                    len -= l + il;                                  }                              }                              break;                            default:                              ebml_read_skip (s, &l);                              break;                            }                          len -= l + il;                        }                      if (!name)                        name = strdup("(unnamed)");                                            cid = demuxer_add_chapter(demuxer, name, start, end);                                            mp_msg(MSGT_DEMUX, MSGL_V,                             "[mkv] Chapter %u from %02d:%02d:%02d."                             "%03d to %02d:%02d:%02d.%03d, %s\n",                             cid,                             (int) (start / 60 / 60 / 1000),                             (int) ((start / 60 / 1000) % 60),                             (int) ((start / 1000) % 60),                             (int) (start % 1000),                             (int) (end / 60 / 60 / 1000),                             (int) ((end / 60 / 1000) % 60),                             (int) ((end / 1000) % 60),                             (int) (end % 1000), name);                      free(name);                      break;                    }                  default:                    ebml_read_skip (s, &l);                    break;                  }                len -= l + il;              }            break;          }        default:          ebml_read_skip (s, &l);          break;        }      length -= l + il;    }  mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing chapters ] ---------\n");  return 0;}static intdemux_mkv_read_tags (demuxer_t *demuxer){  ebml_read_skip (demuxer->stream, NULL);  return 0;}static intdemux_mkv_read_attachments (demuxer_t *demuxer){  mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;  stream_t *s = demuxer->stream;  uint64_t length, l;  int il;  mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing attachments ] ---------\n");  length = ebml_read_length (s, NULL);  while (length > 0)    {      switch (ebml_read_id (s, &il))        {          case MATROSKA_ID_ATTACHEDFILE:            {              uint64_t len;              int i;              char* name = NULL;              char* mime = NULL;              uint64_t uid = 0;              char* data = NULL;              int data_size = 0;              len = ebml_read_length (s, &i);              l = len + i;              mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] | + an attachment...\n");              grow_array(&mkv_d->attachments, mkv_d->num_attachments,                         sizeof(*mkv_d->attachments));              while (len > 0)                {                  uint64_t l;                  int il;                  switch (ebml_read_id (s, &il))                    {                    case MATROSKA_ID_FILENAME:                      name = ebml_read_utf8 (s, &l);                      if (name == NULL)                        return 0;                      mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + FileName: %s\n",                        name);                      break;                    case MATROSKA_ID_FILEMIMETYPE:                      mime = ebml_read_ascii (s, &l);                      if (mime == NULL)                        return 0;                      mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + FileMimeType: %s\n",                        mime);                      break;                    case MATROSKA_ID_FILEUID:                      uid = ebml_read_uint (s, &l);                      break;                    case MATROSKA_ID_FILEDATA:                      {                        int x;                        uint64_t num = ebml_read_length (s, &x);                        l = x + num;                        free(data);                        data = malloc (num);                        if (stream_read(s, data, num) != (int) num)                        {                          free(data);                          return 0;                        }                        data_size = num;                        mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] |  + FileData, length "                                "%u\n", data_size);                        break;                      }                    default:                      ebml_read_skip (s, &l);                      break;                    }                  len -= l + il;                }              mkv_d->attachments[mkv_d->num_attachments].name = name;              mkv_d->attachments[mkv_d->num_attachments].mime = mime;              mkv_d->attachments[mkv_d->num_attachments].uid = uid;              mkv_d->attachments[mkv_d->num_attachments].data = data;              mkv_d->attachments[mkv_d->num_attachments].data_size = data_size;              mkv_d->num_attachments ++;              mp_msg(MSGT_DEMUX, MSGL_V,                     "[mkv] Attachment: %s, %s, %u bytes\n",                     name, mime, data_size);#ifdef USE_ASS              if (ass_library &&                  extract_embedded_fonts && name && data && data_size &&                  mime && (strcmp(mime, "application/x-truetype-font") == 0 ||                  strcmp(mime, "application/x-font") == 0))                ass_add_font(ass_library, name, data, data_size);#endif              break;            }          default:            ebml_read_skip (s, &l);            break;        }      length -= l + il;    }  mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing attachments ] ---------\n");  return 0;}static intdemux_mkv_read_seekhead (demuxer_t *demuxer){  mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;  stream_t *s = demuxer->stream;  uint64_t length, l, seek_pos, saved_pos, num;  uint32_t seek_id;  int i, il, res = 0;  off_t off;  off = stream_tell (s);  for (i=0; i<mkv_d->parsed_seekhead_num; i++)    if (mkv_d->parsed_seekhead[i] == off)      {        ebml_read_skip (s, NULL);        return 0;      }  mkv_d->parsed_seekhead = realloc (mkv_d->parsed_seekhead,                                     (mkv_d->parsed_seekhead_num+1)                                    * sizeof (off_t));  mkv_d->parsed_seekhead[mkv_d->parsed_seekhead_num++] = off;  mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing seek head ] ---------\n");  length = ebml_read_length (s, NULL);  /* off now holds the position of the next element after the seek head. */  off = stream_tell (s) + length;  while (length > 0 && !res)    {      seek_id = 0;      seek_pos = EBML_UINT_INVALID;      switch (ebml_read_id (s, &il))        {        case MATROSKA_ID_SEEKENTRY:          {            uint64_t len;            len = ebml_read_length (s, &i);            l = len + i;            while (len > 0)              {                uint64_t l;                int il;                switch (ebml_read_id (s, &il))                  {                  case MATROSKA_ID_SEEKID:                    num = ebml_read_uint (s, &l);                    if (num != EBML_UINT_INVALID)                      seek_id = num;                    break;                  case MATROSKA_ID_SEEKPOSITION:                    seek_pos = ebml_read_uint (s, &l);                    break;                  default:                    ebml_read_skip (s, &l);                    break;                  }                len -= l + il;              }            break;          }        default:            ebml_read_skip (s, &l);            break;        }      length -= l + il;      if (seek_id == 0 || seek_id == MATROSKA_ID_CLUSTER          || seek_pos == EBML_UINT_INVALID ||          ((mkv_d->segment_start + seek_pos) >= (uint64_t)demuxer->movi_end))        continue;      saved_pos = stream_tell (s);      if (!stream_seek (s, mkv_d->segment_start + seek_pos))        res = 1;      else        {          if (ebml_read_id (s, &il) != seek_id)            res = 1;          else            switch (seek_id)              {              case MATROSKA_ID_CUES:                if (demux_mkv_read_cues (demuxer))                  res = 1;                break;              case MATROSKA_ID_TAGS:                if (demux_mkv_read_tags (demuxer))                  res = 1;                break;              case MATROSKA_ID_SEEKHEAD:                if (demux_mkv_read_seekhead (demuxer))                  res = 1;                break;              case MATROSKA_ID_CHAPTERS:                if (demux_mkv_read_chapters (demuxer))                  res = 1;                break;              }        }      stream_seek (s, saved_pos);    }  if (res)    {      /* If there was an error then try to skip this seek head. */      if (stream_seek (s, off))        res = 0;    }  else  if (length > 0)     stream_seek (s, stream_tell (s) + length);  mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing seek head ] ---------\n");  return res;}static intdemux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid);static intdemux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid);static intdemux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track, int sid);static voiddisplay_create_tracks (demuxer_t *demuxer){  mkv_demuxer_t *mkv_d = (mkv_demuxer_t *)demuxer->priv;  int i, vid=0, aid=0, sid=0;  for (i=0; i<mkv_d->num_tracks; i++)    {      char *type = "unknown", str[32];      *str = '\0';      switch (mkv_d->tracks[i]->type)        {        case MATROSKA_TRACK_VIDEO:          type = "video";          demux_mkv_open_video(demuxer, mkv_d->tracks[i], vid);          if (mkv_d->tracks[i]->name)            mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", vid, mkv_d->tracks[i]->name);          sprintf (str, "-vid %u", vid++);          break;        case MATROSKA_TRACK_AUDIO:          type = "audio";          demux_mkv_open_audio(demuxer, mkv_d->tracks[i], aid);          if (mkv_d->tracks[i]->name)            mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", aid, mkv_d->tracks[i]->name);          mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n", aid, mkv_d->tracks[i]->language);          sprintf (str, "-aid %u, -alang %.5s",aid++,mkv_d->tracks[i]->language);          break;        case MATROSKA_TRACK_SUBTITLE:          type = "subtitles";          demux_mkv_open_sub(demuxer, mkv_d->tracks[i], sid);          if (mkv_d->tracks[i]->name)

⌨️ 快捷键说明

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