📄 demux_mkv.c
字号:
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){ sh_audio_t *sh_a = new_sh_audio(demuxer, track->tnum); demux_packet_t *dp; int i; sh_a->ds = demuxer->audio; sh_a->wf = (WAVEFORMATEX *) malloc (sizeof (WAVEFORMATEX)); if (track->ms_compat && (track->private_size >= sizeof(WAVEFORMATEX))) { WAVEFORMATEX *wf = (WAVEFORMATEX *)track->private_data; sh_a->wf = (WAVEFORMATEX *) 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)) track->a_formattag = mmioFOURCC('M', 'P', '4', 'A'); else if (!strcmp(track->codec_id, MKV_A_VORBIS)) { unsigned char *c; uint32_t offset, length; if (track->private_data == NULL) return 1; c = (unsigned char *) track->private_data; if (*c != 2) { mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] Vorbis track does not " "contain valid headers.\n"); return 1; } offset = 1; for (i=0; i < 2; i++) { length = 0; while (c[offset] == (unsigned char) 0xFF && length < track->private_size) { length += 255; offset++; } if (offset >= (track->private_size - 1)) { mp_msg (MSGT_DEMUX, MSGL_WARN, "[mkv] Vorbis track " "does not contain valid headers.\n"); return 1; } length += c[offset]; offset++; track->header_sizes[i] = length; } track->headers[0] = &c[offset]; track->headers[1] = &c[offset + track->header_sizes[0]]; track->headers[2] = &c[offset + track->header_sizes[0] + track->header_sizes[1]]; track->header_sizes[2] = track->private_size - offset - track->header_sizes[0] - track->header_sizes[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, "[mkv] FLAC track does not " "contain valid headers.\n"); return 1; } track->a_formattag = mmioFOURCC ('f', 'L', 'a', 'C'); } else if (track->private_size >= sizeof (real_audio_v4_props_t)) { 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, "[mkv] Unknown/unsupported audio " "codec ID '%s' for track %u or missing/faulty private " "codec data.\n", track->codec_id, track->tnum); free_sh_audio (sh_a); 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 */ { sh_a->wf->nAvgBytesPerSec = 16000; sh_a->wf->nBlockAlign = 1536; } 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=(unsigned char *)malloc(track->private_size); 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; /* 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 = (unsigned char *) malloc (5); 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 */ { for (i=0; i < 3; i++) { dp = new_demux_packet (track->header_sizes[i]); memcpy (dp->buffer,track->headers[i],track->header_sizes[i]); dp->pts = 0; dp->flags = 0; ds_add_packet (demuxer->audio, dp); } } else if (track->private_size >= sizeof(real_audio_v4_props_t) && !strncmp (track->codec_id, MKV_A_REALATRC, 7)) { /* Common initialization for all RealAudio codecs */ real_audio_v4_props_t *ra4p; real_audio_v5_props_t *ra5p; unsigned char *src; int codecdata_length, version; ra4p = (real_audio_v4_props_t *) track->private_data; ra5p = (real_audio_v5_props_t *) track->private_data; sh_a->wf->nAvgBytesPerSec = 0; /* FIXME !? */ sh_a->wf->nBlockAlign = be2me_16 (ra4p->frame_size); version = be2me_16 (ra4p->version1); if (version == 4) { src = (unsigned char *) (ra4p + 1); src += src[0] + 1; src += src[0] + 1; } else src = (unsigned char *) (ra5p + 1); src += 3; if (version == 5) src++; codecdata_length = be2me_32 (*(uint32_t *)src); src += 4; sh_a->wf->cbSize = 10 + codecdata_length; sh_a->wf = (WAVEFORMATEX *) realloc (sh_a->wf, sizeof (WAVEFORMATEX) + sh_a->wf->cbSize); ((short *)(sh_a->wf + 1))[0] = be2me_16 (ra4p->sub_packet_size); ((short *)(sh_a->wf + 1))[1] = be2me_16 (ra4p->sub_packet_h); ((short *)(sh_a->wf + 1))[2] = be2me_16 (ra4p->flavor); ((short *)(sh_a->wf + 1))[3] = be2me_32 (ra4p->coded_frame_size); ((short *)(sh_a->wf + 1))[4] = codecdata_length; memcpy(((char *)(sh_a->wf + 1)) + 10, src, codecdata_length); track->realmedia = 1; } else if (!strcmp(track->codec_id, MKV_A_FLAC) || (track->a_formattag == 0xf1ac)) { unsigned char *ptr; int size; free(sh_a->wf); sh_a->wf = NULL; if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C')) { ptr = (unsigned char *)track->private_data; size = track->private_size; } else { sh_a->format = mmioFOURCC('f', 'L', 'a', 'C'); ptr = (unsigned char *) track->private_data + sizeof (WAVEFORMATEX); size = track->private_size - sizeof (WAVEFORMATEX); } if (size < 4 || ptr[0] != 'f' || ptr[1] != 'L' || ptr[2] != 'a' || ptr[3] != 'C') { dp = new_demux_packet (4); memcpy (dp->buffer, "fLaC", 4); } else { dp = new_demux_packet (size); memcpy (dp->buffer, ptr, size); } dp->pts = 0; dp->flags = 0; ds_add_packet (demuxer->audio, dp); } else if (!track->ms_compat || (track->private_size < sizeof(WAVEFORMATEX))) { free_sh_audio (sh_a); return 1; } return 0;}/** \brief Parse the private data for VobSub subtitle tracks. This function tries to parse the private data for all VobSub tracks. The private data contains the normal text from the original .idx file. Things like the palette, subtitle dimensions and custom colors are stored here. \param demuxer The generic demuxer.*/static voiddemux_mkv_parse_vobsub_data (demuxer_t *demuxer){ mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; mkv_track_t *track; int i, m, size; uint8_t *buffer; for (i = 0; i < mkv_d->num_tracks; i++) { track = mkv_d->tracks[i]; if ((track->type != MATROSKA_TRACK_SUBTITLE) || (track->subtitle_type != MATROSKA_SUBTYPE_VOBSUB)) continue; size = track->private_size; m = demux_mkv_decode (track,track->private_data,&buffer,&size,2); if (buffer && m) { free (track->private_data); track->private_data = buffer; } if (!demux_mkv_parse_idx (track)) { free (track->private_data); track->private_data = NULL; track->private_size = 0; } }}static intdemux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track){ if (track->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN) { if (track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB) { if (track->private_data != NULL) { demuxer->sub->sh = malloc(sizeof(mkv_sh_sub_t)); if (demuxer->sub->sh != NULL) memcpy(demuxer->sub->sh, &track->sh_sub, sizeof(mkv_sh_sub_t)); } } } else { mp_msg (MSGT_DEMUX, MSGL_ERR, "[mkv] Subtitle type '%s' is not " "supported.\n", track->codec_id); return 1; } return 0;}void demux_mkv_seek (demuxer_t *demuxer, float rel_seek_secs, int flags);/** \brief Given a matroska track number, find the subtitle number that mplayer would ask for. * \param d The demuxer for which the subtitle id should be returned. * \param num The matroska track number we are looking up. */static int demux_mkv_sub_reverse_id(mkv_demuxer_t *d, int num){ int i, id; for (i=0, id=0; i < d->num_tracks; i++) if (d->tracks[i] != NULL && d->tracks[i]->type == MATROSKA_TRACK_SUBTITLE) { if (d->tracks[i]->tnum == num) return id; id++; } return -1;}intdemux_mkv_open (demuxer_t *demuxer){ stream_t *s = demuxer->stream; mkv_demuxer_t *mkv_d; mkv_track_t *track; int i, version, cont = 0; char *st
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -