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 + -
显示快捷键?