⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mkv_read.c.svn-base

📁 psp播放器PPA源码,在MSYS/CYGWIN环境下编译(GNU-C)
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
						all_lace_sizes[i] = 0; 						do {							all_lace_sizes[i] += *buffer;							(*size)--;						} while (*buffer++ == 0xFF);						total += all_lace_sizes[i];					}					all_lace_sizes[i] = *size - total;					break;				case 2:  /* fixed-size lacing */					for (i=0; i < *laces; i++)						all_lace_sizes[i] = *size / *laces;					break;				case 3:  /* EBML lacing */ {					int32_t l;					uint64_t num = mkv_ebml_read_vlen_uint(buffer, &l);					if (num == EBML_UINT_INVALID) {						return 0;					}					buffer += l;					*size -= l;					total = all_lace_sizes[0] = num;					for (i=1; i < *laces-1; i++) {						int64_t snum;						snum = mkv_ebml_read_vlen_int(buffer, &l);						if (snum == EBML_INT_INVALID) {							return 0;						}						buffer += l;						*size -= l;						all_lace_sizes[i] = all_lace_sizes[i-1] + snum;						total += all_lace_sizes[i];					}					all_lace_sizes[i] = *size - total;					break;				}			}			break;	}	return 1;}int mkv_handle_block(struct mkv_read_struct *p, uint8_t *block_buffer, uint64_t block_size,	int64_t block_bref, int64_t block_fref, uint8_t simpleblock, int track_id, int skip_to_keyframe) {	int32_t tracknum;	int32_t current_tracknum, video_tracknum, audio_tracknum;	int32_t tmp = 0;	int16_t time;	uint8_t flags;	uint64_t old_block_size;	int32_t lace_size[16];	uint8_t laces;	int64_t timecode;	int res;	int use_this_block = 1;		current_tracknum = p->file.info->tracks[track_id]->tracknum;	video_tracknum = p->file.info->tracks[p->file.video_track_id]->tracknum;	audio_tracknum = p->file.info->tracks[p->file.audio_track_ids[p->current_audio_track]]->tracknum;		tracknum = mkv_ebml_read_vlen_uint(block_buffer, &tmp);		block_buffer += tmp;	time = block_buffer[0] << 8 | block_buffer[1];	block_buffer += 2;	block_size -= tmp + 2;	old_block_size = block_size;	flags = block_buffer[0];	memset(lace_size, 0, 16*sizeof(int32_t));	res = mkv_read_block_lacing(block_buffer, &block_size, &laces, lace_size);	if (res != 1)		return res;		block_buffer += old_block_size - block_size;		timecode = ((p->cluster_timecode + time - p->file.info->first_timecode) * p->file.info->timecode_scale /1000000.0);	if (timecode < 0)		timecode = 0;			res = 1;		if ( tracknum == current_tracknum ) {		if ( skip_to_keyframe ) {			if ( simpleblock ) {				if (!(flags&0x80)) {					use_this_block = 0;					res = 0;				}			}			else if (block_bref != 0 || block_fref != 0) {            			use_this_block = 0;            			res = 0;            		}		}	}	else {		use_this_block = 0;		res = 0;		if ( !skip_to_keyframe && (tracknum == video_tracknum || tracknum == audio_tracknum) )			use_this_block = 1;	}		if ( use_this_block ) {		int i;		struct mkv_read_output_struct packet;		for (i=0; i < laces; i++) {			memset(&packet, 0, sizeof(struct mkv_read_output_struct));			packet.size = lace_size[i];			packet.data = malloc_64(packet.size);			if (packet.data == 0) {				return -2;			}			memcpy(packet.data, block_buffer, packet.size);			packet.timestamp = (int)timecode;			if ( tracknum == video_tracknum )				tmp = in_mkv_read_queue(p->video_queue, &p->video_queue_size, &p->video_queue_rear, MKV_VIDEO_QUEUE_MAX, &packet);			else				tmp = in_mkv_read_queue(p->audio_queue, &p->audio_queue_size, &p->audio_queue_rear, MKV_AUDIO_QUEUE_MAX, &packet);			if ( tmp == 0 )  {				return -1;			}			block_buffer+=packet.size;			if ( tracknum == video_tracknum )				timecode+=(1000LL*p->file.audio_resample_scale/p->file.audio_rate);			else				timecode+=(1000LL*p->file.video_scale/p->file.video_rate);		}	}		return(res);}char *mkv_read_fill_buffer(struct mkv_read_struct *p, int track_id, int skip_to_keyframe) {		int32_t il, tmp;	uint64_t l;	int res;		while (1) {		while (p->cluster_size > 0) {			uint64_t block_duration = 0;			int64_t block_bref = 0, block_fref = 0;			while (p->blockgroup_size > 0) {				switch (mkv_ebml_read_id(p->reader, &il)) {					case MATROSKA_ID_BLOCKDURATION: {						block_duration = mkv_ebml_read_uint(p->reader, &l);						if (block_duration == EBML_UINT_INVALID) {							if( p->block_buffer ) {								free_64(p->block_buffer);								p->block_buffer = 0;							}							return("mkv_read_fill_buffer: error block duration");						}						break;					}					case MATROSKA_ID_BLOCK: {						p->block_size = mkv_ebml_read_length(p->reader, &tmp);						if (p->block_size > SIZE_MAX - MKV_INPUT_PADDING) 							return("mkv_read_fill_buffer: error block size");						if( p->block_buffer ) {							free_64(p->block_buffer);							p->block_buffer = 0;						}						p->block_buffer = malloc_64(p->block_size+ MKV_INPUT_PADDING);						if ( !p->block_buffer )							return("mkv_read_fill_buffer: can not malloc_64 block_buffer");						if (buffered_reader_read(p->reader, p->block_buffer, p->block_size) != (uint32_t)(p->block_size)) {							free_64(p->block_buffer);							p->block_buffer = 0;							return("mkv_read_fill_buffer: can not read block");						}						l = tmp + p->block_size;						break;					}					case MATROSKA_ID_REFERENCEBLOCK: {						int64_t num = mkv_ebml_read_int(p->reader, &l);						if (num == EBML_INT_INVALID) {							if( p->block_buffer ) {								free_64(p->block_buffer);								p->block_buffer = 0;							}							return("mkv_read_fill_buffer: can not find block ref");						}						if (num <= 0)							block_bref = num;						else							block_fref = num;						break;					}					case EBML_ID_INVALID:						if( p->block_buffer ) {							free_64(p->block_buffer);							p->block_buffer = 0;						}						return("mkv_read_fill_buffer: read id invalid");					default:						mkv_ebml_read_skip(p->reader, &l);						break;				}				p->blockgroup_size -= l + il;				p->cluster_size -= l + il;			}			if (p->block_buffer) {				res = mkv_handle_block(p, (uint8_t *)(p->block_buffer), p->block_size, block_bref, block_fref, 0, track_id, skip_to_keyframe);				free_64(p->block_buffer);				p->block_buffer = 0;				if (res < 0) {					if ( res == -1 )						return("mkv_read_fill_buffer: queue is full");					else						return("mkv_read_fill_buffer: can not malloc_64 data buffer");				}				if (res)					return(0);			}			if (p->cluster_size > 0) {				switch (mkv_ebml_read_id(p->reader, &il)) {					case MATROSKA_ID_CLUSTERTIMECODE: {						uint64_t num = mkv_ebml_read_uint(p->reader, &l);						if (num == EBML_UINT_INVALID)							return("mkv_read_fill_buffer: invalid cluster timecode");												p->cluster_timecode = num;						break;					}					case MATROSKA_ID_BLOCKGROUP: {						p->blockgroup_size = mkv_ebml_read_length(p->reader, &tmp);						l = tmp;						break;					}					case MATROSKA_ID_SIMPLEBLOCK: {						int res;						p->block_size = mkv_ebml_read_length(p->reader, &tmp);						if (p->block_size > SIZE_MAX - MKV_INPUT_PADDING) 							return("mkv_read_fill_buffer: error block size");						if( p->block_buffer ) {							free_64(p->block_buffer);							p->block_buffer = 0;						}						p->block_buffer = malloc_64(p->block_size+ MKV_INPUT_PADDING);						if ( !p->block_buffer )							return("mkv_read_fill_buffer: can not malloc_64 block_buffer");						if (buffered_reader_read(p->reader, p->block_buffer, p->block_size) != (uint32_t)(p->block_size)) {							free_64(p->block_buffer);							p->block_buffer = 0;							return("mkv_read_fill_buffer: can not read block");						}						l = tmp + p->block_size;						res = mkv_handle_block (p, (uint8_t *)(p->block_buffer), p->block_size, block_bref, block_fref, 1, track_id, skip_to_keyframe);						free_64(p->block_buffer);						p->block_buffer = 0;						p->cluster_size -= l + il;						if (res < 0) {							if ( res == -1 )								return("mkv_read_fill_buffer: queue is full");							else								return("mkv_read_fill_buffer: can not malloc_64 data buffer");						}						else if (res)							return(0);						else 							p->cluster_size += l + il;						break;					}										case EBML_ID_INVALID:						return("mkv_read_fill_buffer: can not find block");;					default:						mkv_ebml_read_skip(p->reader, &l);						break;				}				p->cluster_size -= l + il;			}		}		if (mkv_ebml_read_id(p->reader, &il) != MATROSKA_ID_CLUSTER)			return("mkv_read_fill_buffer: eof");		p->cluster_size = mkv_ebml_read_length(p->reader, 0);	}	return(0);}char *mkv_read_seek(struct mkv_read_struct *p, int timestamp) {	int32_t video_tracknum = p->file.info->tracks[p->file.video_track_id]->tracknum;	int32_t i;	mkvinfo_index_t* index = 0;	if (timestamp < 0)		timestamp = 0;	for(i=0; i < p->file.info->total_indexes-1; i++) {		if ( p->file.info->indexes[i].tracknum == video_tracknum ) {			int64_t timecode = ((p->file.info->indexes[i].timecode - p->file.info->first_timecode) * p->file.info->timecode_scale /1000000.0);			int64_t next_timecode = ((p->file.info->indexes[i+1].timecode - p->file.info->first_timecode) * p->file.info->timecode_scale /1000000.0);			if (timestamp >= (int)timecode && timestamp < (int)next_timecode) {				index = p->file.info->indexes+i;				break;			}		}	}	if ( index == 0 ) {		index = p->file.info->indexes + (p->file.info->total_indexes-1);	}	buffered_reader_seek(p->reader, index->filepos);	p->cluster_size = p->blockgroup_size = 0;		clear_mkv_read_queue(p->audio_queue, &p->audio_queue_size, &p->audio_queue_front, &p->audio_queue_rear, MKV_VIDEO_QUEUE_MAX);	clear_mkv_read_queue(p->video_queue, &p->video_queue_size, &p->video_queue_front, &p->video_queue_rear, MKV_AUDIO_QUEUE_MAX);		return(mkv_read_fill_buffer(p, p->file.video_track_id, 1));}char *mkv_read_get_video(struct mkv_read_struct *p, struct mkv_read_output_struct *output) {	if ( p->video_queue_size > 0 )		out_mkv_read_queue(p->video_queue, &p->video_queue_size, &p->video_queue_front, MKV_VIDEO_QUEUE_MAX, output);	else {		char* res = mkv_read_fill_buffer(p, p->file.video_track_id, 0);		if (res)			return res;		if ( !(p->video_queue_size>0) )			return "mkv_read_get_video: video queue is empty";		out_mkv_read_queue(p->video_queue, &p->video_queue_size, &p->video_queue_front, MKV_VIDEO_QUEUE_MAX, output);	}	return(0);}char *mkv_read_get_audio(struct mkv_read_struct *p, unsigned int audio_stream, struct mkv_read_output_struct *output){	p->current_audio_track = audio_stream;	if ( p->audio_queue_size > 0 )		out_mkv_read_queue(p->audio_queue, &p->audio_queue_size, &p->audio_queue_front, MKV_AUDIO_QUEUE_MAX, output);	else {		char* res = mkv_read_fill_buffer(p, p->file.audio_track_ids[audio_stream], 0);		if (res)			return res;		if ( !(p->audio_queue_size>0) )			return "mkv_read_get_audio: audio queue is empty";		out_mkv_read_queue(p->audio_queue, &p->audio_queue_size, &p->audio_queue_front, MKV_AUDIO_QUEUE_MAX, output);	}	return(0);}

⌨️ 快捷键说明

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