void extract_tags(struct fidinfo *fidinfo, char *buf, size_t len) { int i; char *cp; uint16_t num_tags; uint16_t tag_size; uint16_t value_size; uint16_t unknown; char *tagname; cp = buf; num_tags = *(uint16_t *)cp; le2me_16(num_tags); cp += sizeof(uint16_t); for (i=0; i<num_tags; i++) { tag_size = *(uint16_t *)cp; le2me_16(tag_size); cp += sizeof(uint16_t); tagname = utf16tointernal(cp, tag_size); cp += tag_size; unknown = *(uint16_t *)cp; cp += sizeof(uint16_t); value_size = *(uint16_t *)cp; cp += sizeof(uint16_t); parsewmatag(fidinfo, tagname, cp, value_size); cp += value_size; } }
static int net_stream_fill_buffer(client_t* cl,uint16_t max_len) { int r; mp_net_stream_packet_t *pack; if(!cl->stream) { if(!write_error(cl->fd,"No stream is currently opened\n")) return 0; return 1; } if(max_len == 0) { if(!write_error(cl->fd,"Fill buffer called with 0 lenght\n")) return 0; return 1; } pack = malloc(max_len + sizeof(mp_net_stream_packet_t)); pack->cmd = NET_STREAM_OK; r = stream_read(cl->stream,pack->data,max_len); pack->len = le2me_16(r + sizeof(mp_net_stream_packet_t)); if(!net_write(cl->fd,(char*)pack,le2me_16(pack->len))) { free(pack); return 0; } free(pack); return 1; }
static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { int retval; char path[100]; int fd; short vendor, device; sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd == -1) { retval=0xFFFF; } else if (pread(fd, &vendor, 2, PCI_VENDOR_ID) == 2 && pread(fd, &device, 2, PCI_DEVICE_ID) == 2) { vendor = le2me_16(vendor); device = le2me_16(device); retval = vendor + (device<<16); /*no worries about byte order, all ppc are bigendian*/ } else { retval = 0xFFFF; } if (fd > 0) { close(fd); } return retval; }
void _x_waveformatex_le2me( xine_waveformatex *wavex ) { wavex->wFormatTag = le2me_16(wavex->wFormatTag); wavex->nChannels = le2me_16(wavex->nChannels); wavex->nSamplesPerSec = le2me_32(wavex->nSamplesPerSec); wavex->nAvgBytesPerSec = le2me_32(wavex->nAvgBytesPerSec); wavex->nBlockAlign = le2me_16(wavex->nBlockAlign); wavex->wBitsPerSample = le2me_16(wavex->wBitsPerSample); wavex->cbSize = le2me_16(wavex->cbSize); }
static int fill_buffer(stream_t *s, char *buffer, int max_len) { cdda_priv *p = (cdda_priv *)s->priv; int16_t *buf; int i; if (max_len < CDIO_CD_FRAMESIZE_RAW) return -1; if ((p->sector < p->start_sector) || (p->sector > p->end_sector)) { return 0; } buf = paranoia_read(p->cdp, cdparanoia_callback); if (!buf) return 0; #if BYTE_ORDER == BIG_ENDIAN for (i = 0; i < CDIO_CD_FRAMESIZE_RAW / 2; i++) buf[i] = le2me_16(buf[i]); #endif p->sector++; memcpy(buffer, buf, CDIO_CD_FRAMESIZE_RAW); for (i = 0; i < p->cd->tracks; i++) { if (p->cd->disc_toc[i].dwStartSector == p->sector - 1) { print_track_info(s, i + 1); break; } } return CDIO_CD_FRAMESIZE_RAW; }
void _x_bmiheader_le2me( xine_bmiheader *bih ) { /* OBS: fourcc must be read using machine endianness * so don't play with biCompression here! */ bih->biSize = le2me_32(bih->biSize); bih->biWidth = le2me_32(bih->biWidth); bih->biHeight = le2me_32(bih->biHeight); bih->biPlanes = le2me_16(bih->biPlanes); bih->biBitCount = le2me_16(bih->biBitCount); bih->biSizeImage = le2me_32(bih->biSizeImage); bih->biXPelsPerMeter = le2me_32(bih->biXPelsPerMeter); bih->biYPelsPerMeter = le2me_32(bih->biYPelsPerMeter); bih->biClrUsed = le2me_32(bih->biClrUsed); bih->biClrImportant = le2me_32(bih->biClrImportant); }
static int sol_probe(AVProbeData *p) { /* check file header */ uint16_t magic; magic=le2me_16(*((uint16_t*)p->buf)); if ((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) && p->buf[2] == 'S' && p->buf[3] == 'O' && p->buf[4] == 'L' && p->buf[5] == 0) return AVPROBE_SCORE_MAX; else return 0; }
static void cdparanoia_callback(long inpos, int function) { #else static void cdparanoia_callback(long int inpos, paranoia_cb_mode_t function) { #endif } static int fill_buffer(stream_t* s, char* buffer, int max_len) { cdda_priv* p = (cdda_priv*)s->priv; cd_track_t *cd_track; int16_t * buf; int i; buf = paranoia_read(p->cdp,cdparanoia_callback); if (!buf) return 0; #ifdef WORDS_BIGENDIAN for(i=0;i<CD_FRAMESIZE_RAW/2;i++) buf[i]=le2me_16(buf[i]); #endif p->sector++; s->pos = p->sector*CD_FRAMESIZE_RAW; memcpy(buffer,buf,CD_FRAMESIZE_RAW); if((p->sector < p->start_sector) || (p->sector >= p->end_sector)) { s->eof = 1; return 0; } for(i=0;i<p->cd->tracks;i++){ if(p->cd->disc_toc[i].dwStartSector==p->sector-1) { cd_track = cd_info_get_track(p->cd_info, i+1); //printf("Track %d, sector=%d\n", i, p->sector-1); if( cd_track!=NULL ) { mp_msg(MSGT_SEEK, MSGL_INFO, "\n%s\n", cd_track->name); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CDDA_TRACK=%d\n", cd_track->track_nb); } break; } } return CD_FRAMESIZE_RAW; }
static int fill_buffer(stream_t *s, char* buffer, int max_len){ uint16_t len = le2me_16(max_len); mp_net_stream_packet_t* pack; pack = send_net_stream_cmd(s,NET_STREAM_FILL_BUFFER,(char*)&len,2); if(!pack) { return -1; } len = pack->len - sizeof(mp_net_stream_packet_t); if(len > max_len) { mp_msg(MSGT_STREAM,MSGL_ERR, "Got a too big a packet %d / %d\n",len,max_len); free(pack); return 0; } if(len > 0) memcpy(buffer,pack->data,len); free(pack); return len; }
// plays 'len' bytes of 'data' // it should round it down to outburst*n // return: number of bytes played static int play(void* data,int len,int flags){ // let libaf to do the conversion... #if 0 //#ifdef WORDS_BIGENDIAN if (ao_data.format == AFMT_S16_LE) { unsigned short *buffer = (unsigned short *) data; register int i; for(i = 0; i < len/2; ++i) { buffer[i] = le2me_16(buffer[i]); } } #endif //printf("PCM: Writing chunk!\n"); fwrite(data,len,1,fp); if(ao_pcm_waveheader) wavhdr.data_length += len; return len; }
int handle_client(client_t* cl,mp_net_stream_packet_t* pack) { if(!pack) return 0; switch(pack->cmd) { case NET_STREAM_OPEN: if(((char*)pack)[pack->len-1] != '\0') { mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid open packet\n"); return 0; } return net_stream_open(cl,pack->data); case NET_STREAM_FILL_BUFFER: if(pack->len != sizeof(mp_net_stream_packet_t) + 2) { mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n"); return 0; } return net_stream_fill_buffer(cl,le2me_16(*((uint16_t*)pack->data))); case NET_STREAM_SEEK: if(pack->len != sizeof(mp_net_stream_packet_t) + 8) { mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n"); return 0; } return net_stream_seek(cl,le2me_64(*((uint64_t*)pack->data))); case NET_STREAM_RESET: return net_stream_reset(cl); case NET_STREAM_CLOSE: if(pack->len != sizeof(mp_net_stream_packet_t)){ mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n"); return 0; } return net_stream_close(cl); default: mp_msg(MSGT_NETST,MSGL_WARN,"Got unknown command %d\n",pack->cmd); if(!write_error(cl->fd,"Unknown command\n")) return 0; } return 0; }
// open & setup audio device // return: 1=success 0=fail static int init(int rate,int channels,int format,int flags){ int bits; opt_t subopts[] = { {"waveheader", OPT_ARG_BOOL, &ao_pcm_waveheader, NULL}, {"file", OPT_ARG_MSTRZ, &ao_outputfilename, NULL}, {"fast", OPT_ARG_BOOL, &fast, NULL}, {NULL} }; // set defaults ao_pcm_waveheader = 1; if (subopt_parse(ao_subdevice, subopts) != 0) { return 0; } if (!ao_outputfilename){ ao_outputfilename = strdup(ao_pcm_waveheader?"audiodump.wav":"audiodump.pcm"); } /* bits is only equal to format if (format == 8) or (format == 16); this means that the following "if" is a kludge and should really be a switch to be correct in all cases */ bits=8; switch(format){ case AF_FORMAT_S8: format=AF_FORMAT_U8; case AF_FORMAT_U8: break; default: format=AF_FORMAT_S16_LE; bits=16; break; } ao_data.outburst = 65536; ao_data.buffersize= 2*65536; ao_data.channels=channels; ao_data.samplerate=rate; ao_data.format=format; ao_data.bps=channels*rate*(bits/8); wavhdr.riff = le2me_32(WAV_ID_RIFF); wavhdr.wave = le2me_32(WAV_ID_WAVE); wavhdr.fmt = le2me_32(WAV_ID_FMT); wavhdr.fmt_length = le2me_32(16); wavhdr.fmt_tag = le2me_16(WAV_ID_PCM); wavhdr.channels = le2me_16(ao_data.channels); wavhdr.sample_rate = le2me_32(ao_data.samplerate); wavhdr.bytes_per_second = le2me_32(ao_data.bps); wavhdr.bits = le2me_16(bits); wavhdr.block_align = le2me_16(ao_data.channels * (bits / 8)); wavhdr.data = le2me_32(WAV_ID_DATA); wavhdr.data_length=le2me_32(0x7ffff000); wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8; mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_PCM_FileInfo, ao_outputfilename, (ao_pcm_waveheader?"WAVE":"RAW PCM"), rate, (channels > 1) ? "Stereo" : "Mono", af_fmt2str_short(format)); mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_PCM_HintInfo); fp = fopen(ao_outputfilename, "wb"); if(fp) { if(ao_pcm_waveheader){ /* Reserve space for wave header */ fwrite(&wavhdr,sizeof(wavhdr),1,fp); wavhdr.file_length=wavhdr.data_length=0; } return 1; } mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_PCM_CantOpenOutputFile, ao_outputfilename); return 0; }
/* * choose best audio and video streams, below bw. * 'header' is an asf header, and 'asf_header_size' is its size. * the result will be in 'streams' * return value: 1 ... success * -1 ... failed */ int asf_choose_best_streams(const uint8_t *header, int asf_header_size, int bw, struct asf_streams_t *streams) { int i = 0,pos = 0,start = 0; int *v_rates = NULL, *a_rates = NULL; int v_rate = 0, a_rate = 0, v_idx = -1, a_idx = -1; /* header is entire ASF header, including very first asf_header_t. */ pos = sizeof(struct asf_header_t); start = pos; /* choose best (fastest) streams */ while((pos = find_asf_guid(header,pos,asf_stream_header_guid,asf_header_size)) >= 0) { struct asf_stream_header_t *streamh = (struct asf_stream_header_t *)(header + pos); pos += sizeof(struct asf_stream_header_t); if(pos > asf_header_size) /* error */ return -1; /* get ASF GUID PREFIX (first 4 byte of GUID) */ switch(get32_le(streamh->type)) { case ASF_AUDIO_STREAM: /* audio stream */ display(MSDL_VER,"audio stream detected!!!!\n"); if(streams->audio_streams == NULL) { /* no audio stream registerd yet */ streams->audio_streams = (int *)xmalloc(sizeof(int)); streams->n_audio = 1; } else { /* more audio streams.!! */ streams->n_audio++; streams->audio_streams = (int *)xrealloc(streams->audio_streams, streams->n_audio * sizeof(int)); } streams->audio_streams[streams->n_audio - 1] = le2me_16(streamh->stream_no); break; case ASF_VIDEO_STREAM: /* video streams */ display(MSDL_VER,"video stream detected!!!!\n"); if(streams->video_streams == NULL) { /* no video stream registerd yet */ streams->video_streams = (int *)xmalloc(sizeof(int)); streams->n_video = 1; } else { /* more video streams.!! */ streams->n_video++; streams->video_streams = (int *)xrealloc(streams->video_streams, streams->n_video * sizeof(int)); } streams->video_streams[streams->n_video - 1] = le2me_16(streamh->stream_no); break; case ASF_COMMAND_MEDIA_STREAM: /* Command media stream... whatever*/ display(MSDL_VER,"Command media stream detected, but ignore this.\n"); break; case ASF_FILE_TRANSFER_MEDIA_STREAM: /* File transfer media stream... I don't know what the heck this is.*/ display(MSDL_VER,"File transfer stream detected, but ignore this.\n"); break; } } a_rates = (int *)xmalloc(streams->n_audio * sizeof(int)); v_rates = (int *)xmalloc(streams->n_video * sizeof(int)); pos = find_asf_guid(header,start,asf_stream_group_guid,asf_header_size); if(pos >= 0) { /* stream bitrate proterties object */ int stream_count = 0; uint8_t *ptr = (uint8_t *)header + pos; display(MSDL_VER,"stream bitrate properties object\n"); stream_count = get16_le(ptr); /* little endian. */ ptr += sizeof(uint16_t); if(ptr > header + asf_header_size) goto failed; display(MSDL_VER,"stream count = [0x%x] [%u]\n",stream_count,stream_count); display(MSDL_VER,"audio streams: %d, video streams: %d\n", streams->n_audio,streams->n_video); for(i = 0; i < stream_count; i++) { uint32_t rate = 0; int id = 0; int j = 0; id = get16_le(ptr); ptr += sizeof(uint16_t); if(ptr > header + asf_header_size) goto failed; rate = get32_le(ptr); ptr += sizeof(uint32_t); if(ptr > header + asf_header_size) goto failed; display(MSDL_VER, "stream_id = [0x%x] [%u]\n" "max bitrate = [0x%x] [%u]\n", id,id,rate,rate); for(j = 0; j < streams->n_audio; j++) { if(id == streams->audio_streams[j]) { display(MSDL_VER,"is audio stream\n"); a_rates[j] = rate; break; } } for(j = 0; j < streams->n_video; j++) { if(id == streams->video_streams[j]) { display(MSDL_VER,"is video stream\n"); v_rates[j] = rate; break; } } } } /* just to make sure bw is not Zero! */ if(bw == 0) { bw = INT_MAX_BANDWIDTH; } if(streams->n_audio) { /* find lowest-bitrate audio stream */ a_rate = a_rates[0]; a_idx = 0; for(i = 0; i < streams->n_audio; i++) { if(a_rates[i] < a_rate) { a_rate = a_rates[i]; a_idx = i; } } if(max_idx(streams->n_video,v_rates,bw - a_rate) < 0) { /* both audio and video are not possible, try video only next */ a_idx = -1; a_rate = 0; } } /* find best video stream */ v_idx = max_idx(streams->n_video,v_rates,bw - a_rate); if(v_idx >= 0) { v_rate = v_rates[v_idx]; } /* find best auido stream */ a_idx = max_idx(streams->n_audio,a_rates,bw - v_rate); free(v_rates); v_rates = NULL; free(a_rates); a_rates = NULL; if(a_idx < 0 && v_idx < 0) { display(MSDL_ERR,"bandwidth too low ... cannot get streams."); return -1; } if(a_idx >= 0) { streams->audio_id = streams->audio_streams[a_idx]; } else if(streams->n_audio) { display(MSDL_ERR,"Bandwidth too too small so deselected audio....sad.\n"); } if(v_idx >= 0) { streams->video_id = streams->video_streams[v_idx]; } else if(streams->n_video) { display(MSDL_ERR,"Bandwidth too too small so deselected video....sad.\n"); } return 1; failed: free(v_rates); free(a_rates); return -1; }
int main(int argc, char *argv[]) { if( argc != 4 ) { io::cerr << "Usage: \t lpcm2wav sample_rate:channels:bps file.lpcm out_file.wav" << io::endl; io::cerr << "\t lpcm2wav makes wav from dvd lpcm stream." << io::endl; return 1; } PCMWaveHeader hdr; if( !ParsePcmTriple(argv[1], hdr) ) { io::cerr << "Can't get correct sample_rate:channels:bps triple!" << io::endl; return 2; } uint32_t samplerate = hdr.sampleRate; uint16_t channels = hdr.channels; uint16_t bits = hdr.bits; io::cerr << "Sample rate (Hz):\t " << samplerate << io::endl; io::cerr << "Number of channels:\t " << channels << io::endl; io::cerr << "Sample size (bit):\t " << bits << io::endl; io::stream strm(argv[2], iof::in); if( !strm ) { io::cerr << "Can't open file: " << argv[2] << io::endl; return 3; } io::pos file_big_sz = StreamSize(strm); if( file_big_sz > UINT32_MAX-100 ) // ограничение размера wav-файла 32битами { io::cerr << "Can't do wav-file because " << argv[2] << " is too big, > 3,9Gb." << io::endl; return 4; } uint32_t file_sz = file_big_sz; // заполняем оставшееся, c учетом little endian hdr.riff = le2me_32(WAV_ID_RIFF); hdr.fileLen = le2me_32(file_sz + PCM_WAVE_HEADER_SIZE - 8); hdr.wave = le2me_32(WAV_ID_WAVE); hdr.frmt = le2me_32(WAV_ID_FMT); hdr.frmtLen = le2me_32(16); hdr.frmtTag = le2me_16(WAV_ID_PCM); hdr.channels = le2me_16(channels); hdr.sampleRate = le2me_32(samplerate); hdr.bytesPerSecond = le2me_32(channels * samplerate * bits / 8); hdr.blockAlign = le2me_16(channels * bits / 8); hdr.bits = le2me_16(bits); hdr.data = le2me_32(WAV_ID_DATA); hdr.dataLen = le2me_32(file_sz); // запись io::stream wav_strm(argv[3], iof::out); if( !wav_strm ) { io::cerr << "Can't write to file: " << argv[3] << io::endl; return 5; } wav_strm.raw_write((const char*)&hdr, PCM_WAVE_HEADER_SIZE); const char* incomplete_samples = "Error: Number of PCM samples is incomplete."; switch( bits ) { case 16: { if( file_sz%2 ) io::cerr << incomplete_samples << io::endl; TBReadFunctor fnr = bl::bind(&Swap16AndWrite, bl::_1, boost::ref(wav_strm)); ReadStreamThroughTB(fnr, strm, file_sz); } break; case 20: { if( file_sz%(5*channels) ) io::cerr << incomplete_samples << io::endl; TBReadFunctor fnr = bl::bind(&Reconstruct20bitLPCM, bl::_1, channels, boost::ref(wav_strm)); ReadStreamThroughTB(fnr, strm, file_sz); } break; case 24: { if( file_sz%(6*channels) ) io::cerr << incomplete_samples << io::endl; TBReadFunctor fnr = bl::bind(&Reconstruct24bitLPCM, bl::_1, channels, boost::ref(wav_strm)); ReadStreamThroughTB(fnr, strm, file_sz); } break; default: ASSERT(0); } return 0; }
static int demux_mkv_open_audio (FileInfo *finfo, mkv_track_t *track) { WAVEFORMATEX *finfowf = &finfo->wf; if (track->ms_compat && (track->private_size >= sizeof(WAVEFORMATEX))) { WAVEFORMATEX *wf = (WAVEFORMATEX *)track->private_data; finfowf->wFormatTag = le2me_16 (wf->wFormatTag); finfowf->nChannels = le2me_16 (wf->nChannels); finfowf->nSamplesPerSec = le2me_32 (wf->nSamplesPerSec); finfowf->nAvgBytesPerSec = le2me_32 (wf->nAvgBytesPerSec); finfowf->nBlockAlign = le2me_16 (wf->nBlockAlign); finfowf->wBitsPerSample = le2me_16 (wf->wBitsPerSample); if (track->a_sfreq == 0.0) track->a_sfreq = finfowf->nSamplesPerSec; if (track->a_channels == 0) track->a_channels = finfowf->nChannels; if (track->a_bps == 0) track->a_bps = finfowf->wBitsPerSample; track->a_formattag = finfowf->wFormatTag; } else { memset(finfowf, 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 (!strncmp(track->codec_id, MKV_A_EAC3, strlen(MKV_A_EAC3))) track->a_formattag = AUDIO_EAC3; else if (!strcmp(track->codec_id, MKV_A_DTS)) { track->a_formattag = 0x2001; //dts_packet = 1; } 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_WAVPACK)) track->a_formattag = mmioFOURCC('W', 'V', 'P', 'K'); else if (!strcmp(track->codec_id, MKV_A_TRUEHD)) track->a_formattag = mmioFOURCC('T', 'R', 'H', 'D'); 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); return 1; } } finfowf->wFormatTag = track->a_formattag; finfowf->nChannels = track->a_channels; finfowf->nSamplesPerSec = (uint32_t) track->a_sfreq; if (track->a_bps == 0) { finfowf->wBitsPerSample = 16; } else { finfowf->wBitsPerSample = track->a_bps; } if (track->a_formattag == 0x0055) /* MP3 || MP2 */ { finfowf->nAvgBytesPerSec = 16000; finfowf->nBlockAlign = 1152; } else if (track->a_formattag == 0x2000 )/* AC3 */ { } else if (track->a_formattag == AUDIO_EAC3 )/* EAC3 */ { } else if (track->a_formattag == 0x2001) /* DTS */ { //dts_packet = 1; } else if (track->a_formattag == 0x0001) /* PCM || PCM_BE */ { finfowf->nAvgBytesPerSec = track->a_channels * track->a_sfreq * 2; finfowf->nBlockAlign = finfowf->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)) { finfowf->nAvgBytesPerSec = 16000; finfowf->nBlockAlign = 1486; track->fix_i_bps = 1; track->qt_last_a_pts = 0.0; } else if (track->a_formattag == mmioFOURCC('M', 'P', '4', 'A')) { int profile, srate_idx; finfowf->nAvgBytesPerSec = 16000; finfowf->nBlockAlign = 1024; if (!strcmp (track->codec_id, MKV_A_AAC) && (NULL != track->private_data)) { return 0; } /* Recreate the 'private data' */ /* which faad2 uses in its initialization */ srate_idx = aac_get_sample_rate_index (track->a_sfreq); 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; if (strstr(track->codec_id, "SBR") != NULL) { /* HE-AAC (aka SBR AAC) */ track->default_duration = 1024.0 / finfowf->nSamplesPerSec; finfowf->nSamplesPerSec *= 2; } else { track->default_duration = 1024.0 / (float)finfowf->nSamplesPerSec; } } else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) /* VORBIS */ { //finfowf->cbSize = track->private_size; } else if (track->private_size >= RAPROPERTIES4_SIZE && !strncmp (track->codec_id, MKV_A_REALATRC, 7)) { /* Common initialization for all RealAudio codecs */ unsigned char *src = (unsigned char *)track->private_data; int codecdata_length, version; int flavor; finfowf->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); finfowf->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; switch (track->a_formattag) { case mmioFOURCC('a', 't', 'r', 'c'): finfowf->nAvgBytesPerSec = atrc_fl2bps[flavor]; finfowf->nBlockAlign = track->sub_packet_size; break; case mmioFOURCC('c', 'o', 'o', 'k'): finfowf->nAvgBytesPerSec = cook_fl2bps[flavor]; finfowf->nBlockAlign = track->sub_packet_size; break; case mmioFOURCC('s', 'i', 'p', 'r'): finfowf->nAvgBytesPerSec = sipr_fl2bps[flavor]; finfowf->nBlockAlign = track->coded_framesize; break; case mmioFOURCC('2', '8', '_', '8'): finfowf->nAvgBytesPerSec = 3600; finfowf->nBlockAlign = track->coded_framesize; break; } track->realmedia = 1; } else if (!strcmp(track->codec_id, MKV_A_FLAC) || (track->a_formattag == 0xf1ac)) { unsigned char *ptr; int size; #if 1 //Fuchun 2010.06.23 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') { //finfowf->cbSize = 4; } else { //finfowf->cbSize = size; } #else free(finfowf); finfowf = 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); #endif } else if (track->a_formattag == mmioFOURCC('W', 'V', 'P', 'K') || track->a_formattag == mmioFOURCC('T', 'R', 'H', 'D')) { /* do nothing, still works */ } else if (!track->ms_compat || (track->private_size < sizeof(WAVEFORMATEX))) { return 1; } return 0; }
static int demux_mkv_open_video (FileInfo *finfo, mkv_track_t *track) { BITMAP_INFO_HEADER *bih = &finfo->bih; #ifdef CONFIG_QTX_CODECS void *ImageDesc = NULL; #endif if (track->ms_compat) /* MS compatibility mode */ { BITMAP_INFO_HEADER *src; if (track->private_data == NULL || track->private_size < sizeof (BITMAP_INFO_HEADER)) return 1; src = (BITMAP_INFO_HEADER *) track->private_data; 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); if (track->v_width == 0) track->v_width = bih->biWidth; if (track->v_height == 0) track->v_height = bih->biHeight; } else { bih->biSize = sizeof (BITMAP_INFO_HEADER); 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 *src; uint32_t type2; unsigned int cnt; src = (uint8_t *)track->private_data + RVPROPERTIES_SIZE; cnt = track->private_size - RVPROPERTIES_SIZE; 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'); track->realmedia = 1; #ifdef CONFIG_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 /* CONFIG_QTX_CODECS */ } else { const videocodec_info_t *vi = vinfo; while (vi->id && strcmp(vi->id, track->codec_id)) vi++; bih->biCompression = vi->fourcc; track->reorder_timecodes = 1; if (!vi->id) { mp_msg (MSGT_DEMUX,MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCodecID, track->codec_id, track->tnum); return 1; } } } if (track->v_frate == 0.0) track->v_frate = 25.0; finfo->FPS = track->v_frate; return 0; }