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

📄 demux_mkv.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
  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;                      int i;                      len = ebml_read_length (s, &i);                      l = len + i;                      if (mkv_d->chapters == NULL)                        mkv_d->chapters = malloc (32*sizeof(*mkv_d->chapters));                      else if (!(mkv_d->num_chapters % 32))                        mkv_d->chapters = realloc (mkv_d->chapters,                                                   (mkv_d->num_chapters + 32)                                                   * sizeof(*mkv_d->chapters));                      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;                            default:                              ebml_read_skip (s, &l);                              break;                            }                          len -= l + il;                        }                      mkv_d->chapters[mkv_d->num_chapters].start = start;                      mkv_d->chapters[mkv_d->num_chapters].end = end;                      mp_msg(MSGT_DEMUX, MSGL_V,                             "[mkv] Chapter %u from %02d:%02d:%02d."                             "%03d to %02d:%02d:%02d.%03d\n",                             ++mkv_d->num_chapters,                             (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));                      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_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 = (off_t *) 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);  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 (length > 0)     stream_seek (s, stream_tell (s) + length);  mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing seek head ] ---------\n");  return res;}static voiddisplay_tracks (mkv_demuxer_t *mkv_d){  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";          if (identify)            mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", vid);          sprintf (str, "-vid %u", vid++);          break;        case MATROSKA_TRACK_AUDIO:          type = "audio";          if (identify)            {              mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", aid);              mp_msg(MSGT_GLOBAL, 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";          if (identify)            {              mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", sid);              mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SID_%d_LANG=%s\n", sid, mkv_d->tracks[i]->language);            }          sprintf (str, "-sid %u, -slang %.5s",sid++,mkv_d->tracks[i]->language);          break;        }      mp_msg(MSGT_DEMUX, MSGL_INFO, "[mkv] Track ID %u: %s (%s), %s\n",             mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id, str);    }}static intdemux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track){  BITMAPINFOHEADER *bih;  void *ImageDesc = NULL;  sh_video_t *sh_v;  if (track->ms_compat)  /* MS compatibility mode */    {      BITMAPINFOHEADER *src;      if (track->private_data == NULL          || track->private_size < sizeof (BITMAPINFOHEADER))        return 1;      src = (BITMAPINFOHEADER *) track->private_data;      bih = (BITMAPINFOHEADER *) malloc (track->private_size);      memset (bih, 0, track->private_size);      bih->biSize = le2me_32 (src->biSize);      bih->biWidth = le2me_32 (src->biWidth);      bih->biHeight = le2me_32 (src->biHeight);      bih->biPlanes = le2me_16 (src->biPlanes);      bih->biBitCount = le2me_16 (src->biBitCount);      bih->biCompression = le2me_32 (src->biCompression);      bih->biSizeImage = le2me_32 (src->biSizeImage);      bih->biXPelsPerMeter = le2me_32 (src->biXPelsPerMeter);      bih->biYPelsPerMeter = le2me_32 (src->biYPelsPerMeter);      bih->biClrUsed = le2me_32 (src->biClrUsed);      bih->biClrImportant = le2me_32 (src->biClrImportant);      memcpy((char *) bih + sizeof (BITMAPINFOHEADER),             (char *) src + sizeof (BITMAPINFOHEADER),             track->private_size - sizeof (BITMAPINFOHEADER));      if (track->v_width == 0)        track->v_width = bih->biWidth;      if (track->v_height == 0)        track->v_height = bih->biHeight;    }  else    {      bih = (BITMAPINFOHEADER *) malloc (sizeof (BITMAPINFOHEADER));      memset (bih, 0, sizeof (BITMAPINFOHEADER));      bih->biSize = sizeof (BITMAPINFOHEADER);      bih->biWidth = track->v_width;      bih->biHeight = track->v_height;      bih->biBitCount = 24;      bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;      if (track->private_size >= sizeof (real_video_props_t)          && (!strcmp (track->codec_id, MKV_V_REALV10)              || !strcmp (track->codec_id, MKV_V_REALV20)              || !strcmp (track->codec_id, MKV_V_REALV30)              || !strcmp (track->codec_id, MKV_V_REALV40)))        {          unsigned char *dst, *src;          real_video_props_t *rvp;          uint32_t type2;          rvp = (real_video_props_t *) track->private_data;          src = (unsigned char *) (rvp + 1);          bih = (BITMAPINFOHEADER *) realloc(bih,                                             sizeof (BITMAPINFOHEADER)+12);          bih->biSize = 48;          bih->biPlanes = 1;          type2 = be2me_32 (rvp->type2);          if (type2 == 0x10003000 || type2 == 0x10003001)            bih->biCompression=mmioFOURCC('R','V','1','3');          else            bih->biCompression=mmioFOURCC('R','V',track->codec_id[9],'0');          dst = (unsigned char *) (bih + 1);          ((unsigned int *) dst)[0] = be2me_32 (rvp->type1);          ((unsigned int *) dst)[1] = type2;          if (bih->biCompression <= 0x30335652 && type2 >= 0x20200002)            {              /* read secondary WxH for the cmsg24[] (see vd_realvid.c) */              ((unsigned short *)(bih+1))[4] = 4 * (unsigned short) src[0];              ((unsigned short *)(bih+1))[5] = 4 * (unsigned short) src[1];            }          else            memset(&dst[8], 0, 4);          track->realmedia = 1;#ifdef USE_QTX_CODECS        }      else if (track->private_size >= sizeof (ImageDescription)               && !strcmp(track->codec_id, MKV_V_QUICKTIME))        {          ImageDescriptionPtr idesc;          idesc = (ImageDescriptionPtr) track->private_data;          idesc->idSize = be2me_32 (idesc->idSize);          idesc->cType = be2me_32 (idesc->cType);          idesc->version = be2me_16 (idesc->version);          idesc->revisionLevel = be2me_16 (idesc->revisionLevel);          idesc->vendor = be2me_32 (idesc->vendor);          idesc->temporalQuality = be2me_32 (idesc->temporalQuality);          idesc->spatialQuality = be2me_32 (idesc->spatialQuality);          idesc->width = be2me_16 (idesc->width);          idesc->height = be2me_16 (idesc->height);          idesc->hRes = be2me_32 (idesc->hRes);          idesc->vRes = be2me_32 (idesc->vRes);          idesc->dataSize = be2me_32 (idesc->dataSize);          idesc->frameCount = be2me_16 (idesc->frameCount);          idesc->depth = be2me_16 (idesc->depth);          idesc->clutID = be2me_16 (idesc->clutID);          bih->biPlanes = 1;          bih->biCompression = idesc->cType;          ImageDesc = idesc;#endif /* USE_QTX_CODECS */        }      else if (!strcmp(track->codec_id, MKV_V_MPEG1))        {          bih->biCompression = mmioFOURCC('m', 'p', 'g', '1');          track->reorder_timecodes = 1;        }      else if (!strcmp(track->codec_id, MKV_V_MPEG2))        {          bih->biCompression = mmioFOURCC('m', 'p', 'g', '2');          track->reorder_timecodes = 1;        }      else if (!strcmp(track->codec_id, MKV_V_MPEG4_AVC))        {          bih->biCompression = mmioFOURCC('a', 'v', 'c', '1');          if (track->private_data && (track->private_size > 0))            {              bih->biSize += track->private_size;              bih = (BITMAPINFOHEADER *) realloc (bih, bih->biSize);              memcpy (bih + 1, track->private_data, track->private_size);            }          track->reorder_timecodes = 1;        }      else        {          mp_msg (MSGT_DEMUX,MSGL_WARN,"[mkv] Unknown/unsupported CodecID "                  "(%s) or missing/bad CodecPrivate data (track %u).\n",                  track->codec_id, track->tnum);          free(bih);          return 1;        }    }  sh_v = new_sh_video (demuxer, track->tnum);  sh_v->bih = bih;  sh_v->format = sh_v->bih->biCompression;  if (track->v_frate == 0.0)    track->v_frate = 25.0;  sh_v->fps = track->v_frate;  sh_v->frametime = 1 / track->v_frate;  sh_v->aspect = 0;  if (!track->realmedia)    {      sh_v->disp_w = track->v_width;      sh_v->disp_h = track->v_height;      if (track->v_dheight)      sh_v->aspect = (float)track->v_dwidth / (float)track->v_dheight;    }  else    {      // vd_realvid.c will set aspect to disp_w/disp_h and rederive      // disp_w and disp_h from the RealVideo stream contents returned      // by the Real DLLs. If DisplayWidth/DisplayHeight was not set in      // the Matroska file then it has already been set to PixelWidth/Height      // by check_track_information.      sh_v->disp_w = track->v_dwidth;

⌨️ 快捷键说明

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