demux_mkv.c

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

C
2,147
字号
            mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", sid, mkv_d->tracks[i]->name);          mp_msg(MSGT_IDENTIFY, 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;        }      if (mkv_d->tracks[i]->name)        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_TrackIDName,             mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id, mkv_d->tracks[i]->name, str);      else        mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_TrackID,             mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id, str);    }}typedef struct {  char *id;  int fourcc;  int extradata;} videocodec_info_t;static const videocodec_info_t vinfo[] = {  { MKV_V_MPEG1,     mmioFOURCC('m', 'p', 'g', '1'), 0 },  { MKV_V_MPEG2,     mmioFOURCC('m', 'p', 'g', '2'), 0 },  { MKV_V_MPEG4_SP,  mmioFOURCC('m', 'p', '4', 'v'), 1 },  { MKV_V_MPEG4_ASP, mmioFOURCC('m', 'p', '4', 'v'), 1 },  { MKV_V_MPEG4_AP,  mmioFOURCC('m', 'p', '4', 'v'), 1 },  { MKV_V_MPEG4_AVC, mmioFOURCC('a', 'v', 'c', '1'), 1 },  { MKV_V_THEORA,    mmioFOURCC('t', 'h', 'e', 'o'), 1 },  { NULL, 0, 0 }};static intdemux_mkv_open_video (demuxer_t *demuxer, mkv_track_t *track, int vid){  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 = calloc (1, 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 = calloc (1, 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 >= RVPROPERTIES_SIZE          && (!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;          uint32_t type2;          unsigned int cnt;          src = track->private_data + RVPROPERTIES_SIZE;          cnt = track->private_size - RVPROPERTIES_SIZE;          bih = realloc(bih, sizeof (BITMAPINFOHEADER)+8+cnt);          bih->biSize = 48+cnt;          bih->biPlanes = 1;          type2 = AV_RB32(src - 4);          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);          // copy type1 and type2 info from rv properties          memcpy(dst, src - 8, 8);          stream_read(demuxer->stream, dst+8, cnt);          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        {          const videocodec_info_t *vi = vinfo;          while (vi->id && strcmp(vi->id, track->codec_id)) vi++;          bih->biCompression = vi->fourcc;          if (vi->extradata && track->private_data && (track->private_size > 0))            {              bih->biSize += track->private_size;              bih = realloc (bih, bih->biSize);              memcpy (bih + 1, track->private_data, track->private_size);            }          track->reorder_timecodes = !correct_pts;          if (!vi->id) {              mp_msg (MSGT_DEMUX,MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCodecID,                      track->codec_id, track->tnum);              free(bih);              return 1;          }        }    }  sh_v = new_sh_video_vid (demuxer, track->tnum, vid);  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;      sh_v->disp_h = track->v_dheight;    }  sh_v->ImageDesc = ImageDesc;  mp_msg (MSGT_DEMUX, MSGL_V, "[mkv] Aspect: %f\n", sh_v->aspect);  sh_v->ds = demuxer->video;  return 0;}static intdemux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track, int aid){  mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;  sh_audio_t *sh_a = new_sh_audio_aid(demuxer, track->tnum, aid);  demux_packet_t *dp;  if(!sh_a) return 1;  mkv_d->audio_tracks[mkv_d->last_aid] = track->tnum;  sh_a->ds = demuxer->audio;  sh_a->wf = malloc (sizeof (WAVEFORMATEX));  if (track->ms_compat && (track->private_size >= sizeof(WAVEFORMATEX)))    {      WAVEFORMATEX *wf = (WAVEFORMATEX *)track->private_data;      sh_a->wf = realloc(sh_a->wf, track->private_size);      sh_a->wf->wFormatTag = le2me_16 (wf->wFormatTag);      sh_a->wf->nChannels = le2me_16 (wf->nChannels);      sh_a->wf->nSamplesPerSec = le2me_32 (wf->nSamplesPerSec);      sh_a->wf->nAvgBytesPerSec = le2me_32 (wf->nAvgBytesPerSec);      sh_a->wf->nBlockAlign = le2me_16 (wf->nBlockAlign);      sh_a->wf->wBitsPerSample = le2me_16 (wf->wBitsPerSample);      sh_a->wf->cbSize = track->private_size - sizeof(WAVEFORMATEX);      memcpy(sh_a->wf + 1, wf + 1, track->private_size - sizeof(WAVEFORMATEX));      if (track->a_sfreq == 0.0)        track->a_sfreq = sh_a->wf->nSamplesPerSec;      if (track->a_channels == 0)        track->a_channels = sh_a->wf->nChannels;      if (track->a_bps == 0)        track->a_bps = sh_a->wf->wBitsPerSample;      track->a_formattag = sh_a->wf->wFormatTag;    }  else    {      memset(sh_a->wf, 0, sizeof (WAVEFORMATEX));      if (!strcmp(track->codec_id, MKV_A_MP3) ||          !strcmp(track->codec_id, MKV_A_MP2))        track->a_formattag = 0x0055;      else if (!strncmp(track->codec_id, MKV_A_AC3, strlen(MKV_A_AC3)))        track->a_formattag = 0x2000;      else if (!strcmp(track->codec_id, MKV_A_DTS))        track->a_formattag = 0x2001;      else if (!strcmp(track->codec_id, MKV_A_PCM) ||               !strcmp(track->codec_id, MKV_A_PCM_BE))        track->a_formattag = 0x0001;      else if (!strcmp(track->codec_id, MKV_A_AAC_2MAIN) ||               !strncmp(track->codec_id, MKV_A_AAC_2LC,                        strlen(MKV_A_AAC_2LC)) ||               !strcmp(track->codec_id, MKV_A_AAC_2SSR) ||               !strcmp(track->codec_id, MKV_A_AAC_4MAIN) ||               !strncmp(track->codec_id, MKV_A_AAC_4LC,                        strlen(MKV_A_AAC_4LC)) ||               !strcmp(track->codec_id, MKV_A_AAC_4SSR) ||               !strcmp(track->codec_id, MKV_A_AAC_4LTP) ||               !strcmp(track->codec_id, MKV_A_AAC))        track->a_formattag = mmioFOURCC('M', 'P', '4', 'A');      else if (!strcmp(track->codec_id, MKV_A_VORBIS))        {          if (track->private_data == NULL)            return 1;          track->a_formattag = mmioFOURCC('v', 'r', 'b', 's');        }      else if (!strcmp(track->codec_id, MKV_A_QDMC))        track->a_formattag = mmioFOURCC('Q', 'D', 'M', 'C');      else if (!strcmp(track->codec_id, MKV_A_QDMC2))        track->a_formattag = mmioFOURCC('Q', 'D', 'M', '2');      else if (!strcmp(track->codec_id, MKV_A_FLAC))        {          if (track->private_data == NULL || track->private_size == 0)            {              mp_msg (MSGT_DEMUX, MSGL_WARN,                      MSGTR_MPDEMUX_MKV_FlacTrackDoesNotContainValidHeaders);              return 1;            }          track->a_formattag = mmioFOURCC ('f', 'L', 'a', 'C');        }      else if (track->private_size >= RAPROPERTIES4_SIZE)        {          if (!strcmp(track->codec_id, MKV_A_REAL28))            track->a_formattag = mmioFOURCC('2', '8', '_', '8');          else if (!strcmp(track->codec_id, MKV_A_REALATRC))            track->a_formattag = mmioFOURCC('a', 't', 'r', 'c');          else if (!strcmp(track->codec_id, MKV_A_REALCOOK))            track->a_formattag = mmioFOURCC('c', 'o', 'o', 'k');          else if (!strcmp(track->codec_id, MKV_A_REALDNET))            track->a_formattag = mmioFOURCC('d', 'n', 'e', 't');          else if (!strcmp(track->codec_id, MKV_A_REALSIPR))            track->a_formattag = mmioFOURCC('s', 'i', 'p', 'r');        }      else        {          mp_msg (MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownAudioCodec,                  track->codec_id, track->tnum);          free_sh_audio(demuxer, track->tnum);          return 1;        }    }  sh_a->format = track->a_formattag;  sh_a->wf->wFormatTag = track->a_formattag;  sh_a->channels = track->a_channels;  sh_a->wf->nChannels = track->a_channels;  sh_a->samplerate = (uint32_t) track->a_sfreq;  sh_a->wf->nSamplesPerSec = (uint32_t) track->a_sfreq;  if (track->a_bps == 0)    {      sh_a->samplesize = 2;      sh_a->wf->wBitsPerSample = 16;    }  else    {      sh_a->samplesize = track->a_bps / 8;      sh_a->wf->wBitsPerSample = track->a_bps;    }  if (track->a_formattag == 0x0055)  /* MP3 || MP2 */    {      sh_a->wf->nAvgBytesPerSec = 16000;      sh_a->wf->nBlockAlign = 1152;    }  else if ((track->a_formattag == 0x2000) || /* AC3 */           (track->a_formattag == 0x2001)) /* DTS */    {      free(sh_a->wf);      sh_a->wf = NULL;    }  else if (track->a_formattag == 0x0001)  /* PCM || PCM_BE */    {      sh_a->wf->nAvgBytesPerSec = sh_a->channels * sh_a->samplerate*2;      sh_a->wf->nBlockAlign = sh_a->wf->nAvgBytesPerSec;      if (!strcmp(track->codec_id, MKV_A_PCM_BE))        sh_a->format = mmioFOURCC('t', 'w', 'o', 's');    }  else if (!strcmp(track->codec_id, MKV_A_QDMC) ||           !strcmp(track->codec_id, MKV_A_QDMC2))    {      sh_a->wf->nAvgBytesPerSec = 16000;      sh_a->wf->nBlockAlign = 1486;      track->fix_i_bps = 1;      track->qt_last_a_pts = 0.0;      if (track->private_data != NULL)        {          sh_a->codecdata=malloc(track->private_size);          sh_a->codecdatatype = 1;          memcpy (sh_a->codecdata, track->private_data,                  track->private_size);          sh_a->codecdata_len = track->private_size;        }    }  else if (track->a_formattag == mmioFOURCC('M', 'P', '4', 'A'))    {      int profile, srate_idx;      sh_a->wf->nAvgBytesPerSec = 16000;      sh_a->wf->nBlockAlign = 1024;      if (!strcmp (track->codec_id, MKV_A_AAC) &&          (NULL != track->private_data))        {          sh_a->codecdata=malloc(track->private_size);          sh_a->codecdatatype = 1;          memcpy (sh_a->codecdata, track->private_data,                  track->private_size);          sh_a->codecdata_len = track->private_size;          return 0;        }      /* Recreate the 'private data' */      /* which faad2 uses in its initialization */      srate_idx = aac_get_sample_rate_index (sh_a->samplerate);      if (!strncmp (&track->codec_id[12], "MAIN", 4))        profile = 0;      else if (!strncmp (&track->codec_id[12], "LC", 2))        profile = 1;      else if (!strncmp (&track->codec_id[12], "SSR", 3))        profile = 2;      else        profile = 3;      sh_a->codecdata = malloc (5);      sh_a->codecdatatype = 1;      sh_a->codecdata[0] = ((profile+1) << 3) | ((srate_idx&0xE) >> 1);      sh_a->codecdata[1] = ((srate_idx&0x1)<<7)|(track->a_channels<<3);      if (strstr(track->codec_id, "SBR") != NULL)        {          /* HE-AAC (aka SBR AAC) */          sh_a->codecdata_len = 5;          sh_a->samplerate *= 2;          sh_a->wf->nSamplesPerSec *= 2;          srate_idx = aac_get_sample_rate_index(sh_a->samplerate);          sh_a->codecdata[2] = AAC_SYNC_EXTENSION_TYPE >> 3;          sh_a->codecdata[3] = ((AAC_SYNC_EXTENSION_TYPE&0x07)<<5) | 5;          sh_a->codecdata[4] = (1 << 7) | (srate_idx << 3);          track->default_duration = 1024.0 / (sh_a->samplerate / 2);        }      else        {          sh_a->codecdata_len = 2;          track->default_duration = 1024.0 / (float)sh_a->samplerate;        }    }  else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's'))  /* VORBIS */    {      sh_a->wf->cbSize = track->private_size;      sh_a->wf = realloc(sh_a->wf, sizeof(WAVEFORMATEX) + sh_a->wf->cbSize);      memcpy((unsigned char *) (sh_a->wf+1), track->private_data, sh_a->wf->cbSize);    }  else if (track->private_size >= RAPROPERTIES4_SIZE           && !strncmp (track->codec_id, MKV_A_REALATRC, 7))    {      /* Common initialization for all RealAudio codecs */      unsigned char *src = track->private_data;      int codecdata_length, version;      int flavor;      sh_a->wf->nAvgBytesPerSec = 0;  /* FIXME !? */      version = AV_RB16(src + 4);      flavor = AV_RB16(src + 22);      track->coded_framesize = AV_RB32(src + 24);      track->sub_packet_h = AV_RB16(src + 40);      sh_a->wf->nBlockAlign =      track->audiopk_size = AV_RB16(src + 42);      track->sub_packet_size = AV_RB16(src + 44);      if (version == 4)        {          src += RAPROPERTIES4_SIZE;          src += src[0] + 1;          src += src[0] + 1;        }      else        src += RAPROPERTIES5_SIZE;      src += 3;      if (version == 5)        src++;      codecdata_length = AV_RB32(src);      src += 4;      sh_a->wf->cbSize = codecdata_length;      sh_a->wf = realloc (sh_a->wf,                          sizeof (WAVEFORMATEX) +                          sh_a->wf-

⌨️ 快捷键说明

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