📄 mkv_read.c.svn-base
字号:
/* * Copyright (C) 2009 cooleyes * eyes.cooleyes@gmail.com * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */#include "mkv_read.h"#include "ebml_id.h"static void zero_set_mkv_read_output_struct(struct mkv_read_output_struct *p) { p->size = 0; p->data = 0; p->timestamp = 0;}static void copy_mkv_read_output_struct(struct mkv_read_output_struct *dest, struct mkv_read_output_struct *src) { dest->size = src->size; dest->data = src->data; dest->timestamp = src->timestamp;}static int in_mkv_read_queue(struct mkv_read_output_struct* queue, unsigned int* queue_size, unsigned int* queue_rear, unsigned int queue_max, struct mkv_read_output_struct* item) { if ( *queue_size+1 > queue_max ) return 0; copy_mkv_read_output_struct(&queue[*queue_rear], item); *queue_rear = (*queue_rear+1)%queue_max; *queue_size += 1; return 1;}static int out_mkv_read_queue(struct mkv_read_output_struct* queue, unsigned int* queue_size, unsigned int* queue_front, unsigned int queue_max, struct mkv_read_output_struct* item) { if ( *queue_size == 0 ) return 0; copy_mkv_read_output_struct(item, &queue[*queue_front]); zero_set_mkv_read_output_struct(&queue[*queue_front]); *queue_front = (*queue_front+1)%queue_max; *queue_size -= 1; return 1;}static void clear_mkv_read_queue(struct mkv_read_output_struct* queue, unsigned int* queue_size, unsigned int* queue_front, unsigned int* queue_rear, unsigned int queue_max) { unsigned int i; for(i=0; i<queue_max; i++) { if ( queue[i].data ) free_64(queue[i].data); zero_set_mkv_read_output_struct(&queue[i]); } *queue_size = 0; *queue_front = 0; *queue_rear = 0;}//static uint64_t mkv_read_be64(buffered_reader_t* reader) {// uint8_t data[8];// uint64_t result = 0;// int i;// // buffered_reader_read(reader, data, 8);// for (i = 0; i < 8; i++) {// result |= ((uint64_t)data[i]) << ((7 - i) * 8);// }//// return result;//}////static uint32_t mkv_read_be32(buffered_reader_t* reader) {// uint8_t data[4];// uint32_t result = 0;// uint32_t a, b, c, d;// // buffered_reader_read(reader, data, 4);// a = (uint8_t)data[0];// b = (uint8_t)data[1];// c = (uint8_t)data[2];// d = (uint8_t)data[3];// result = (a<<24) | (b<<16) | (c<<8) | d;//// return result;//}////static uint16_t mkv_read_be16(buffered_reader_t* reader) {// uint8_t data[2];// uint16_t result = 0;// uint16_t a, b;// // buffered_reader_read(reader, data, 2);// a = (uint8_t)data[0];// b = (uint8_t)data[1];// result = (a<<8) | b;//// return result;//}uint8_t mkv_read_8(buffered_reader_t* reader) { uint8_t result; buffered_reader_read(reader, &result, 1); return result;}uint32_t mkv_ebml_read_id (buffered_reader_t* reader, int32_t *length) { int32_t i, len_mask = 0x80; uint32_t id; for (i=0, id=mkv_read_8(reader); i<4 && !(id & len_mask); i++) len_mask >>= 1; if (i >= 4) return EBML_ID_INVALID; if (length) *length = i + 1; while (i--) id = (id << 8) | mkv_read_8(reader); return id;}uint64_t mkv_ebml_read_length(buffered_reader_t* reader, int32_t* length) { int32_t i, j, num_ffs = 0, len_mask = 0x80; uint64_t len; for (i=0, len=mkv_read_8(reader); i<8 && !(len & len_mask); i++) len_mask >>= 1; if (i >= 8) return EBML_UINT_INVALID; j = i+1; if (length) *length = j; if ((int)(len &= (len_mask - 1)) == len_mask - 1) num_ffs++; while (i--) { len = (len << 8) | mkv_read_8(reader); if ((len & 0xFF) == 0xFF) num_ffs++; } if (j == num_ffs) return EBML_UINT_INVALID; return len;}uint64_t mkv_ebml_read_uint(buffered_reader_t* reader, uint64_t* length) { uint64_t len, value = 0; int32_t l; len = mkv_ebml_read_length (reader, &l); if (len == EBML_UINT_INVALID || len < 1 || len > 8) return EBML_UINT_INVALID; if (length) *length = len + l; while (len--) value = (value << 8) | mkv_read_8(reader); return value;}int64_t mkv_ebml_read_int(buffered_reader_t* reader, uint64_t* length) { int64_t value = 0; uint64_t len; int32_t l; len = mkv_ebml_read_length (reader, &l); if (len == EBML_UINT_INVALID || len < 1 || len > 8) return EBML_INT_INVALID; if (length) *length = len + l; len--; l = mkv_read_8(reader); if (l & 0x80) value = -1; value = (value << 8) | l; while (len--) value = (value << 8) | mkv_read_8(reader); return value;}int32_t mkv_ebml_read_skip(buffered_reader_t* reader, uint64_t* length) { uint64_t len; int32_t l; len = mkv_ebml_read_length (reader, &l); if (len == EBML_UINT_INVALID) return 1; if (length) *length = len + l; buffered_reader_seek(reader, buffered_reader_position(reader)+len); return 0;}uint64_t mkv_ebml_read_vlen_uint(uint8_t* buffer, int32_t* length) { int32_t i, j, num_ffs = 0, len_mask = 0x80; uint64_t num; for (i=0, num=*buffer++; i<8 && !(num & len_mask); i++) len_mask >>= 1; if (i >= 8) return EBML_UINT_INVALID; j = i+1; if (length) *length = j; if ((int)(num &= (len_mask - 1)) == len_mask - 1) num_ffs++; while (i--) { num = (num << 8) | *buffer++; if ((num & 0xFF) == 0xFF) num_ffs++; } if (j == num_ffs) return EBML_UINT_INVALID; return num;}int64_t mkv_ebml_read_vlen_int(uint8_t* buffer, int32_t *length) { uint64_t unum; int32_t l; unum = mkv_ebml_read_vlen_uint (buffer, &l); if (unum == EBML_UINT_INVALID) return EBML_INT_INVALID; if (length) *length = l; return unum - ((1 << ((7 * l) - 1)) - 1);}void mkv_read_safe_constructor(struct mkv_read_struct *p) { mkv_file_safe_constructor(&p->file); p->reader = 0; p->current_audio_track = 0; p->block_buffer = 0; int i; for(i=0; i<MKV_VIDEO_QUEUE_MAX; i++) zero_set_mkv_read_output_struct(&(p->video_queue[i])); p->video_queue_front = 0; p->video_queue_rear = 0; p->video_queue_size = 0; for(i=0; i<MKV_AUDIO_QUEUE_MAX; i++) zero_set_mkv_read_output_struct(&(p->audio_queue[i])); p->audio_queue_front = 0; p->audio_queue_rear = 0; p->audio_queue_size = 0; p->cluster_size = 0; p->cluster_timecode = 0; p->blockgroup_size = 0; p->block_size = 0;}void mkv_read_close(struct mkv_read_struct *p) { mkv_file_close(&p->file); if (!(p->reader)) buffered_reader_close(p->reader); if (p->block_buffer != 0) free_64(p->block_buffer); int i; for(i=0; i<MKV_VIDEO_QUEUE_MAX; i++) { if ( p->video_queue[i].data ) free_64(p->video_queue[i].data); } for(i=0; i<MKV_AUDIO_QUEUE_MAX; i++) { if ( p->audio_queue[i].data ) free_64(p->audio_queue[i].data); } mkv_read_safe_constructor(p);}char *mkv_read_open(struct mkv_read_struct *p, char *s) { mkv_read_safe_constructor(p); char *result = mkv_file_open(&p->file, s); if (result != 0) { mkv_read_close(p); return(result); } //p->reader = buffered_reader_open(s, 32768, 0); p->reader = buffered_reader_open(s, 96*1024, 0, 0x30); if (!p->reader) { mkv_read_close(p); return("mkv_read_open: can't open file"); } buffered_reader_seek(p->reader, p->file.info->indexes[0].filepos); return(0);}int mkv_read_block_lacing(uint8_t *buffer, uint64_t *size, uint8_t *laces, int32_t *all_lace_sizes) { uint32_t total = 0; uint8_t flags; int i; /* lacing flags */ flags = *buffer++; (*size)--; switch ((flags & 0x06) >> 1) { case 0: /* no lacing */ *laces = 1; all_lace_sizes[0] = *size; break; case 1: /* xiph lacing */ case 2: /* fixed-size lacing */ case 3: /* EBML lacing */ *laces = *buffer++; (*size)--; (*laces)++; switch ((flags & 0x06) >> 1) { case 1: /* xiph lacing */ for (i=0; i < *laces-1; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -