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

📄 metadata.c

📁 Sun公司Dream项目
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the "License").  You may not use this file except
 * in compliance with the License.
 *
 * You can obtain a copy of the license at
 * http://www.opensource.org/licenses/cddl1.php
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * HEADER in each file and include the License file at
 * http://www.opensource.org/licenses/cddl1.php.  If 
 * applicable, add the following below this CDDL HEADER, 
 * with the fields enclosed by brackets "[]" replaced 
 * with your own identifying information: 
 * Portions Copyright [yyyy]
 * [name of copyright owner]
 */ 

/*
 * $(@)metadata.c $Revision: 1.2 $ $Date: 2006/07/15 00:02:36 $
 * 
 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
 */
/*
 * =====================================================================================
 * 
 *        Filename:  metadata.c
 * 
 *     Description:  This has routines for metadata creation and manipulation	 
 * 
 *         Version:  1.0
 *         Created:  09/03/04 19:03:54 PDT
 *        Revision:  none
 *        Compiler:  cc
 * 
 *          Author:   (Deepak Chandra), 
 *         Company:  Sun Microsystems Inc.
 *            Bugs:  Known Bug: For a particular stream speed whose metadata is
 *            already in the metadata file, a repeat mux for a stream of that
 *            speed causes meta file corruption.
 * =====================================================================================
 */




/*  Metadata file structure :

	Version no: 		1 bytes
	no_streams: 		1 bytes
 	meta_data_offset:	2 bytes  		

	for each stream:  {stream_metadata} 
	speed_of_stream: 4 bytes  :Just to be word aligned

*/

#include "metadata.h"
#include <assert.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>

//void initialize_stream(metadata *meta);
/*
	This function creates the metadata file.
 
  */


void initialize_stream(metadata *meta);
int  read_frame(metadata *meta, picFrame_metadata *frame);


metadata *init_metadata(char *meta_name, int speed){

	int ret_code;
	FILE *meta_file;
	metadata *ret;
	int err;
	stream_metadata *stream;
        metadata_header *header;	
	
	meta_file = fopen(meta_name,"wb");
	if (meta_file ==  NULL)
		FATAL_ERROR("cannot open the metadata file");

	header = (metadata_header *)malloc(sizeof(metadata_header));
	stream = (stream_metadata *)malloc(sizeof(stream_metadata));

	header->version = 	METADATA_VERSION;
	header->no_of_streams = 1;	  //this is the first stream
	header->metadata_offset = sizeof(*header) +
		                  1*sizeof(stream_metadata);
	stream->speed = speed;

	// write it to the file
	err = fwrite(header,1,sizeof(*header), meta_file);
	if (err != sizeof(*header))
		FATAL_ERROR("Unable to write to the file");
	err = fwrite(stream,1,sizeof(*stream),meta_file);				
	
	ret = (metadata*)malloc(sizeof(metadata));
	ret->header= header;
	ret->meta_file = meta_file;
	ret->stream_no  = 1; 
	ret->stream[0] = stream;
	return ret;
}	


metadata *open_metadata_file(char* metadata_file_name ){

	FILE *file;
        metadata_header *header;
   	int stream_no;
	int no_of_streams;
        stream_metadata *stream;
	int i;
	metadata *meta;	


	header = (metadata_header *)malloc(sizeof(metadata_header));			 
	stream = (stream_metadata *)malloc(sizeof(stream_metadata));
	meta = (metadata *)malloc(sizeof(metadata));
	meta->header = header;
	assert(metadata_file_name != NULL);	
        printf("%s",metadata_file_name);
        fflush(stdout);
	assert((file = fopen(metadata_file_name,"rb")) !=  NULL);
	meta->meta_file = file;	
	meta->meta_filename = metadata_file_name;


	assert(fread(header,1,sizeof(*header),file) != NULL);
	meta->header = header;
	

	if(header->version != METADATA_VERSION)	
		FATAL_ERROR("metadata version not supported");
	
	for(i=0;i<header->no_of_streams; i++){
		stream = (stream_metadata*)malloc(sizeof(stream_metadata));
    		assert(fread(stream,1,sizeof(*stream),file) != NULL);
		meta->stream[i] = stream;
	}

	meta->stream_no = -1; //no curr stream
	meta->speed = -1;



	
	
	return meta;
}


int open_temp_metafile(metadata *meta, int speed) {

        char *tmp_filename;
	FILE  *tmp_file;
	int i;
	metadata_header *header;
	int stream_no;
	stream_metadata *stream;
	
	assert(meta != NULL);
	assert(meta->header != NULL);
	assert(meta->stream != NULL);
	tmp_filename = (char*)malloc(strlen(meta->meta_filename)+10);	
	sprintf(tmp_filename,"%s.tmp",meta->meta_filename);
	//tmpnam(tmp_filename);
	assert((tmp_file = fopen(tmp_filename,"wb")) != NULL);
	meta->tmp_file = tmp_file;
	meta->tmp_filename = tmp_filename;
	meta->total_frames = 0;   //to keep track of already seen frames
	
	header = meta->header;
	for(i=0, stream_no = -1;i<header->no_of_streams; i++){
	    	if(meta->stream[i]->speed == speed)
			stream_no = i;
	}

	if (stream_no == -1){
		stream_no = header->no_of_streams++;
		stream = (stream_metadata*)malloc(sizeof(stream_metadata));
		meta->stream[stream_no] = stream;
		stream->speed= speed;
		initialize_stream(meta);

	} else {
        // FIXME
        fprintf(stderr,"\nStream already exists. Cannot handle condition FIXME");
        // exit(-1);
        // return 0;
		header->metadata_offset = sizeof(*header) +
		                  header->no_of_streams*sizeof(stream_metadata);
		//writing to tmp file 

		fwrite(meta->header,1,sizeof(metadata_header),tmp_file);
		for(i=0;i<header->no_of_streams; i++)
			fwrite(meta->stream[i],1,sizeof(stream_metadata), tmp_file);
	}


	meta->speed = speed;
	meta->stream_no = stream_no;

    return 0;
}



void initialize_stream(metadata *meta){
	int i,err;	
	FILE *prev;
    FILE *newfile;	
	picFrame_metadata frame;
	metadata_header *header;

	prev = meta->meta_file;
	newfile = meta->tmp_file;
	header = meta->header;


	header->metadata_offset = sizeof(*header) +
		                  header->no_of_streams*sizeof(stream_metadata);
	
	//write the header into the new file
	fwrite(meta->header,1,sizeof(metadata_header),newfile);
	for(i=0;i<header->no_of_streams; i++)
		fwrite(meta->stream[i],1,sizeof(stream_metadata), newfile);
	fseek(newfile,header->metadata_offset,SEEK_SET);	
	fseek(prev,header->metadata_offset-sizeof(stream_metadata), SEEK_SET);  //fix this. Have an old metadata saved
	//read data from the old file and write it to the new one and fill -1 for the new stream
	while(!feof(prev)){
		err = read_frame(meta, &frame);			
		if(err == 0) break;
		frame.offsets[header->no_of_streams-1] = -1;
		fwrite(&(frame.frame_number),1,sizeof(frame.frame_number),newfile);
		fwrite(&(frame.frametype),1,sizeof(frame.frametype),newfile);
		fwrite(frame.offsets,1,sizeof(FileOffset)*header->no_of_streams,newfile);
	}
	return ;
}

int  read_frame(metadata *meta, picFrame_metadata *frame){

	FileOffset pos;
	int no_of_streams;
	int err;

	assert(meta != NULL);
	assert(meta->header != NULL);
 	//read one less-- exclude the new stream 
	no_of_streams = meta->header->no_of_streams -1;
	
      //read the frame number and type info before reading anything else 
	err = fread(&(frame->frame_number),1,
		      sizeof(frame->frame_number), meta->meta_file);
	if(feof(meta->meta_file)) return 0;
	assert(err =  sizeof(frame->frame_number));
	err = fread(&(frame->frametype),1,
		      sizeof(frame->frametype), meta->meta_file);
	assert(err ==  sizeof(frame->frametype));
	
	err = fread(frame->offsets,1,
		no_of_streams*sizeof(FileOffset),
		 meta->meta_file);
	return err;

}

void meta_cleanup(metadata *meta){

	int i, no_of_streams;
	
	assert(meta != NULL);
	assert(meta->header != NULL);
	no_of_streams = meta->header->no_of_streams;
	for(i=0;i<no_of_streams;i++)	
		free(meta->stream[i]);
	fclose(meta->meta_file);
	fclose(meta->tmp_file);

	//printf("%s\n",meta->tmp_filename);
	
	remove(meta->meta_filename);
	i= rename(meta->tmp_filename, meta->meta_filename);
//	free(meta->tmp_filename);	
//	free(meta->meta_filename);
	free(meta);
}

FileOffset get_pos( metadata *meta, picFrame_metadata * frame, int speed )
{
    int cur_stream_no; 
    FileOffset switch_stream_offset;
    stream_metadata *cur_stream;

    //////////// XXX Since we only support switch speeds of 12 change switch
    //////////// speed greater than 1 to 12
    if ( speed > 1 )
        speed = 12;
    if ( speed < 1 )
        speed = -12;
    ////////////

	assert((cur_stream = get_stream_metadata(meta, speed, &cur_stream_no)) != NULL);
    switch_stream_offset = frame->offsets[cur_stream_no];

#ifdef PRN_DEBUG
    printf("File position is %lld\n", frame->offsets[cur_stream_no]);
    fflush(stdout);
#endif // PRN_DEBUG

    // 23 = number of bytes to back up to get to sequence header. 
    switch_stream_offset -= 23;
    // back up to beginning of the transport stream packet. 
    switch_stream_offset = switch_stream_offset - 
                                  ( switch_stream_offset % 188 );

    
    return switch_stream_offset; 
}

//FileOffset get_switch_offset(metadata *meta,int cur_speed, FileOffset cur_offset,
picFrame_metadata * get_switch_frame(metadata *meta,int cur_speed, FileOffset
cur_offset, int switch_speed, int direction, int curr_direction,
int frame_type){

	long pic_frame_no;
	int size_of_frame, no_of_streams;
	stream_metadata *cur_stream,*switch_stream;
	FileOffset switch_stream_offset;
	long offset;
	picFrame_metadata frame, *ret_frame;
	int cur_stream_no, switch_stream_no;
    	
#ifdef PRN_DEBUG
    printf("\nswitch_stream arguments: meta %x, cur_speed %d, cur_offset %lld, switch_speed %d, direction %d", 
                                       meta, cur_speed, cur_offset, switch_speed, direction);
#endif //PRN_DEBUG

    //////////// XXX Since we only support switch speeds of 12 change switch
    //////////// speed greater than 1 to 12
    if ( switch_speed > 1 )
        switch_speed = 12;
    if ( cur_speed > 1 )
        cur_speed = 12;    
    if ( switch_speed < 1 )
        switch_speed = -12;
    if ( cur_speed < 1 )
        cur_speed = -12;
    ////////////

	//assert(meta != NULL);
    if ( meta == NULL ) {
        fprintf(stderr, "metadata structure is null. Cannot get switch frame!\n");
        return NULL;
    }
        
	//assert(cur_offset < LONG_MAX);
    if ( cur_offset > LONG_MAX ) {
        fprintf( stderr, "Invalid value for curr_offset. Cannot get switch frame\n");
        return NULL;
    }
    
	//assert((cur_stream = get_stream_metadata(meta, cur_speed, &cur_stream_no)) != NULL);	
    cur_stream = get_stream_metadata( meta, cur_speed, &cur_stream_no );
    if ( cur_stream == NULL )  {
        fprintf( stderr, "Cannot get stream metadata for speed = %d. \n", cur_speed);
        return NULL;
    }
    
	// assert((switch_stream = get_stream_metadata(meta, switch_speed, &switch_stream_no)) != NULL);
    switch_stream = get_stream_metadata( meta, switch_speed, &switch_stream_no );
    if ( switch_stream == NULL )  {
        fprintf( stderr, "Cannot get stream metadata for speed = %d. \n", switch_speed);
        return NULL;
    }

	pic_frame_no = cur_offset/cur_stream->avg_frame_length;

	
	no_of_streams = meta->header->no_of_streams;
	size_of_frame = sizeof(frame.frame_number) + sizeof(frame.frametype) +
			 no_of_streams*sizeof(FileOffset);	


	offset = meta->header->metadata_offset + (pic_frame_no-1)*size_of_frame;
    // XXX Hack for finding the correct frame number when offset is in the
    // reverse direction. Currently the frame number returned for DIR_REV is
    // pic_frame_no when it should be pic_frame_no frames from the last since
    // the offset values are in decreasing order of value for the reverse

⌨️ 快捷键说明

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