static void write_avi_chunk(stream_t *stream,unsigned int id,int len,void* data){ int le_len = le2me_32(len); int le_id = le2me_32(id); stream_write_buffer(stream, &le_id, 4); stream_write_buffer(stream, &le_len, 4); if(len>0){ if(data){ // DATA stream_write_buffer(stream, data, len); if(len&1){ // padding unsigned char zerobyte=0; stream_write_buffer(stream, &zerobyte, 1); } } else { // JUNK char *avi_junk_data="[= MPlayer junk data! =]"; if(len&1) ++len; // padding while(len>0){ int l=strlen(avi_junk_data); if(l>len) l=len; stream_write_buffer(stream, avi_junk_data, l); len-=l; } } } }
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); }
/* * get file property. * return value packet size ... success * -1 ... error */ int asf_get_file_property(const uint8_t *header,int asf_header_size, struct asf_file_header_t *fileh) { int pos = 0; int packet_size = 0; /* examine file properties */ pos = find_asf_guid(header,0,asf_file_header_guid,asf_header_size); if(pos < 0) { goto failed; } if((pos + sizeof(struct asf_file_header_t )) > asf_header_size) {/* 2big */ goto failed; } memcpy((uint8_t *)fileh,header + pos,sizeof(struct asf_file_header_t)); /* little endian */ fileh->file_size = le2me_64(fileh->file_size); fileh->creation_time = le2me_64(fileh->creation_time); fileh->num_packets = le2me_64(fileh->num_packets); fileh->play_duration = le2me_64(fileh->play_duration); fileh->send_duration = le2me_64(fileh->send_duration); fileh->preroll = le2me_64(fileh->preroll); fileh->flags = le2me_32(fileh->flags); fileh->min_packet_size = le2me_32(fileh->min_packet_size); fileh->max_packet_size = le2me_32(fileh->max_packet_size); fileh->max_bitrate = le2me_32(fileh->max_bitrate); display(MSDL_VER,"file size = %lld\n",fileh->file_size); display(MSDL_VER,"play_duration = %d\n", fileh->play_duration/10000000); display(MSDL_VER,"send_duration = %d\n", fileh->send_duration/10000000); display(MSDL_VER,"# of packets = %d\n", fileh->num_packets); display(MSDL_VER,"flags = %x\n", fileh->flags); packet_size = fileh->max_packet_size; display(MSDL_VER,"packet_size = %d\n", fileh->max_packet_size); display(MSDL_VER,"min_packsize = %d\n", fileh->min_packet_size); return packet_size; failed: return -1; }
static void write_avi_list(stream_t *stream,unsigned int id,int len){ unsigned int list_id=FOURCC_LIST; int le_len; int le_id; len+=4; // list fix list_id = le2me_32(list_id); le_len = le2me_32(len); le_id = le2me_32(id); stream_write_buffer(stream, &list_id, 4); stream_write_buffer(stream, &le_len, 4); stream_write_buffer(stream, &le_id, 4); }
// close audio device static void uninit(int immed){ if(ao_pcm_waveheader && fseek(fp, 0, SEEK_SET) == 0){ /* Write wave header */ wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8; wavhdr.file_length = le2me_32(wavhdr.file_length); wavhdr.data_length = le2me_32(wavhdr.data_length); fwrite(&wavhdr,sizeof(wavhdr),1,fp); } fclose(fp); if (ao_outputfilename) free(ao_outputfilename); ao_outputfilename = NULL; }
/** * Compute and save calculated hash into the given array. * * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ void has160_final(has160_ctx *ctx, unsigned char* result) { unsigned shift = ((unsigned)ctx->length & 3) * 8; unsigned index = ((unsigned)ctx->length & 63) >> 2; /* pad message and run for last block */ #ifdef CPU_LITTLE_ENDIAN ctx->message[index] &= ~(0xFFFFFFFF << shift); ctx->message[index++] ^= 0x80 << shift; #else ctx->message[index] &= ~(0xFFFFFFFF >> shift); ctx->message[index++] ^= 0x80000000 >> shift; #endif /* if no room left in the message to store 64-bit message length */ if(index>14) { /* then fill the rest with zeros and process it */ while(index < 16) { ctx->message[index++] = 0; } has160_process_block(ctx->hash, ctx->message); index = 0; } while(index < 14) { ctx->message[index++] = 0; } ctx->message[14] = le2me_32( (unsigned)(ctx->length << 3) ); ctx->message[15] = le2me_32( (unsigned)(ctx->length >> 29) ); has160_process_block(ctx->hash, ctx->message); le32_copy(result, &ctx->hash, has160_hash_size); }
static int handle_block (mkv_demuxer_t *mkv_d, uint8_t *block, uint64_t length, uint64_t block_duration, int64_t block_bref, int64_t block_fref, uint8_t simpleblock) { int ii, num, tmp; mkv_track_t *track = NULL; int nRet = 1; /* first byte(s): track num */ num = ebml_read_vlen_uint (block, &tmp); // find track info for (ii=0; ii<mkv_d->num_tracks; ii++) { if ( (mkv_d->tracks[ii]->type == MATROSKA_TRACK_VIDEO) && (mkv_d->tracks[ii]->tnum == num) ) { track = mkv_d->tracks[ii]; break; } } if ( (track != NULL) && track->ms_compat && (track->private_data) && (track->hw_notsupport == 0) ) { BITMAP_INFO_HEADER *src; uint32_t biCompression; src = (BITMAP_INFO_HEADER *) track->private_data; biCompression = le2me_32 (src->biCompression); if ( (biCompression == mmioFOURCC('X', 'V', 'I', 'D')) || (biCompression == mmioFOURCC('x', 'v', 'i', 'd')) || (biCompression == mmioFOURCC('D', 'I', 'V', 'X')) || (biCompression == mmioFOURCC('d', 'i', 'v', 'x')) || (biCompression == mmioFOURCC('D', 'X', '5', '0')) ) { uint8_t *check_mp4_vol_buf = (uint8_t *)malloc(128); if (check_mp4_vol_buf != NULL) { memcpy(check_mp4_vol_buf, block, 128); if ( !check_mp4_header_vol(check_mp4_vol_buf, 128) ) { printf("\nMKV: GMC AND STATIC SPRITE CODING not supported\n\n"); track->hw_notsupport = 1; nRet = 0; } free(check_mp4_vol_buf); } } } return nRet; }
void av_md5_final(AVMD5 *ctx, uint8_t *dst){ int i; uint64_t finalcount= le2me_64(ctx->len<<3); av_md5_update(ctx, "\200", 1); while((ctx->len & 63)<56) av_md5_update(ctx, "", 1); av_md5_update(ctx, &finalcount, 8); for(i=0; i<4; i++) ((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]); }
static int encode_init(AVCodecContext *avctx){ ASV1Context * const a = avctx->priv_data; int i; const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; common_init(avctx); if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE; a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality; avctx->extradata= av_mallocz(8); avctx->extradata_size=8; ((uint32_t*)avctx->extradata)[0]= le2me_32(a->inv_qscale); ((uint32_t*)avctx->extradata)[1]= le2me_32(ff_get_fourcc("ASUS")); for(i=0; i<64; i++){ int q= 32*scale*ff_mpeg1_default_intra_matrix[i]; a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q; } return 0; }
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 odml_get_vstream_id(int id, unsigned char res[]) { unsigned char *p = (unsigned char *)&id; id = le2me_32(id); if (p[2] == 'd') { if (res) { res[0] = p[0]; res[1] = p[1]; } return 1; } return 0; }
static void avifile_odml_new_riff(muxer_t *muxer) { struct avi_stream_info *vsi = muxer->def_v->priv; uint32_t riff[3]; mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Starting new RIFF chunk at %dMB.\n", (int)(muxer->file_end/1024/1024)); vsi->riffofspos++; if (vsi->riffofspos>=vsi->riffofssize) { vsi->riffofssize+=16; vsi->riffofs=realloc_struct(vsi->riffofs,(vsi->riffofssize+1),sizeof(off_t)); } vsi->riffofs[vsi->riffofspos] = stream_tell(muxer->stream); /* RIFF/AVIX chunk */ riff[0]=le2me_32(mmioFOURCC('R','I','F','F')); riff[1]=0; riff[2]=le2me_32(mmioFOURCC('A','V','I','X')); stream_write_buffer(muxer->stream, riff, 12); write_avi_list(muxer->stream,listtypeAVIMOVIE,0); muxer->file_end = stream_tell(muxer->stream); }
void av_md5_final(AVMD5 *ctx, uint8_t *dst){ int i; ctx->block[ctx->b_used++] = 0x80; memset(&ctx->block[ctx->b_used], 0, 64 - ctx->b_used); if( 56 < ctx->b_used ){ body( ctx->ABCD, (uint32_t*) ctx->block ); memset(ctx->block, 0, 64); } for(i=0; i<8; i++) ctx->block[56+i] = (ctx->len << 3) >> (i<<3); body(ctx->ABCD, (uint32_t*) ctx->block); for(i=0; i<4; i++) ((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]); }
static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { long retval; char path[100]; int fd; sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd == -1) { retval=0; } else if (pread(fd, &retval, 4, cmd) == 4) { retval = le2me_32(retval); } else { retval = 0; } if (fd > 0) { close(fd); } return retval; }
int mware_tune_config(crusher_t *crusher){ FILE *mware_h = NULL; uint32_t *temp32; long fsize; int i; /* have file config? */ if(crusher->mwarecfg) { mware_h = fopen(crusher->mwarecfg, "r"); if(!mware_h) { ERROR("Open file %s failed.", crusher->mwarecfg); return 0; } // obtain file size: fseek (mware_h, 0, SEEK_END); fsize = ftell (mware_h); rewind (mware_h); if(fsize != MWARE_SIZE*sizeof(uint32_t)) { ERROR("Strange size of %s file, must be %d bytes.", crusher->mwarecfg, MWARE_SIZE*sizeof(uint32_t)); fclose(mware_h); return 0; } temp32 = calloc(MWARE_SIZE, sizeof(uint32_t)); if(!temp32){ fclose(mware_h); return 0; } if(fread (temp32, sizeof(uint32_t), MWARE_SIZE, mware_h) != MWARE_SIZE) { ERROR("Can't read %d byts from file %s.", fsize, crusher->mwarecfg); fclose(mware_h); return 0; } fclose(mware_h); for (i=0; i<MWARE_SIZE; i++) crusher->mware_data[i] = le2me_32(temp32[i]); } else { /* generate config */ if (crusher->devmode == DEV_TYPE_ENCODER) { /* use default mware */ if (crusher->width != 320 || crusher->height != 240) { /* mware values: qvgaconfig_16mb.bin vgaconfig_16mb.bin captured_d1.bin arbiconfig_16mb.bin qvgaconfig.bin 0: 2, 0, 0, 84, 4: 1, 0, 6144, 2048 *x, x, x, 512* *x, x, x, 512* *x, x, x, 512* 8: 1, 76801, 64, 64, *x, 257, x, x* *x, 257, x, x* *x, 257, x, x* 12: 6, 1, 2, 32, 16: 1, 1, 257, 256, 20: 64, 23, 1, 320, *x, 9, x, 640* *x, 7, x, 720* *x, 7, x, 512* 24: 240, 320, 240, 8192, *480, 640, 480, x* *576, 720, 576, x* *240, 512, 240, x* 28: 8192, 0, 0, 0, 32: 0, 320, 240, 1, *x, 640, 480, x* *1, 720, 576, x,* *x, 512, 240, x,* 36: 1, 44, 0, 0, *x, 21, x, x* 40: 1, 0, 320, 240, *0, x, 640, 480* *x, x, 720, 576* *x, x, 512, 240* 44: 8, 9, 0, 0, 48: 1, 1, 1, 521, *0, 0, 0, x* 52: 0, 45, 144, 17, *x, 0, 0, 0* *x, x, 228, x* *x, x, 228, x* 56: 320, 260, 0, 0, *0, 0, x, x* *720, 596, x, x* *512, 260, x, x* 60: 0, 0, 45, 144, 64: 8, 0, 16, 16, *x, 2, x, x* 68: 8, 16, 16, 2, 72: 0, 7, 7, 16, 76: 0, 0, 0, 1, 80: 0, 7, 3, 16, 84: 0, 1, 0, 1 */ /* tune mware * TODO: what this values means? * */ /* 7 for 720x576, 11 for 640x480, 23 for lower */ if((crusher->width > 400) && (crusher->width <= 640)) crusher->mware_data[MWARE_DECODE_VIDEO_FRAMES+4] = 11; else if((crusher->width > 640)) crusher->mware_data[MWARE_DECODE_VIDEO_FRAMES+4] = 7; crusher->mware_data[MWARE_MAX_VIDEO_ENCODE_WIDTH+4] = crusher->width; crusher->mware_data[MWARE_MAX_VIDEO_ENCODE_HEIGHT+4] = crusher->height; crusher->mware_data[MWARE_MAX_VIDEO_DECODE_WIDTH+4] = crusher->width; crusher->mware_data[MWARE_MAX_VIDEO_DECODE_HEIGHT+4] = crusher->height; crusher->mware_data[MWARE_VIDEO_PAL+4] = (crusher->width > 640) ? 1 : 0; /* ! */ crusher->mware_data[MWARE_VIDEO_VPP_INPUT_WIDTH+4] = crusher->width; crusher->mware_data[MWARE_VIDEO_VPP_INPUT_HEIGHT+4] = crusher->height; crusher->mware_data[MWARE_VIDEO_VPU_OUTPUT_WIDTH+4] = crusher->width; crusher->mware_data[MWARE_VIDEO_VPU_OUTPUT_HEIGHT+4] = crusher->height; crusher->mware_data[MWARE_VIDEO_VPU_PHYSICAL_OUTPUT_WIDTH+4] = crusher->width; if(crusher->height % 16) crusher->mware_data[MWARE_VIDEO_VPU_PHYSICAL_OUTPUT_HEIGHT+4] = crusher->height + 20 + 16 - (crusher->height % 16); else crusher->mware_data[MWARE_VIDEO_VPU_PHYSICAL_OUTPUT_HEIGHT+4] = crusher->height + 20; } } else if (crusher->devmode == DEV_TYPE_CAPTURE) { //TODO: configure mware for CrusherCapture if needed. if(crusher->audio_samplerate != 48000) { #if 0 crusher->mware_data[MWARE_AUDIO_AII_DRIVELRCK_SCKPHASE+4] = 7; crusher->mware_data[MWARE_AUDIO_AOI_DRIVE_SCKPHASE+4] = 7; crusher->mware_data[MWARE_AUDIO_AII_SAMPLE_SCKPHASE+4] = 3; crusher->mware_data[MWARE_AUDIO_AOI_SAMPLELRCK_SCKPHASE+4] = 3; crusher->mware_data[MWARE_AUDIO_AII_MCLKTOFS_RATIO+4] = AUD_MASTER_CLOCK_512FS; crusher->mware_data[MWARE_AUDIO_AOI_MCLKTOFS_RATIO+4] = AUD_MASTER_CLOCK_512FS; crusher->mware_data[MWARE_AUDIO_AII_SCKTOLRCK_RATIO+4] = AUD_BUS_CLOCK_32FS; crusher->mware_data[MWARE_AUDIO_AOI_SCKTOLRCK_RATIO+4] = AUD_BUS_CLOCK_32FS; #endif ERROR("Samplerate %d is not partially supported", crusher->audio_samplerate); } } } return 1; }
static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap) { ByteIOContext *pb = &s->pb; SmackerContext *smk = (SmackerContext *)s->priv_data; AVStream *st, *ast[7]; int i, ret; int tbase; /* read and check header */ smk->magic = get_le32(pb); if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4')) return -1; smk->width = get_le32(pb); smk->height = get_le32(pb); smk->frames = get_le32(pb); smk->pts_inc = (int32_t)get_le32(pb); smk->flags = get_le32(pb); for(i = 0; i < 7; i++) smk->audio[i] = get_le32(pb); smk->treesize = get_le32(pb); if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant) av_log(s, AV_LOG_ERROR, "treesize too large\n"); return -1; } //FIXME remove extradata "rebuilding" smk->mmap_size = get_le32(pb); smk->mclr_size = get_le32(pb); smk->full_size = get_le32(pb); smk->type_size = get_le32(pb); for(i = 0; i < 7; i++) smk->rates[i] = get_le32(pb); smk->pad = get_le32(pb); /* setup data */ if(smk->frames > 0xFFFFFF) { av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames); return -1; } smk->frm_size = av_malloc(smk->frames * 4); smk->frm_flags = av_malloc(smk->frames); smk->is_ver4 = (smk->magic != MKTAG('S', 'M', 'K', '2')); /* read frame info */ for(i = 0; i < smk->frames; i++) { smk->frm_size[i] = get_le32(pb); } for(i = 0; i < smk->frames; i++) { smk->frm_flags[i] = get_byte(pb); } /* init video codec */ st = av_new_stream(s, 0); if (!st) return -1; smk->videoindex = st->index; st->codec->width = smk->width; st->codec->height = smk->height; st->codec->pix_fmt = PIX_FMT_PAL8; st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_SMACKVIDEO; st->codec->codec_tag = smk->magic; /* Smacker uses 100000 as internal timebase */ if(smk->pts_inc < 0) smk->pts_inc = -smk->pts_inc; else smk->pts_inc *= 100; tbase = 100000; av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1); av_set_pts_info(st, 33, smk->pts_inc, tbase); /* handle possible audio streams */ for(i = 0; i < 7; i++) { smk->indexes[i] = -1; if((smk->rates[i] & 0xFFFFFF) && !(smk->rates[i] & SMK_AUD_BINKAUD)){ ast[i] = av_new_stream(s, 0); smk->indexes[i] = ast[i]->index; ast[i]->codec->codec_type = CODEC_TYPE_AUDIO; ast[i]->codec->codec_id = (smk->rates[i] & SMK_AUD_PACKED) ? CODEC_ID_SMACKAUDIO : CODEC_ID_PCM_U8; ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A'); ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1; ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF; ast[i]->codec->bits_per_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8; if(ast[i]->codec->bits_per_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8) ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE; av_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate * ast[i]->codec->channels * ast[i]->codec->bits_per_sample / 8); } } /* load trees to extradata, they will be unpacked by decoder */ st->codec->extradata = av_malloc(smk->treesize + 16); st->codec->extradata_size = smk->treesize + 16; if(!st->codec->extradata){ av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16); av_free(smk->frm_size); av_free(smk->frm_flags); return -1; } ret = get_buffer(pb, st->codec->extradata + 16, st->codec->extradata_size - 16); if(ret != st->codec->extradata_size - 16){ av_free(smk->frm_size); av_free(smk->frm_flags); return AVERROR_IO; } ((int32_t*)st->codec->extradata)[0] = le2me_32(smk->mmap_size); ((int32_t*)st->codec->extradata)[1] = le2me_32(smk->mclr_size); ((int32_t*)st->codec->extradata)[2] = le2me_32(smk->full_size); ((int32_t*)st->codec->extradata)[3] = le2me_32(smk->type_size); smk->curstream = -1; smk->nextpos = url_ftell(pb); 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; }
/* * Process WVE file header * Returns 1 if the WVE file is valid and successfully opened, 0 otherwise */ static int process_ea_header(AVFormatContext *s) { int inHeader; uint32_t blockid, size; EaDemuxContext *ea = s->priv_data; ByteIOContext *pb = &s->pb; if (get_buffer(pb, (void*)&blockid, 4) != 4) { return 0; } if (le2me_32(blockid) != SCHl_TAG) { return 0; } if (get_buffer(pb, (void*)&size, 4) != 4) { return 0; } size = le2me_32(size); if (get_buffer(pb, (void*)&blockid, 4) != 4) { return 0; } if (le2me_32(blockid) != PT00_TAG) { av_log (s, AV_LOG_ERROR, "PT header missing\n"); return 0; } inHeader = 1; while (inHeader) { int inSubheader; uint8_t byte; byte = get_byte(pb) & 0xFF; switch (byte) { case 0xFD: av_log (s, AV_LOG_INFO, "entered audio subheader\n"); inSubheader = 1; while (inSubheader) { uint8_t subbyte; subbyte = get_byte(pb) & 0xFF; switch (subbyte) { case 0x82: ea->num_channels = read_arbitary(pb); av_log (s, AV_LOG_INFO, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels); break; case 0x83: ea->compression_type = read_arbitary(pb); av_log (s, AV_LOG_INFO, "compression_type (element 0x83) set to 0x%08x\n", ea->compression_type); break; case 0x85: ea->num_samples = read_arbitary(pb); av_log (s, AV_LOG_INFO, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples); break; case 0x8A: av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); av_log (s, AV_LOG_INFO, "exited audio subheader\n"); inSubheader = 0; break; default: av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); break; } } break; case 0xFF: av_log (s, AV_LOG_INFO, "end of header block reached\n"); inHeader = 0; break; default: av_log (s, AV_LOG_INFO, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb)); break; } } if ((ea->num_channels != 2) || (ea->compression_type != 7)) { av_log (s, AV_LOG_ERROR, "unsupported stream type\n"); return 0; } /* skip to the start of the data */ url_fseek(pb, size, SEEK_SET); return 1; }
static void avifile_write_header(muxer_t *muxer){ uint32_t riff[3]; unsigned int dmlh[1]; unsigned int i; unsigned int hdrsize; muxer_info_t info[16]; VideoPropHeader vprp; uint32_t aspect = avi_aspect(muxer->def_v); struct avi_stream_info *vsi = muxer->def_v->priv; int isodml = vsi->riffofspos > 0; mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_WritingHeader); if (aspect == 0) { mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: Aspect information not (yet?) available or unspecified, not writing vprp header.\n"); } else { mp_msg(MSGT_MUXER, MSGL_INFO, "ODML: vprp aspect is %d:%d.\n", aspect >> 16, aspect & 0xffff); } /* deal with stream delays */ for (i = 0; muxer->streams[i] && i < MUXER_MAX_STREAMS; ++i) { muxer_stream_t *s = muxer->streams[i]; if (s->type == MUXER_TYPE_AUDIO && muxer->audio_delay_fix > 0.0) { s->h.dwStart = muxer->audio_delay_fix * s->h.dwRate/s->h.dwScale + 0.5; mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_SettingAudioDelay, (float)s->h.dwStart * s->h.dwScale/s->h.dwRate); } if (s->type == MUXER_TYPE_VIDEO && muxer->audio_delay_fix < 0.0) { s->h.dwStart = -muxer->audio_delay_fix * s->h.dwRate/s->h.dwScale + 0.5; mp_msg(MSGT_MUXER, MSGL_INFO, MSGTR_SettingVideoDelay, (float)s->h.dwStart * s->h.dwScale/s->h.dwRate); } } if (isodml) { unsigned int rifflen, movilen; int i; vsi->riffofs[vsi->riffofspos+1] = muxer->file_end; /* fixup RIFF lengths */ for (i=0; i<=vsi->riffofspos; i++) { rifflen = vsi->riffofs[i+1] - vsi->riffofs[i] - 8; movilen = le2me_32(rifflen - 12); rifflen = le2me_32(rifflen); stream_seek(muxer->stream, vsi->riffofs[i]+4); stream_write_buffer(muxer->stream,&rifflen,4); /* fixup movi length */ if (i > 0) { stream_seek(muxer->stream, vsi->riffofs[i]+16); stream_write_buffer(muxer->stream,&movilen,4); } } stream_seek(muxer->stream, 12); } else { // RIFF header: riff[0]=mmioFOURCC('R','I','F','F'); riff[1]=muxer->file_end-2*sizeof(unsigned int); // filesize riff[2]=formtypeAVI; // 'AVI ' riff[0]=le2me_32(riff[0]); riff[1]=le2me_32(riff[1]); riff[2]=le2me_32(riff[2]); stream_write_buffer(muxer->stream,&riff,12); } // update AVI header: if(muxer->def_v){ int i; muxer->avih.dwMicroSecPerFrame=1000000.0*muxer->def_v->h.dwScale/muxer->def_v->h.dwRate; // muxer->avih.dwMaxBytesPerSec=1000000; // dummy!!!!! FIXME // muxer->avih.dwPaddingGranularity=2; // ??? muxer->avih.dwFlags|=AVIF_ISINTERLEAVED|AVIF_TRUSTCKTYPE; muxer->avih.dwTotalFrames=0; for (i=0; i<muxer->idx_pos; i++) { if (muxer->idx[i].ckid == muxer->def_v->ckid) muxer->avih.dwTotalFrames++; } // muxer->avih.dwSuggestedBufferSize=muxer->def_v->h.dwSuggestedBufferSize; muxer->avih.dwWidth=muxer->def_v->bih->biWidth; muxer->avih.dwHeight=muxer->def_v->bih->biHeight; } // AVI header: hdrsize=sizeof(muxer->avih)+8; if (isodml) hdrsize+=sizeof(dmlh)+20; // dmlh // calc total header size: for(i=0;i<muxer->avih.dwStreams;i++){ muxer_stream_t *s = muxer->streams[i]; struct avi_stream_info *si = s->priv; hdrsize+=12; // LIST hdrsize+=sizeof(muxer->streams[i]->h)+8; // strh switch(muxer->streams[i]->type){ case MUXER_TYPE_VIDEO: hdrsize+=muxer->streams[i]->bih->biSize+8; // strf if (aspect != 0) { hdrsize+=8+4*(9+8*1); // vprp } break; case MUXER_TYPE_AUDIO: hdrsize+=WFSIZE(muxer->streams[i]->wf)+8; // strf break; } if (isodml && si && si->superidx && si->superidxsize) { hdrsize += 32 + 16*si->superidxsize; //indx } } write_avi_list(muxer->stream,listtypeAVIHEADER,hdrsize); le2me_MainAVIHeader(&muxer->avih); write_avi_chunk(muxer->stream,ckidAVIMAINHDR,sizeof(muxer->avih),&muxer->avih); /* MainAVIHeader */ le2me_MainAVIHeader(&muxer->avih); // stream headers: for(i=0;i<muxer->avih.dwStreams;i++){ muxer_stream_t *s = muxer->streams[i]; struct avi_stream_info *si = s->priv; unsigned int idxhdr[8]; int j,n; hdrsize=sizeof(s->h)+8; // strh if (si && si->superidx && si->superidxsize) { hdrsize += 32 + 16*si->superidxsize; //indx } switch(s->type){ case MUXER_TYPE_VIDEO: hdrsize+=s->bih->biSize+8; // strf s->h.fccHandler = s->bih->biCompression; s->h.rcFrame.right = s->bih->biWidth; s->h.rcFrame.bottom = s->bih->biHeight; if (aspect != 0) { // fill out vprp info memset(&vprp, 0, sizeof(vprp)); vprp.dwVerticalRefreshRate = (s->h.dwRate+s->h.dwScale-1)/s->h.dwScale; vprp.dwHTotalInT = muxer->avih.dwWidth; vprp.dwVTotalInLines = muxer->avih.dwHeight; vprp.dwFrameAspectRatio = aspect; vprp.dwFrameWidthInPixels = muxer->avih.dwWidth; vprp.dwFrameHeightInLines = muxer->avih.dwHeight; vprp.nbFieldPerFrame = 1; vprp.FieldInfo[0].CompressedBMHeight = muxer->avih.dwHeight; vprp.FieldInfo[0].CompressedBMWidth = muxer->avih.dwWidth; vprp.FieldInfo[0].ValidBMHeight = muxer->avih.dwHeight; vprp.FieldInfo[0].ValidBMWidth = muxer->avih.dwWidth; hdrsize+=8+4*(9+8*1); // vprp } break; case MUXER_TYPE_AUDIO: hdrsize+=WFSIZE(s->wf)+8; // strf s->h.fccHandler = s->wf->wFormatTag; break; } write_avi_list(muxer->stream,listtypeSTREAMHEADER,hdrsize); le2me_AVIStreamHeader(&s->h); write_avi_chunk(muxer->stream,ckidSTREAMHEADER,sizeof(s->h),&s->h); /* AVISTreamHeader */ // strh le2me_AVIStreamHeader(&s->h); switch(s->type){ case MUXER_TYPE_VIDEO: { int biSize=s->bih->biSize; le2me_BITMAPINFOHEADER(s->bih); write_avi_chunk(muxer->stream,ckidSTREAMFORMAT,biSize,s->bih); /* BITMAPINFOHEADER */ le2me_BITMAPINFOHEADER(s->bih); if (aspect != 0) { int fields = vprp.nbFieldPerFrame; le2me_VideoPropHeader(&vprp); le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[0]); le2me_VIDEO_FIELD_DESC(&vprp.FieldInfo[1]); write_avi_chunk(muxer->stream,mmioFOURCC('v','p','r','p'), sizeof(VideoPropHeader) - sizeof(VIDEO_FIELD_DESC)*(2-fields), &vprp); /* Video Properties Header */ } } break; case MUXER_TYPE_AUDIO: { int wfsize = WFSIZE(s->wf); le2me_WAVEFORMATEX(s->wf); write_avi_chunk(muxer->stream,ckidSTREAMFORMAT,wfsize,s->wf); /* WAVEFORMATEX */ le2me_WAVEFORMATEX(s->wf); } break; } if (isodml && si && si->superidx && si->superidxsize) { n = si->superidxsize; idxhdr[0] = le2me_32(mmioFOURCC('i', 'n', 'd', 'x')); idxhdr[1] = le2me_32(24 + 16*n); idxhdr[2] = le2me_32(0x00000004); idxhdr[3] = le2me_32(si->superidxpos); idxhdr[4] = le2me_32(s->ckid); idxhdr[5] = 0; idxhdr[6] = 0; idxhdr[7] = 0; stream_write_buffer(muxer->stream,idxhdr,sizeof(idxhdr)); for (j=0; j<n; j++) { struct avi_odmlsuperidx_entry *entry = &si->superidx[j]; unsigned int data[4]; data[0] = le2me_32(entry->ofs); data[1] = le2me_32(entry->ofs >> 32); data[2] = le2me_32(entry->len); data[3] = le2me_32(entry->duration); stream_write_buffer(muxer->stream,data,sizeof(data)); } } }
static struct demuxer *demux_open_stream(struct MPOpts *opts, struct stream *stream, int file_format, bool force, int audio_id, int video_id, int sub_id, char *filename, struct demuxer_params *params) { struct demuxer *demuxer = NULL; const struct demuxer_desc *desc; // If somebody requested a demuxer check it if (file_format) { desc = get_demuxer_desc_from_type(file_format); if (!desc) // should only happen with obsolete -demuxer 99 numeric format return NULL; demuxer = open_given_type(opts, desc, stream, force, audio_id, video_id, sub_id, filename, params); if (demuxer) goto dmx_open; return NULL; } // Test demuxers with safe file checks for (int i = 0; (desc = demuxer_list[i]); i++) { if (desc->safe_check) { demuxer = open_given_type(opts, desc, stream, false, audio_id, video_id, sub_id, filename, params); if (demuxer) goto dmx_open; } } // Ok. We're over the stable detectable fileformats, the next ones are // a bit fuzzy. So by default (extension_parsing==1) try extension-based // detection first: if (filename && opts->extension_parsing == 1) { desc = get_demuxer_desc_from_type(demuxer_type_by_filename(filename)); if (desc) demuxer = open_given_type(opts, desc, stream, false, audio_id, video_id, sub_id, filename, params); if (demuxer) goto dmx_open; } // Finally try detection for demuxers with unsafe checks for (int i = 0; (desc = demuxer_list[i]); i++) { if (!desc->safe_check && desc->check_file) { demuxer = open_given_type(opts, desc, stream, false, audio_id, video_id, sub_id, filename, params); if (demuxer) goto dmx_open; } } return NULL; dmx_open: if (demuxer->type == DEMUXER_TYPE_PLAYLIST) return demuxer; struct sh_video *sh_video = demuxer->video->sh; if (sh_video && sh_video->bih) { int biComp = le2me_32(sh_video->bih->biCompression); mp_msg(MSGT_DEMUX, MSGL_INFO, "VIDEO: [%.4s] %dx%d %dbpp %5.3f fps %5.1f kbps (%4.1f kbyte/s)\n", (char *) &biComp, sh_video->bih->biWidth, sh_video->bih->biHeight, sh_video->bih->biBitCount, sh_video->fps, sh_video->i_bps * 0.008f, sh_video->i_bps / 1024.0f); } return demuxer; }
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 decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { int h, w; AVFrame *pic = avctx->coded_frame; const uint8_t *psrc = avpkt->data; uint16_t *y, *u, *v; int aligned_width = ((avctx->width + 47) / 48) * 48; int stride = aligned_width * 8 / 3; if (pic->data[0]) avctx->release_buffer(avctx, pic); if (avpkt->size < stride * avctx->height) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return -1; } pic->reference = 0; if (avctx->get_buffer(avctx, pic) < 0) return -1; y = (uint16_t*)pic->data[0]; u = (uint16_t*)pic->data[1]; v = (uint16_t*)pic->data[2]; pic->pict_type = FF_I_TYPE; pic->key_frame = 1; #define READ_PIXELS(a, b, c) \ do { \ val = le2me_32(*src++); \ *a++ = val << 6; \ *b++ = (val >> 4) & 0xFFC0; \ *c++ = (val >> 14) & 0xFFC0; \ } while (0) for (h = 0; h < avctx->height; h++) { const uint32_t *src = (const uint32_t*)psrc; uint32_t val; for (w = 0; w < avctx->width - 5; w += 6) { READ_PIXELS(u, y, v); READ_PIXELS(y, u, y); READ_PIXELS(v, y, u); READ_PIXELS(y, v, y); } if (w < avctx->width - 1) { READ_PIXELS(u, y, v); val = le2me_32(*src++); *y++ = val << 6; } if (w < avctx->width - 3) { *u++ = (val >> 4) & 0xFFC0; *y++ = (val >> 14) & 0xFFC0; val = le2me_32(*src++); *v++ = val << 6; *y++ = (val >> 4) & 0xFFC0; } psrc += stride; y += pic->linesize[0] / 2 - avctx->width; u += pic->linesize[1] / 2 - avctx->width / 2; v += pic->linesize[2] / 2 - avctx->width / 2; }
int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf) { int hdr_len = asf->header.objh.size - sizeof(asf->header); int hdr_skip = 0; char *hdr = NULL; char guid_buffer[16]; int pos, start = stream_tell(demuxer->stream); uint32_t* streams = NULL; int audio_streams=0; int video_streams=0; uint16_t stream_count=0; int best_video = -1; int best_audio = -1; uint64_t data_len; ASF_stream_header_t *streamh; uint8_t *buffer; int audio_pos=0; if(hdr_len < 0) { mp_msg(MSGT_HEADER, MSGL_FATAL, "Header size is too small.\n"); return 0; } if (hdr_len > 1024 * 1024) { mp_tmsg(MSGT_HEADER, MSGL_ERR, "FATAL: header size bigger than 1 MB (%d)!\nPlease contact MPlayer authors, and upload/send this file.\n", hdr_len); hdr_skip = hdr_len - 1024 * 1024; hdr_len = 1024 * 1024; } hdr = malloc(hdr_len); if (!hdr) { mp_tmsg(MSGT_HEADER, MSGL_FATAL, "Could not allocate %d bytes for header.\n", hdr_len); return 0; } stream_read(demuxer->stream, hdr, hdr_len); if (hdr_skip) stream_skip(demuxer->stream, hdr_skip); if (stream_eof(demuxer->stream)) { mp_tmsg(MSGT_HEADER, MSGL_FATAL, "EOF while reading ASF header, broken/incomplete file?\n"); goto err_out; } if (is_drm(hdr, hdr_len)) mp_tmsg(MSGT_HEADER, MSGL_FATAL, "This file has been encumbered with DRM encryption, it will not play in MPlayer!\n"); if ((pos = find_asf_guid(hdr, asf_ext_stream_audio, 0, hdr_len)) >= 0) { // Special case: found GUID for dvr-ms audio. // Now skip back to associated stream header. int sh_pos=0; sh_pos = find_backwards_asf_guid(hdr, asf_stream_header_guid, pos); if (sh_pos > 0) { sh_audio_t *sh_audio; mp_msg(MSGT_HEADER, MSGL_V, "read_asf_header found dvr-ms audio stream header pos=%d\n", sh_pos); // found audio stream header - following code reads header and // initializes audio stream. audio_pos = pos - 16 - 8; streamh = (ASF_stream_header_t *)&hdr[sh_pos]; le2me_ASF_stream_header_t(streamh); audio_pos += 64; //16+16+4+4+4+16+4; buffer = &hdr[audio_pos]; sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F); sh_audio->needs_parsing = 1; mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "asfheader", streamh->stream_no & 0x7F); ++audio_streams; if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &audio_pos, &buffer, hdr, hdr_len)) goto len_err_out; if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 0)) goto len_err_out; } } // find stream headers // only reset pos if we didnt find dvr_ms audio stream // if we did find it then we want to avoid reading its header twice if (audio_pos == 0) pos = 0; while ((pos = find_asf_guid(hdr, asf_stream_header_guid, pos, hdr_len)) >= 0) { streamh = (ASF_stream_header_t *)&hdr[pos]; pos += sizeof(ASF_stream_header_t); if (pos > hdr_len) goto len_err_out; le2me_ASF_stream_header_t(streamh); mp_msg(MSGT_HEADER, MSGL_V, "stream type: %s\n", asf_chunk_type(streamh->type)); mp_msg(MSGT_HEADER, MSGL_V, "stream concealment: %s\n", asf_chunk_type(streamh->concealment)); mp_msg(MSGT_HEADER, MSGL_V, "type: %d bytes, stream: %d bytes ID: %d\n", (int)streamh->type_size, (int)streamh->stream_size, (int)streamh->stream_no); mp_msg(MSGT_HEADER, MSGL_V, "unk1: %lX unk2: %X\n", (unsigned long)streamh->unk1, (unsigned int)streamh->unk2); mp_msg(MSGT_HEADER, MSGL_V, "FILEPOS=0x%X\n", pos + start); // type-specific data: buffer = &hdr[pos]; pos += streamh->type_size; if (pos > hdr_len) goto len_err_out; switch(ASF_LOAD_GUID_PREFIX(streamh->type)) { case ASF_GUID_PREFIX_audio_stream: { sh_audio_t* sh_audio=new_sh_audio(demuxer,streamh->stream_no & 0x7F); mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Audio stream found, -aid %d\n", "asfheader", streamh->stream_no & 0x7F); ++audio_streams; if (!asf_init_audio_stream(demuxer, asf, sh_audio, streamh, &pos, &buffer, hdr, hdr_len)) goto len_err_out; //if(demuxer->audio->id==-1) demuxer->audio->id=streamh.stream_no & 0x7F; break; } case ASF_GUID_PREFIX_video_stream: { unsigned int len; float asp_ratio; sh_video_t* sh_video=new_sh_video(demuxer,streamh->stream_no & 0x7F); mp_tmsg(MSGT_DEMUX, MSGL_INFO, "[%s] Video stream found, -vid %d\n", "asfheader", streamh->stream_no & 0x7F); len=streamh->type_size-(4+4+1+2); ++video_streams; // sh_video->bih=malloc(chunksize); memset(sh_video->bih,0,chunksize); sh_video->bih=calloc((len<sizeof(BITMAPINFOHEADER))?sizeof(BITMAPINFOHEADER):len,1); memcpy(sh_video->bih,&buffer[4+4+1+2],len); le2me_BITMAPINFOHEADER(sh_video->bih); if (sh_video->bih->biSize > len && sh_video->bih->biSize > sizeof(BITMAPINFOHEADER)) sh_video->bih->biSize = len; if (sh_video->bih->biCompression == mmioFOURCC('D', 'V', 'R', ' ')) { //mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "DVR will probably only work with libavformat, try -demuxer 35 if you have problems\n"); //sh_video->fps=(float)sh_video->video.dwRate/(float)sh_video->video.dwScale; //sh_video->frametime=(float)sh_video->video.dwScale/(float)sh_video->video.dwRate; asf->asf_frame_state=-1; asf->asf_frame_start_found=0; asf->asf_is_dvr_ms=1; asf->dvr_last_vid_pts=0.0; } else asf->asf_is_dvr_ms=0; if (!get_ext_stream_properties(hdr, hdr_len, streamh->stream_no, asf, 1)) goto len_err_out; if (get_meta(hdr, hdr_len, streamh->stream_no, &asp_ratio)) { sh_video->aspect = asp_ratio * sh_video->bih->biWidth / sh_video->bih->biHeight; } sh_video->i_bps = asf->bps; if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_video_header(sh_video->bih, MSGL_V); //asf_video_id=streamh.stream_no & 0x7F; //if(demuxer->video->id==-1) demuxer->video->id=streamh.stream_no & 0x7F; break; } } // stream-specific data: // stream_read(demuxer->stream,(char*) buffer,streamh.stream_size); } // find file header pos = find_asf_guid(hdr, asf_file_header_guid, 0, hdr_len); if (pos >= 0) { ASF_file_header_t *fileh = (ASF_file_header_t *)&hdr[pos]; pos += sizeof(ASF_file_header_t); if (pos > hdr_len) goto len_err_out; le2me_ASF_file_header_t(fileh); mp_msg(MSGT_HEADER, MSGL_V, "ASF: packets: %d flags: %d " "max_packet_size: %d min_packet_size: %d max_bitrate: %d " "preroll: %d\n", (int)fileh->num_packets, (int)fileh->flags, (int)fileh->min_packet_size, (int)fileh->max_packet_size, (int)fileh->max_bitrate, (int)fileh->preroll); asf->packetsize=fileh->max_packet_size; asf->packet=malloc(asf->packetsize); // !!! asf->packetrate=fileh->max_bitrate/8.0/(double)asf->packetsize; asf->movielength=(fileh->play_duration-10000*fileh->preroll)/10000000.0; } // find content header pos = find_asf_guid(hdr, asf_content_desc_guid, 0, hdr_len); if (pos >= 0) { ASF_content_description_t *contenth = (ASF_content_description_t *)&hdr[pos]; char *string=NULL; uint16_t* wstring = NULL; uint16_t len; pos += sizeof(ASF_content_description_t); if (pos > hdr_len) goto len_err_out; le2me_ASF_content_description_t(contenth); mp_msg(MSGT_HEADER,MSGL_V,"\n"); // extract the title if((len = contenth->title_size) != 0) { wstring = (uint16_t*)&hdr[pos]; pos += len; if (pos > hdr_len) goto len_err_out; if ((string = get_ucs2str(wstring, len))) { mp_msg(MSGT_HEADER,MSGL_V," Title: %s\n", string); demux_info_add(demuxer, "title", string); free(string); } } // extract the author if((len = contenth->author_size) != 0) { wstring = (uint16_t*)&hdr[pos]; pos += len; if (pos > hdr_len) goto len_err_out; if ((string = get_ucs2str(wstring, len))) { mp_msg(MSGT_HEADER,MSGL_V," Author: %s\n", string); demux_info_add(demuxer, "author", string); free(string); } } // extract the copyright if((len = contenth->copyright_size) != 0) { wstring = (uint16_t*)&hdr[pos]; pos += len; if (pos > hdr_len) goto len_err_out; if ((string = get_ucs2str(wstring, len))) { mp_msg(MSGT_HEADER,MSGL_V," Copyright: %s\n", string); demux_info_add(demuxer, "copyright", string); free(string); } } // extract the comment if((len = contenth->comment_size) != 0) { wstring = (uint16_t*)&hdr[pos]; pos += len; if (pos > hdr_len) goto len_err_out; if ((string = get_ucs2str(wstring, len))) { mp_msg(MSGT_HEADER,MSGL_V," Comment: %s\n", string); demux_info_add(demuxer, "comments", string); free(string); } } // extract the rating if((len = contenth->rating_size) != 0) { wstring = (uint16_t*)&hdr[pos]; pos += len; if (pos > hdr_len) goto len_err_out; if ((string = get_ucs2str(wstring, len))) { mp_msg(MSGT_HEADER,MSGL_V," Rating: %s\n", string); free(string); } } mp_msg(MSGT_HEADER,MSGL_V,"\n"); } // find content header pos = find_asf_guid(hdr, asf_stream_group_guid, 0, hdr_len); if (pos >= 0) { int max_streams = (hdr_len - pos - 2) / 6; uint16_t stream_id, i; uint32_t max_bitrate; char *ptr = &hdr[pos]; mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == START ===\n"); if(max_streams <= 0) goto len_err_out; stream_count = AV_RL16(ptr); ptr += sizeof(uint16_t); if(stream_count > max_streams) stream_count = max_streams; if(stream_count > 0) streams = malloc(2*stream_count*sizeof(uint32_t)); mp_msg(MSGT_HEADER,MSGL_V," stream count=[0x%x][%u]\n", stream_count, stream_count ); for( i=0 ; i<stream_count ; i++ ) { stream_id = AV_RL16(ptr); ptr += sizeof(uint16_t); memcpy(&max_bitrate, ptr, sizeof(uint32_t));// workaround unaligment bug on sparc max_bitrate = le2me_32(max_bitrate); ptr += sizeof(uint32_t); mp_msg(MSGT_HEADER,MSGL_V," stream id=[0x%x][%u]\n", stream_id, stream_id ); mp_msg(MSGT_HEADER,MSGL_V," max bitrate=[0x%x][%u]\n", max_bitrate, max_bitrate ); streams[2*i] = stream_id; streams[2*i+1] = max_bitrate; } mp_msg(MSGT_HEADER,MSGL_V,"============ ASF Stream group == END ===\n"); } free(hdr); hdr = NULL; start = stream_tell(demuxer->stream); // start of first data chunk stream_read(demuxer->stream, guid_buffer, 16); if (memcmp(guid_buffer, asf_data_chunk_guid, 16) != 0) { mp_tmsg(MSGT_HEADER, MSGL_FATAL, "No data chunk following header!\n"); free(streams); streams = NULL; return 0; } // read length of chunk stream_read(demuxer->stream, (char *)&data_len, sizeof(data_len)); data_len = le2me_64(data_len); demuxer->movi_start = stream_tell(demuxer->stream) + 26; demuxer->movi_end = start + data_len; mp_msg(MSGT_HEADER, MSGL_V, "Found movie at 0x%X - 0x%X\n", (int)demuxer->movi_start, (int)demuxer->movi_end); if(streams) { // stream selection is done in the network code, it shouldn't be done here // as the servers often do not care about what we requested. #if 0 uint32_t vr = 0, ar = 0,i; #ifdef CONFIG_NETWORK if( demuxer->stream->streaming_ctrl!=NULL ) { if( demuxer->stream->streaming_ctrl->bandwidth!=0 && demuxer->stream->streaming_ctrl->data!=NULL ) { best_audio = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->audio_id; best_video = ((asf_http_streaming_ctrl_t*)demuxer->stream->streaming_ctrl->data)->video_id; } } else #endif for(i = 0; i < stream_count; i++) { uint32_t id = streams[2*i]; uint32_t rate = streams[2*i+1]; if(demuxer->v_streams[id] && rate > vr) { vr = rate; best_video = id; } else if(demuxer->a_streams[id] && rate > ar) { ar = rate; best_audio = id; } } #endif free(streams); streams = NULL; } mp_msg(MSGT_HEADER,MSGL_V,"ASF: %d audio and %d video streams found\n",audio_streams,video_streams); if(!audio_streams) demuxer->audio->id=-2; // nosound else if(best_audio > 0 && demuxer->audio->id == -1) demuxer->audio->id=best_audio; if(!video_streams) { if(!audio_streams) { mp_tmsg(MSGT_HEADER,MSGL_ERR,"ASF: no audio or video headers found - broken file?\n"); return 0; } demuxer->video->id=-2; // audio-only } else if (best_video > 0 && demuxer->video->id == -1) demuxer->video->id = best_video; #if 0 if( mp_msg_test(MSGT_HEADER,MSGL_V) ) { printf("ASF duration: %d\n",(int)fileh.duration); printf("ASF start pts: %d\n",(int)fileh.start_timestamp); printf("ASF end pts: %d\n",(int)fileh.end_timestamp); } #endif return 1; len_err_out: mp_tmsg(MSGT_HEADER, MSGL_FATAL, "Invalid length in ASF header!\n"); err_out: if (hdr) free(hdr); if (streams) free(streams); return 0; }
/** * The core transformation. Process a 512-bit block. * * @param hash algorithm state * @param block the message block to process */ static void has160_process_block(unsigned* hash, const unsigned* block) { unsigned X[32]; { unsigned j; for(j = 0; j < 16; j++) { X[j] = le2me_32(block[j]); } X[16] = X[ 0] ^ X[ 1] ^ X[ 2] ^ X[ 3]; /* for rounds 1..20 */ X[17] = X[ 4] ^ X[ 5] ^ X[ 6] ^ X[ 7]; X[18] = X[ 8] ^ X[ 9] ^ X[10] ^ X[11]; X[19] = X[12] ^ X[13] ^ X[14] ^ X[15]; X[20] = X[ 3] ^ X[ 6] ^ X[ 9] ^ X[12]; /* for rounds 21..40 */ X[21] = X[ 2] ^ X[ 5] ^ X[ 8] ^ X[15]; X[22] = X[ 1] ^ X[ 4] ^ X[11] ^ X[14]; X[23] = X[ 0] ^ X[ 7] ^ X[10] ^ X[13]; X[24] = X[ 5] ^ X[ 7] ^ X[12] ^ X[14]; /* for rounds 41..60 */ X[25] = X[ 0] ^ X[ 2] ^ X[ 9] ^ X[11]; X[26] = X[ 4] ^ X[ 6] ^ X[13] ^ X[15]; X[27] = X[ 1] ^ X[ 3] ^ X[ 8] ^ X[10]; X[28] = X[ 2] ^ X[ 7] ^ X[ 8] ^ X[13]; /* for rounds 61..80 */ X[29] = X[ 3] ^ X[ 4] ^ X[ 9] ^ X[14]; X[30] = X[ 0] ^ X[ 5] ^ X[10] ^ X[15]; X[31] = X[ 1] ^ X[ 6] ^ X[11] ^ X[12]; } { unsigned A, B, C, D, E; A = hash[0]; B = hash[1]; C = hash[2]; D = hash[3]; E = hash[4]; STEP_F1(A,B,C,D,E,X[18], 5); STEP_F1(E,A,B,C,D,X[ 0],11); STEP_F1(D,E,A,B,C,X[ 1], 7); STEP_F1(C,D,E,A,B,X[ 2],15); STEP_F1(B,C,D,E,A,X[ 3], 6); STEP_F1(A,B,C,D,E,X[19],13); STEP_F1(E,A,B,C,D,X[ 4], 8); STEP_F1(D,E,A,B,C,X[ 5],14); STEP_F1(C,D,E,A,B,X[ 6], 7); STEP_F1(B,C,D,E,A,X[ 7],12); STEP_F1(A,B,C,D,E,X[16], 9); STEP_F1(E,A,B,C,D,X[ 8],11); STEP_F1(D,E,A,B,C,X[ 9], 8); STEP_F1(C,D,E,A,B,X[10],15); STEP_F1(B,C,D,E,A,X[11], 6); STEP_F1(A,B,C,D,E,X[17],12); STEP_F1(E,A,B,C,D,X[12], 9); STEP_F1(D,E,A,B,C,X[13],14); STEP_F1(C,D,E,A,B,X[14], 5); STEP_F1(B,C,D,E,A,X[15],13); STEP_F2(A,B,C,D,E,X[22], 5); STEP_F2(E,A,B,C,D,X[ 3],11); STEP_F2(D,E,A,B,C,X[ 6], 7); STEP_F2(C,D,E,A,B,X[ 9],15); STEP_F2(B,C,D,E,A,X[12], 6); STEP_F2(A,B,C,D,E,X[23],13); STEP_F2(E,A,B,C,D,X[15], 8); STEP_F2(D,E,A,B,C,X[ 2],14); STEP_F2(C,D,E,A,B,X[ 5], 7); STEP_F2(B,C,D,E,A,X[ 8],12); STEP_F2(A,B,C,D,E,X[20], 9); STEP_F2(E,A,B,C,D,X[11],11); STEP_F2(D,E,A,B,C,X[14], 8); STEP_F2(C,D,E,A,B,X[ 1],15); STEP_F2(B,C,D,E,A,X[ 4], 6); STEP_F2(A,B,C,D,E,X[21],12); STEP_F2(E,A,B,C,D,X[ 7], 9); STEP_F2(D,E,A,B,C,X[10],14); STEP_F2(C,D,E,A,B,X[13], 5); STEP_F2(B,C,D,E,A,X[ 0],13); STEP_F3(A,B,C,D,E,X[26], 5); STEP_F3(E,A,B,C,D,X[12],11); STEP_F3(D,E,A,B,C,X[ 5], 7); STEP_F3(C,D,E,A,B,X[14],15); STEP_F3(B,C,D,E,A,X[ 7], 6); STEP_F3(A,B,C,D,E,X[27],13); STEP_F3(E,A,B,C,D,X[ 0], 8); STEP_F3(D,E,A,B,C,X[ 9],14); STEP_F3(C,D,E,A,B,X[ 2], 7); STEP_F3(B,C,D,E,A,X[11],12); STEP_F3(A,B,C,D,E,X[24], 9); STEP_F3(E,A,B,C,D,X[ 4],11); STEP_F3(D,E,A,B,C,X[13], 8); STEP_F3(C,D,E,A,B,X[ 6],15); STEP_F3(B,C,D,E,A,X[15], 6); STEP_F3(A,B,C,D,E,X[25],12); STEP_F3(E,A,B,C,D,X[ 8], 9); STEP_F3(D,E,A,B,C,X[ 1],14); STEP_F3(C,D,E,A,B,X[10], 5); STEP_F3(B,C,D,E,A,X[ 3],13); STEP_F4(A,B,C,D,E,X[30], 5); STEP_F4(E,A,B,C,D,X[ 7],11); STEP_F4(D,E,A,B,C,X[ 2], 7); STEP_F4(C,D,E,A,B,X[13],15); STEP_F4(B,C,D,E,A,X[ 8], 6); STEP_F4(A,B,C,D,E,X[31],13); STEP_F4(E,A,B,C,D,X[ 3], 8); STEP_F4(D,E,A,B,C,X[14],14); STEP_F4(C,D,E,A,B,X[ 9], 7); STEP_F4(B,C,D,E,A,X[ 4],12); STEP_F4(A,B,C,D,E,X[28], 9); STEP_F4(E,A,B,C,D,X[15],11); STEP_F4(D,E,A,B,C,X[10], 8); STEP_F4(C,D,E,A,B,X[ 5],15); STEP_F4(B,C,D,E,A,X[ 0], 6); STEP_F4(A,B,C,D,E,X[29],12); STEP_F4(E,A,B,C,D,X[11], 9); STEP_F4(D,E,A,B,C,X[ 6],14); STEP_F4(C,D,E,A,B,X[ 1], 5); STEP_F4(B,C,D,E,A,X[12],13); hash[0] += A; hash[1] += B; hash[2] += C; hash[3] += D; hash[4] += E; } }
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; }
// 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; }
extern int vorbis_comment (AVFormatContext * as, char *buf, int size) { char *p = buf; int s, n, j; if (size < 4) return -1; s = le2me_32 (unaligned32 (p)); p += 4; size -= 4; if (size < s + 4) return -1; p += s; size -= s; n = le2me_32 (unaligned32 (p)); p += 4; size -= 4; while (size >= 4){ char *t, *v; int tl, vl; s = le2me_32 (unaligned32 (p)); p += 4; size -= 4; if (size < s) break; t = p; p += s; size -= s; n--; v = memchr (t, '=', s); if (!v) continue; tl = v - t; vl = s - tl - 1; v++; if (tl && vl){ char tt[tl + 1]; char ct[vl + 1]; for (j = 0; j < tl; j++) tt[j] = toupper (t[j]); tt[tl] = 0; memcpy (ct, v, vl); ct[vl] = 0; // took from Vorbis_I_spec if (!strcmp (tt, "AUTHOR")) strncpy (as->author, ct, FFMIN(sizeof (as->author), vl)); else if (!strcmp (tt, "TITLE")) strncpy (as->title, ct, FFMIN(sizeof (as->title), vl)); else if (!strcmp (tt, "COPYRIGHT")) strncpy (as->copyright, ct, FFMIN(sizeof (as->copyright), vl)); else if (!strcmp (tt, "DESCRIPTION")) strncpy (as->comment, ct, FFMIN(sizeof (as->comment), vl)); else if (!strcmp (tt, "GENRE")) strncpy (as->genre, ct, FFMIN(sizeof (as->genre), vl)); else if (!strcmp (tt, "TRACKNUMBER")) as->track = atoi (ct); //Too bored to add others for today } } if (size > 0) av_log (as, AV_LOG_INFO, "%i bytes of comment header remain\n", size); if (n > 0) av_log (as, AV_LOG_INFO, "truncated comment header, %i comments not found\n", n); return 0; }