📄 libmpeg3.c
字号:
#include "libmpeg3.h"#include "mpeg3protos.h"#include <fcntl.h>#include <stdlib.h>#include <string.h>#ifndef MAX#define MAX(a, b) ((a) > (b) ? (a) : (b))#endifmpeg3_t* mpeg3_new(const char *path){ int i; mpeg3_t *file = calloc(1, sizeof(mpeg3_t)); file->cpus = 1; file->fs = mpeg3_new_fs(path); file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1); file->seekable = 1; return file;}int mpeg3_delete(mpeg3_t *file){ int i; for(i = 0; i < file->total_vstreams; i++) mpeg3_delete_vtrack(file, file->vtrack[i]); for(i = 0; i < file->total_astreams; i++) mpeg3_delete_atrack(file, file->atrack[i]); mpeg3_delete_fs(file->fs); mpeg3_delete_demuxer(file->demuxer); if(file->frame_offsets) { for(i = 0; i < file->total_vstreams; i++) { free(file->frame_offsets[i]); free(file->keyframe_numbers[i]); } free(file->frame_offsets); free(file->keyframe_numbers); free(file->total_frame_offsets); free(file->total_keyframe_numbers); } if(file->sample_offsets) { for(i = 0; i < file->total_astreams; i++) free(file->sample_offsets[i]); free(file->sample_offsets); free(file->total_sample_offsets); } free(file); return 0;}int mpeg3_check_sig(const char *path){ mpeg3_fs_t *fs; uint32_t bits; char *ext; int result = 0; fs = mpeg3_new_fs(path); if(mpeg3io_open_file(fs)) {/* File not found */ return 0; } bits = mpeg3io_read_int32(fs);/* Test header */ if(bits == MPEG3_TOC_PREFIX) { result = 1; } else if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) || (bits == MPEG3_PACK_START_CODE) || ((bits & 0xfff00000) == 0xfff00000) || ((bits & 0xffff0000) == 0xffe30000) || (bits == MPEG3_SEQUENCE_START_CODE) || (bits == MPEG3_PICTURE_START_CODE) || (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) || ((bits >> 8) == MPEG3_ID3_PREFIX) || (bits == MPEG3_RIFF_CODE) || (bits == MPEG3_IFO_PREFIX)) { result = 1; ext = strrchr(path, '.'); if(ext) {/* Test file extension. */ if(strncasecmp(ext, ".ifo", 4) && strncasecmp(ext, ".mp2", 4) && strncasecmp(ext, ".mp3", 4) && strncasecmp(ext, ".m1v", 4) && strncasecmp(ext, ".m2v", 4) && strncasecmp(ext, ".m2s", 4) && strncasecmp(ext, ".mpg", 4) && strncasecmp(ext, ".vob", 4) && strncasecmp(ext, ".mpeg", 4) && strncasecmp(ext, ".ac3", 4)) result = 0; } } mpeg3io_close_file(fs); mpeg3_delete_fs(fs); return result;}static uint32_t read_int32(unsigned char *buffer, int *position){ uint32_t temp; if(MPEG3_LITTLE_ENDIAN) { ((unsigned char*)&temp)[3] = buffer[(*position)++]; ((unsigned char*)&temp)[2] = buffer[(*position)++]; ((unsigned char*)&temp)[1] = buffer[(*position)++]; ((unsigned char*)&temp)[0] = buffer[(*position)++]; } else { ((unsigned char*)&temp)[0] = buffer[(*position)++]; ((unsigned char*)&temp)[1] = buffer[(*position)++]; ((unsigned char*)&temp)[2] = buffer[(*position)++]; ((unsigned char*)&temp)[3] = buffer[(*position)++]; } return temp;}static uint64_t read_int64(unsigned char *buffer, int *position){ uint64_t temp; if(MPEG3_LITTLE_ENDIAN) { ((unsigned char*)&temp)[7] = buffer[(*position)++]; ((unsigned char*)&temp)[6] = buffer[(*position)++]; ((unsigned char*)&temp)[5] = buffer[(*position)++]; ((unsigned char*)&temp)[4] = buffer[(*position)++]; ((unsigned char*)&temp)[3] = buffer[(*position)++]; ((unsigned char*)&temp)[2] = buffer[(*position)++]; ((unsigned char*)&temp)[1] = buffer[(*position)++]; ((unsigned char*)&temp)[0] = buffer[(*position)++]; } else { ((unsigned char*)&temp)[0] = buffer[(*position)++]; ((unsigned char*)&temp)[1] = buffer[(*position)++]; ((unsigned char*)&temp)[2] = buffer[(*position)++]; ((unsigned char*)&temp)[3] = buffer[(*position)++]; ((unsigned char*)&temp)[4] = buffer[(*position)++]; ((unsigned char*)&temp)[5] = buffer[(*position)++]; ((unsigned char*)&temp)[6] = buffer[(*position)++]; ((unsigned char*)&temp)[7] = buffer[(*position)++]; } return temp;}static int read_toc(mpeg3_t *file){ unsigned char *buffer; int file_type; int position = 4; int stream_type; int atracks; int vtracks; int i, j; buffer = malloc(mpeg3io_total_bytes(file->fs)); mpeg3io_seek(file->fs, 0); mpeg3io_read_data(buffer, mpeg3io_total_bytes(file->fs), file->fs);//printf("read_toc %lld\n", mpeg3io_total_bytes(file->fs));// File type file_type = buffer[position++]; switch(file_type) { case FILE_TYPE_PROGRAM: file->is_program_stream = 1; break; case FILE_TYPE_TRANSPORT: file->is_transport_stream = 1; break; case FILE_TYPE_AUDIO: file->is_audio_stream = 1; break; case FILE_TYPE_VIDEO: file->is_video_stream = 1; break; }// Stream ID's while((stream_type = buffer[position]) != TITLE_PATH) { int offset; int stream_id;//printf("read_toc %d %x\n", position, buffer[position]); position++; offset = read_int32(buffer, &position); stream_id = read_int32(buffer, &position); if(stream_type == STREAM_AUDIO) { file->demuxer->astream_table[offset] = stream_id; } if(stream_type == STREAM_VIDEO) { file->demuxer->vstream_table[offset] = stream_id; } }// Titles while(buffer[position] == TITLE_PATH) { char string[MPEG3_STRLEN]; int string_len = 0; mpeg3_title_t *title; position++; while(buffer[position] != 0) string[string_len++] = buffer[position++]; string[string_len++] = 0; position++; title = file->demuxer->titles[file->demuxer->total_titles++] = mpeg3_new_title(file, string); title->total_bytes = read_int64(buffer, &position);// Cells title->timecode_table_size = title->timecode_table_allocation = read_int32(buffer, &position); title->timecode_table = calloc(title->timecode_table_size, sizeof(mpeg3demux_timecode_t)); for(i = 0; i < title->timecode_table_size; i++) { title->timecode_table[i].start_byte = read_int64(buffer, &position); title->timecode_table[i].end_byte = read_int64(buffer, &position); title->timecode_table[i].program = read_int32(buffer, &position); } }// Audio streams// Skip ATRACK_COUNT position++; atracks = read_int32(buffer, &position);// Skip VTRACK_COUNT position++; vtracks = read_int32(buffer, &position); if(atracks) { file->sample_offsets = malloc(sizeof(int64_t*) * atracks); file->total_sample_offsets = malloc(sizeof(int*) * atracks); for(i = 0; i < atracks; i++) { file->total_sample_offsets[i] = read_int32(buffer, &position); file->sample_offsets[i] = malloc(file->total_sample_offsets[i] * sizeof(int64_t)); for(j = 0; j < file->total_sample_offsets[i]; j++) { file->sample_offsets[i][j] = read_int64(buffer, &position);//printf("samples %llx\n", file->sample_offsets[i][j]); } } } if(vtracks) { file->frame_offsets = malloc(sizeof(int64_t*) * vtracks); file->total_frame_offsets = malloc(sizeof(int*) * vtracks); file->keyframe_numbers = malloc(sizeof(int64_t*) * vtracks); file->total_keyframe_numbers = malloc(sizeof(int*) * vtracks); for(i = 0; i < vtracks; i++) { file->total_frame_offsets[i] = read_int32(buffer, &position); file->frame_offsets[i] = malloc(file->total_frame_offsets[i] * sizeof(int64_t)); for(j = 0; j < file->total_frame_offsets[i]; j++) { file->frame_offsets[i][j] = read_int64(buffer, &position);//printf("frame %llx\n", file->frame_offsets[i][j]); } file->total_keyframe_numbers[i] = read_int32(buffer, &position); file->keyframe_numbers[i] = malloc(file->total_keyframe_numbers[i] * sizeof(int64_t)); for(j = 0; j < file->total_keyframe_numbers[i]; j++) { file->keyframe_numbers[i][j] = read_int64(buffer, &position); } } } free(buffer);//printf("read_toc 1\n"); mpeg3demux_open_title(file->demuxer, 0);//printf("read_toc 2 %llx\n", mpeg3demux_tell(file->demuxer)); return 0;}mpeg3_t* mpeg3_open_copy(const char *path, mpeg3_t *old_file){ mpeg3_t *file = 0; unsigned int bits; int i, done;/* Initialize the file structure */ file = mpeg3_new(path);//printf("mpeg3_open_copy %s\n", path);/* Need to perform authentication before reading a single byte. */ if(mpeg3io_open_file(file->fs)) { mpeg3_delete(file); return 0; }/* =============================== Create the title objects ========================= */ bits = mpeg3io_read_int32(file->fs);//printf("mpeg3_open 1 %p %d %d %d %d\n", old_file, file->is_transport_stream, file->is_program_stream, file->is_video_stream, file->is_audio_stream); if(bits == MPEG3_TOC_PREFIX) /* TOC */ {/* Table of contents for another title set */ if(!old_file) {//printf("libmpeg3 1\n"); if(read_toc(file)) {//printf("libmpeg3 1\n"); mpeg3io_close_file(file->fs); mpeg3_delete(file); return 0; }//printf("libmpeg3 1\n"); } mpeg3io_close_file(file->fs); } else// IFO file#ifndef _WIN32 if(bits == MPEG3_IFO_PREFIX) {//printf("libmpeg3 1\n"); if(!old_file) {//printf("libmpeg3 2\n"); if(mpeg3_read_ifo(file, 0)) { mpeg3_delete(file); mpeg3io_close_file(file->fs); return 0; }//printf("libmpeg3 3\n"); } file->is_ifo_file = 1; mpeg3io_close_file(file->fs); } else#endif if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) {/* Transport stream *///printf("libmpeg3 2\n"); file->is_transport_stream = 1; } else if(bits == MPEG3_PACK_START_CODE) {/* Program stream *//* Determine packet size empirically *///printf("libmpeg3 3\n"); file->is_program_stream = 1; } else if((bits & 0xfff00000) == 0xfff00000 || (bits & 0xffff0000) == 0xffe30000 || ((bits >> 8) == MPEG3_ID3_PREFIX) || (bits == MPEG3_RIFF_CODE)) {/* MPEG Audio only *///printf("libmpeg3 4\n"); file->is_audio_stream = 1; } else if(bits == MPEG3_SEQUENCE_START_CODE || bits == MPEG3_PICTURE_START_CODE) {/* Video only *///printf("libmpeg3 5\n"); file->is_video_stream = 1; } else if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -