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

📄 dvd_udf.c

📁 有关mpeg2的deocde代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      return 1;    }    do {        if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {            TagID = 0;        } else {            UDFDescriptor( LogBlock, &TagID );        }        if( TagID == 261 ) {            UDFFileEntry( LogBlock, FileType, partition, File );           tmpmap.file = *File;           tmpmap.filetype = *FileType;           SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap);            return 1;        };    } while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 )             / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) );    return 0;}/** * Dir: Location of directory to scan * FileName: Name of file to look for * FileICB: Location of ICB of the found file * return 1 on success, 0 on error; */static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,                       struct Partition *partition, struct AD *FileICB,		       int cache_file_info) {    char filename[ MAX_UDF_FILE_NAME_LEN ];    uint8_t directory[ 2 * DVD_VIDEO_LB_LEN ];    uint32_t lbnum;    uint16_t TagID;    uint8_t filechar;    unsigned int p;    uint8_t *cached_dir = NULL;    uint32_t dir_lba;    struct AD tmpICB;    int found = 0;    int in_cache = 0;    /* Scan dir for ICB of file */    lbnum = partition->Start + Dir.Location;        if(DVDUDFCacheLevel(device, -1) > 0) {      /* caching */            if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) {	dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN;	if((cached_dir = malloc(dir_lba * DVD_VIDEO_LB_LEN)) == NULL) {	  return 0;	}	if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) {	  free(cached_dir);	  cached_dir = NULL;	}	/*	if(cached_dir) {	  fprintf(stderr, "malloc dir: %d\n",		  dir_lba * DVD_VIDEO_LB_LEN);	}	*/	SetUDFCache(device, LBUDFCache, lbnum, &cached_dir);      } else {	in_cache = 1;      }            if(cached_dir == NULL) {	return 0;      }            p = 0;            while( p < Dir.Length ) {        UDFDescriptor( &cached_dir[ p ], &TagID );        if( TagID == 257 ) {	  p += UDFFileIdentifier( &cached_dir[ p ], &filechar,				  filename, &tmpICB );	  if(cache_file_info && !in_cache) {	    uint8_t tmpFiletype;	    struct AD tmpFile;	    	    if( !strcasecmp( FileName, filename ) ) {	      *FileICB = tmpICB;	      found = 1;	      	    }	    UDFMapICB(device, tmpICB, &tmpFiletype,		      partition, &tmpFile);	  } else {	    if( !strcasecmp( FileName, filename ) ) {	      *FileICB = tmpICB;	      return 1;	    }	  }        } else {	  if(cache_file_info && (!in_cache) && found) {	    return 1;	  }	  return 0;        }      }      if(cache_file_info && (!in_cache) && found) {	return 1;      }      return 0;    }    if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {        return 0;    }    p = 0;    while( p < Dir.Length ) {        if( p > DVD_VIDEO_LB_LEN ) {            ++lbnum;            p -= DVD_VIDEO_LB_LEN;            Dir.Length -= DVD_VIDEO_LB_LEN;            if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {                return 0;            }        }        UDFDescriptor( &directory[ p ], &TagID );        if( TagID == 257 ) {            p += UDFFileIdentifier( &directory[ p ], &filechar,                                    filename, FileICB );            if( !strcasecmp( FileName, filename ) ) {                return 1;            }        } else {            return 0;        }    }    return 0;}static int UDFGetAVDP( dvd_reader_t *device,		       struct avdp_t *avdp){  uint8_t Anchor[ DVD_VIDEO_LB_LEN ];  uint32_t lbnum, MVDS_location, MVDS_length;  uint16_t TagID;  uint32_t lastsector;  int terminate;  struct avdp_t;     if(GetUDFCache(device, AVDPCache, 0, avdp)) {    return 1;  }  /* Find Anchor */  lastsector = 0;  lbnum = 256;   /* Try #1, prime anchor */  terminate = 0;    for(;;) {    if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {      UDFDescriptor( Anchor, &TagID );    } else {      TagID = 0;    }    if (TagID != 2) {      /* Not an anchor */      if( terminate ) return 0; /* Final try failed */            if( lastsector ) {		/* We already found the last sector.  Try #3, alternative	 * backup anchor.  If that fails, don't try again.	 */	lbnum = lastsector;	terminate = 1;      } else {	/* TODO: Find last sector of the disc (this is optional). */	if( lastsector ) {	  /* Try #2, backup anchor */	  lbnum = lastsector - 256;	} else {	  /* Unable to find last sector */	  return 0;	}      }    } else {      /* It's an anchor! We can leave */      break;    }  }  /* Main volume descriptor */  UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );  avdp->mvds.location = MVDS_location;  avdp->mvds.length = MVDS_length;    /* Backup volume descriptor */  UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );  avdp->rvds.location = MVDS_location;  avdp->rvds.length = MVDS_length;    SetUDFCache(device, AVDPCache, 0, avdp);    return 1;}/** * Looks for partition on the disc.  Returns 1 if partition found, 0 on error. *   partnum: Number of the partition, starting at 0. *   part: structure to fill with the partition information */static int UDFFindPartition( dvd_reader_t *device, int partnum,			     struct Partition *part ) {    uint8_t LogBlock[ DVD_VIDEO_LB_LEN ];    uint32_t lbnum, MVDS_location, MVDS_length;    uint16_t TagID;    int i, volvalid;    struct avdp_t avdp;        if(!UDFGetAVDP(device, &avdp)) {      return 0;    }    /* Main volume descriptor */    MVDS_location = avdp.mvds.location;    MVDS_length = avdp.mvds.length;    part->valid = 0;    volvalid = 0;    part->VolumeDesc[ 0 ] = '\0';    i = 1;    do {        /* Find Volume Descriptor */        lbnum = MVDS_location;        do {            if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {                TagID = 0;            } else {                UDFDescriptor( LogBlock, &TagID );            }            if( ( TagID == 5 ) && ( !part->valid ) ) {                /* Partition Descriptor */                UDFPartition( LogBlock, &part->Flags, &part->Number,                              part->Contents, &part->Start, &part->Length );                part->valid = ( partnum == part->Number );            } else if( ( TagID == 6 ) && ( !volvalid ) ) {                /* Logical Volume Descriptor */                if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) {                      /* TODO: sector size wrong! */                } else {                    volvalid = 1;                }            }        } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )                 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )                 && ( ( !part->valid ) || ( !volvalid ) ) );        if( ( !part->valid) || ( !volvalid ) ) {	  /* Backup volume descriptor */	  MVDS_location = avdp.mvds.location;	  MVDS_length = avdp.mvds.length;        }    } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );    /* We only care for the partition, not the volume */    return part->valid;}uint32_t UDFFindFile( dvd_reader_t *device, char *filename,		      uint32_t *filesize ){    uint8_t LogBlock[ DVD_VIDEO_LB_LEN ];    uint32_t lbnum;    uint16_t TagID;    struct Partition partition;    struct AD RootICB, File, ICB;    char tokenline[ MAX_UDF_FILE_NAME_LEN ];    char *token;    uint8_t filetype;    *filesize = 0;    tokenline[0] = '\0';    strcat( tokenline, filename );        if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&        GetUDFCache(device, RootICBCache, 0, &RootICB))) {      /* Find partition, 0 is the standard location for DVD Video.*/      if( !UDFFindPartition( device, 0, &partition ) ) return 0;      SetUDFCache(device, PartitionCache, 0, &partition);            /* Find root dir ICB */      lbnum = partition.Start;      do {        if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {            TagID = 0;        } else {            UDFDescriptor( LogBlock, &TagID );        }        /* File Set Descriptor */        if( TagID == 256 ) {  // File Set Descriptor            UDFLongAD( &LogBlock[ 400 ], &RootICB );        }    } while( ( lbnum < partition.Start + partition.Length )             && ( TagID != 8 ) && ( TagID != 256 ) );    /* Sanity checks. */    if( TagID != 256 ) return 0;    if( RootICB.Partition != 0 ) return 0;    SetUDFCache(device, RootICBCache, 0, &RootICB);    }    /* Find root dir */    if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) return 0;    if( filetype != 4 ) return 0;  /* Root dir should be dir */    {      int cache_file_info = 0;      /* Tokenize filepath */      token = strtok(tokenline, "/");            while( token != NULL ) {               if( !UDFScanDir( device, File, token, &partition, &ICB,                        cache_file_info)) {         return 0;       }        if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {         return 0;       }       if(!strcmp(token, "VIDEO_TS")) {         cache_file_info = 1;       }        token = strtok( NULL, "/" );      }    }     /* Sanity check. */    if( File.Partition != 0 ) return 0;       *filesize = File.Length;    /* Hack to not return partition.Start for empty files. */    if( !File.Location )      return 0;    else      return partition.Start + File.Location;}/** * Gets a Descriptor . * Returns 1 if descriptor found, 0 on error. * id, tagid of descriptor * bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN). */static int UDFGetDescriptor( dvd_reader_t *device, int id,			     uint8_t *descriptor, int bufsize) {  uint32_t lbnum, MVDS_location, MVDS_length;  struct avdp_t avdp;  uint16_t TagID;  uint32_t lastsector;  int i, terminate;  int desc_found = 0;  /* Find Anchor */  lastsector = 0;  lbnum = 256;   /* Try #1, prime anchor */  terminate = 0;  if(bufsize < DVD_VIDEO_LB_LEN) {    return 0;  }    if(!UDFGetAVDP(device, &avdp)) {    return 0;  }  /* Main volume descriptor */  MVDS_location = avdp.mvds.location;  MVDS_length = avdp.mvds.length;    i = 1;  do {    /* Find  Descriptor */    lbnum = MVDS_location;    do {            if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) {	TagID = 0;      } else {	UDFDescriptor( descriptor, &TagID );      }            if( (TagID == id) && ( !desc_found ) ) {	/* Descriptor */	desc_found = 1;      }    } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )	       / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )	     && ( !desc_found) );        if( !desc_found ) {      /* Backup volume descriptor */      MVDS_location = avdp.rvds.location;      MVDS_length = avdp.rvds.length;    }  } while( i-- && ( !desc_found )  );    return desc_found;}static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd){  uint8_t pvd_buf[DVD_VIDEO_LB_LEN];    if(GetUDFCache(device, PVDCache, 0, pvd)) {    return 1;  }  if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) {    return 0;  }    memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32);  memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128);  SetUDFCache(device, PVDCache, 0, pvd);    return 1;}/** * Gets the Volume Identifier string, in 8bit unicode (latin-1) * volid, place to put the string * volid_size, size of the buffer volid points to * returns the size of buffer needed for all data */int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid,			   unsigned int volid_size){  struct pvd_t pvd;  unsigned int volid_len;  /* get primary volume descriptor */  if(!UDFGetPVD(device, &pvd)) {    return 0;  }  volid_len = pvd.VolumeIdentifier[31];  if(volid_len > 31) {    /* this field is only 32 bytes something is wrong */    volid_len = 31;  }  if(volid_size > volid_len) {    volid_size = volid_len;  }  Unicodedecode(pvd.VolumeIdentifier, volid_size, volid);    return volid_len;}/** * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) * WARNING This is not a null terminated string * volsetid, place to put the data * volsetid_size, size of the buffer volsetid points to  * the buffer should be >=128 bytes to store the whole volumesetidentifier * returns the size of the available volsetid information (128) * or 0 on error */int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid,			      unsigned int volsetid_size){  struct pvd_t pvd;  /* get primary volume descriptor */  if(!UDFGetPVD(device, &pvd)) {    return 0;  }  if(volsetid_size > 128) {    volsetid_size = 128;  }    memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size);    return 128;}

⌨️ 快捷键说明

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