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

📄 mpeg3ifo.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <mpeg4ip.h>#ifdef HAVE_BYTESWAP_H#include <byteswap.h>#endif#include <mpeg4ip_byteswap.h>#include <dirent.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <unistd.h>#include "ifo.h"#include "mpeg3private.h"#include "mpeg3protos.h"typedef struct{	int64_t start_byte;	int64_t end_byte;// Used in final table	int program;// Used in cell play info	int cell_type;// Used in cell addresses	int vob_id;	int cell_id;} mpeg3ifo_cell_t;typedef struct{	mpeg3ifo_cell_t *cells;	long total_cells;	long cells_allocated;} mpeg3ifo_celltable_t;#define CADDR_HDR_LEN 8typedef struct {	u_short	num		: 16;	// Number of Video Objects	u_short unknown		: 16;	// don't know	u_int	len		: 32;	// length of table} cell_addr_hdr_t;typedef struct {	u_int	foo		: 16;	// ???	u_int	num		: 16;	// number of subchannels} audio_hdr_t;#define AUDIO_HDR_LEN 4typedef struct {	u_short id		: 16;	// Language	u_short			: 16;	// don't know	u_int	start		: 32;	// Start of unit} pgci_sub_t;#define PGCI_SUB_LEN 8#define PGCI_COLOR_LEN 4static u_int get4bytes(u_char *buf){	return B2N_32(*((uint32_t *)buf));}static u_int get2bytes(u_char *buf){	return B2N_16(*((uint16_t *)buf));}static int ifo_read(int fd, long pos, long count, unsigned char *data){	if((pos = lseek(fd, pos, SEEK_SET)) < 0)	{    	perror("ifo_read");    	return -1;    }	return read(fd, data, count); }#define OFF_PTT get4bytes (ifo->data[ID_MAT] + 0xC8)#define OFF_TITLE_PGCI get4bytes (ifo->data[ID_MAT] + 0xCC)#define OFF_MENU_PGCI get4bytes (ifo->data[ID_MAT] + 0xD0)#define OFF_TMT get4bytes (ifo->data[ID_MAT] + 0xD4)#define OFF_MENU_CELL_ADDR get4bytes (ifo->data[ID_MAT] + 0xD8)#define OFF_MENU_VOBU_ADDR_MAP get4bytes (ifo->data[ID_MAT] + 0xDC)#define OFF_TITLE_CELL_ADDR get4bytes (ifo->data[ID_MAT] + 0xE0)#define OFF_TITLE_VOBU_ADDR_MAP get4bytes (ifo->data[ID_MAT] + 0xE4)#define OFF_VMG_TSP get4bytes (ifo->data[ID_MAT] + 0xC4)#define OFF_VMG_MENU_PGCI get4bytes (ifo->data[ID_MAT] + 0xC8)#define OFF_VMG_TMT get4bytes (ifo->data[ID_MAT] + 0xD0)static int ifo_vts(ifo_t *ifo){    if(!strncmp((char*)ifo->data[ID_MAT], "DVDVIDEO-VTS", 12)) 		return 0;	return -1;}static int ifo_vmg(ifo_t *ifo){    if(!strncmp((char*)ifo->data[ID_MAT], "DVDVIDEO-VMG", 12))		return 0;	return -1;}static int ifo_table(ifo_t *ifo, unsigned long offset, unsigned long tbl_id){	unsigned char *data;	unsigned long len = 0;	int i;	uint32_t *ptr;	if(!offset) return -1;	data = (u_char *)calloc(1, DVD_VIDEO_LB_LEN);	if(ifo_read(ifo->fd, ifo->pos + offset * DVD_VIDEO_LB_LEN, DVD_VIDEO_LB_LEN, data) <= 0) 	{		perror("ifo_table");		return -1;	}	switch(tbl_id)	{		case ID_TITLE_VOBU_ADDR_MAP:		case ID_MENU_VOBU_ADDR_MAP:			len = get4bytes(data) + 1;			break;		default: 		{			ifo_hdr_t *hdr = (ifo_hdr_t *)data;			len = B2N_32(hdr->len) + 1;		}	}	if(len > DVD_VIDEO_LB_LEN) 	{		data = (u_char *)realloc((void *)data, len);		bzero(data, len);		ifo_read(ifo->fd, ifo->pos + offset * DVD_VIDEO_LB_LEN, len, data);	}	ifo->data[tbl_id] = data;	ptr = (uint32_t*)data;	len /= 4;	if(tbl_id == ID_TMT) 		for (i = 0; i < len; i++)			ptr[i] = B2N_32(ptr[i]);	return 0;}static ifo_t* ifo_open(int fd, long pos){	ifo_t *ifo;	ifo = (ifo_t *)calloc(sizeof(ifo_t), 1);	ifo->data[ID_MAT] = (unsigned char *)calloc(DVD_VIDEO_LB_LEN, 1);	ifo->pos = pos; 	ifo->fd = fd;	if(ifo_read(fd, pos, DVD_VIDEO_LB_LEN, ifo->data[ID_MAT]) < 0) 	{		perror("ifo_open");		free(ifo->data[ID_MAT]);		free(ifo);		return NULL;	}	ifo->num_menu_vobs	= get4bytes(ifo->data[ID_MAT] + 0xC0);	ifo->vob_start		= get4bytes(ifo->data[ID_MAT] + 0xC4);#ifdef DEBUG	printf ("num of vobs: %x vob_start %x\n", ifo->num_menu_vobs, ifo->vob_start);#endif	if(!ifo_vts(ifo)) 	{		ifo_table(ifo, OFF_PTT, ID_PTT);    	ifo_table(ifo, OFF_TITLE_PGCI, ID_TITLE_PGCI);		ifo_table(ifo, OFF_MENU_PGCI, ID_MENU_PGCI);		ifo_table(ifo, OFF_TMT, ID_TMT);		ifo_table(ifo, OFF_MENU_CELL_ADDR, ID_MENU_CELL_ADDR);		ifo_table(ifo, OFF_MENU_VOBU_ADDR_MAP, ID_MENU_VOBU_ADDR_MAP);    	ifo_table(ifo, OFF_TITLE_CELL_ADDR, ID_TITLE_CELL_ADDR);		ifo_table(ifo, OFF_TITLE_VOBU_ADDR_MAP, ID_TITLE_VOBU_ADDR_MAP);	} 	else 	if(!ifo_vmg(ifo)) 	{		ifo_table(ifo, OFF_VMG_TSP, ID_TSP);		ifo_table(ifo, OFF_VMG_MENU_PGCI, ID_MENU_PGCI);		ifo_table(ifo, OFF_VMG_TMT, ID_TMT);		ifo_table(ifo, OFF_TITLE_CELL_ADDR, ID_TITLE_CELL_ADDR);		ifo_table(ifo, OFF_TITLE_VOBU_ADDR_MAP, ID_TITLE_VOBU_ADDR_MAP);	}	return ifo;}static int ifo_close(ifo_t *ifo){	if(ifo->data[ID_MAT]) free(ifo->data[ID_MAT]);	if(ifo->data[ID_PTT]) free(ifo->data[ID_PTT]);	if(ifo->data[ID_TITLE_PGCI]) free(ifo->data[ID_TITLE_PGCI]);	if(ifo->data[ID_MENU_PGCI]) free(ifo->data[ID_MENU_PGCI]);	if(ifo->data[ID_TMT]) free(ifo->data[ID_TMT]);	if(ifo->data[ID_MENU_CELL_ADDR]) free(ifo->data[ID_MENU_CELL_ADDR]);	if(ifo->data[ID_MENU_VOBU_ADDR_MAP]) free(ifo->data[ID_MENU_VOBU_ADDR_MAP]);	if(ifo->data[ID_TITLE_CELL_ADDR]) free(ifo->data[ID_TITLE_CELL_ADDR]);	if(ifo->data[ID_TITLE_VOBU_ADDR_MAP]) free(ifo->data[ID_TITLE_VOBU_ADDR_MAP]);	free(ifo);	return 0;}static int ifo_audio(char *_hdr, char **ptr){	audio_hdr_t *hdr = (audio_hdr_t *)_hdr;	if(!_hdr) return -1;	*ptr = _hdr + AUDIO_HDR_LEN;	return B2N_16(hdr->num);}static int pgci(ifo_hdr_t *hdr, int title, char **ptr){	pgci_sub_t *pgci_sub;	uint32_t temp;	*ptr = (char *) hdr;	if(!*ptr) return -1;	if(title > hdr->num) return -1;	*ptr += IFO_HDR_LEN;	pgci_sub = (pgci_sub_t *)*ptr + title;	temp = pgci_sub->start;	temp = B2N_32(temp);	*ptr = (char *)hdr + temp;	return 0;}static int program_map(char *pgc, char **ptr){	int num;	*ptr = pgc;	if (!pgc)		return -1;	*ptr += 2;		num = **ptr;	*ptr += 10;	*ptr += 8 * 2;			// AUDIO	*ptr += 32 * 4;			// SUBPICTURE	*ptr += 8;	*ptr += 16 * PGCI_COLOR_LEN;	// CLUT	*ptr += 2;	*ptr = get2bytes((unsigned char*)*ptr) + pgc;	return num;}static u_int get_cellplayinfo(u_char *pgc, u_char **ptr){	u_int num;	*ptr = pgc;	if (!pgc)		return -1;	*ptr += 3;		num = **ptr;	*ptr += 9;	*ptr += 8 * 2;			// AUDIO	*ptr += 32 * 4;			// SUBPICTURE	*ptr += 8;	*ptr += 16 * PGCI_COLOR_LEN;	// CLUT	*ptr += 4;	*ptr =  get2bytes(*ptr) + pgc;	return num;}static void get_ifo_playlist(mpeg3_t *file, mpeg3_demuxer_t *demuxer){	DIR *dirstream;	char directory[MPEG3_STRLEN];	char filename[MPEG3_STRLEN];	char complete_path[MPEG3_STRLEN];	char title_path[MPEG3_STRLEN];	char vob_prefix[MPEG3_STRLEN];	struct dirent *new_filename;	char *ptr;	int64_t total_bytes = 0;	int done = 0, i;// Get titles matching ifo file	mpeg3io_complete_path(complete_path, file->fs->path);	mpeg3io_get_directory(directory, complete_path);	mpeg3io_get_filename(filename, complete_path);	strncpy(vob_prefix, filename, 6);	dirstream = opendir(directory);	while(new_filename = readdir(dirstream))	{		if(!strncasecmp(new_filename->d_name, vob_prefix, 6))		{			ptr = strrchr(new_filename->d_name, '.');			if(ptr && !strncasecmp(ptr, ".vob", 4))			{// Got a title				if(atol(&new_filename->d_name[7]) > 0)				{					mpeg3_title_t *title;					mpeg3io_joinpath(title_path, directory, new_filename->d_name);					title = demuxer->titles[demuxer->total_titles++] = mpeg3_new_title(file, title_path);					title->total_bytes = mpeg3io_path_total_bytes(title_path);					total_bytes += title->total_bytes;//printf("%s\n", title_path);				}			}		}	}// Alphabetize titles.  Only problematic for guys who rip entire DVD's// to their hard drives while retaining the file structure.	while(!done)	{		done = 1;		for(i = 0; i < demuxer->total_titles - 1; i++)		{			if(strcmp(demuxer->titles[i]->fs->path, demuxer->titles[i + 1]->fs->path) > 0)			{				mpeg3_title_t *temp = demuxer->titles[i];				demuxer->titles[i] = demuxer->titles[i + 1];				demuxer->titles[i + 1] = temp;				done = 0;			}		}	}		}// IFO parsingstatic void get_ifo_header(mpeg3_demuxer_t *demuxer, ifo_t *ifo){	int i;// Video header	demuxer->vstream_table[0] = 1;// Audio header	if(!ifo_vts(ifo))	{		ifo_audio_t *audio;		int result = 0;// Doesn't detect number of tracks.		int atracks = ifo_audio((char*)ifo->data[ID_MAT] + IFO_OFFSET_AUDIO, (char**)&audio);		int atracks_empirical = 0;// Construct audio stream id's#define TEST_START 0x600000#define TEST_LEN   0x100000		mpeg3demux_open_title(demuxer, 0);		mpeg3demux_seek_byte(demuxer, TEST_START);		while(!result && 			!mpeg3demux_eof(demuxer) && 			mpeg3demux_tell(demuxer) < TEST_START + TEST_LEN)		{			result = mpeg3_read_next_packet(demuxer);

⌨️ 快捷键说明

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