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

📄 files.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    $Id: files.c,v 1.4 2006/09/26 21:18:18 dgp85 Exp $    Copyright (C) 2000, 2004 Herbert Valerio Riedel <hvr@gnu.org>    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 of the License, 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 this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <string.h>#include <stdlib.h>#include <stddef.h>#include <math.h>#include <cdio/cdio.h>#include <cdio/bytesex.h>#include <cdio/util.h>/* Public headers */#include <libvcd/files.h>#include <libvcd/types.h>#include <libvcd/logging.h>/* FIXME! Make this local */#include <libvcd/files_private.h>/* Private headers */#include "vcd_assert.h"#include "mpeg_stream.h"#include "obj.h"#include "pbc.h"#include "util.h"static const char _rcsid[] = "$Id: files.c,v 1.4 2006/09/26 21:18:18 dgp85 Exp $";inline static bool_pal_p (const struct vcd_mpeg_stream_vid_info *_info){  return (_info->vsize == 288 || _info->vsize == 576);}static int_derive_vid_type (const struct vcd_mpeg_stream_info *_info, bool svcd){  if (_info->shdr[0].seen)    return _pal_p (&_info->shdr[0]) ? 0x7 : 0x3;  if (_info->shdr[2].seen)    {      if (svcd)        vcd_warn ("stream with 0xE2 still stream id not allowed for IEC62107 compliant SVCDs");      return _pal_p (&_info->shdr[2]) ? 0x6 : 0x2;    }  if (_info->shdr[1].seen)    return _pal_p (&_info->shdr[1]) ? 0x5 : 0x1;  return 0;}static int_derive_ogt_type (const struct vcd_mpeg_stream_info *_info, bool svcd){    if (!svcd)    return 0;  if ((_info->ogt[3] || _info->ogt[2])      && _info->ogt[1] && _info->ogt[0])    return 0x3;  if (_info->ogt[1] && _info->ogt[0])    return 0x2;  if (_info->ogt[0])    return 0x1;  vcd_debug ("OGT streams available: %d %d %d %d",             _info->ogt[0], _info->ogt[1],              _info->ogt[2], _info->ogt[3]);  return 0x0;}static int_derive_aud_type (const struct vcd_mpeg_stream_info *_info, bool svcd){  if (!_info->ahdr[0].seen)    return 0; /* no MPEG audio */  if (svcd)    {      if (_info->ahdr[2].seen)        return 3; /* MC */      if (_info->ahdr[1].seen)        return 2; /* 2 streams */            return 1; /* just one stream */    }  else    switch (_info->ahdr[0].mode)      {      case MPEG_SINGLE_CHANNEL:        return 1;        break;      case MPEG_STEREO:      case MPEG_JOINT_STEREO:        return 2;        break;      case MPEG_DUAL_CHANNEL:        return 3;        break;      }  return 0;}voidset_entries_vcd (VcdObj *obj, void *buf){  CdioListNode *node = NULL;  int idx = 0;  int track_idx = 0;  EntriesVcd_t entries_vcd;  vcd_assert (sizeof(EntriesVcd_t) == 2048);  vcd_assert (_cdio_list_length (obj->mpeg_track_list) <= MAX_ENTRIES);  vcd_assert (_cdio_list_length (obj->mpeg_track_list) > 0);  memset(&entries_vcd, 0, sizeof(entries_vcd)); /* paranoia / fixme */  switch (obj->type)    {    case VCD_TYPE_VCD:      strncpy(entries_vcd.ID, ENTRIES_ID_VCD, 8);      entries_vcd.version = ENTRIES_VERSION_VCD;      entries_vcd.sys_prof_tag = ENTRIES_SPTAG_VCD;      break;    case VCD_TYPE_VCD11:      strncpy(entries_vcd.ID, ENTRIES_ID_VCD, 8);      entries_vcd.version = ENTRIES_VERSION_VCD11;      entries_vcd.sys_prof_tag = ENTRIES_SPTAG_VCD11;      break;    case VCD_TYPE_VCD2:      strncpy(entries_vcd.ID, ENTRIES_ID_VCD, 8);      entries_vcd.version = ENTRIES_VERSION_VCD2;      entries_vcd.sys_prof_tag = ENTRIES_SPTAG_VCD2;      break;    case VCD_TYPE_SVCD:      if (!obj->svcd_vcd3_entrysvd)        strncpy(entries_vcd.ID, ENTRIES_ID_SVCD, 8);      else        {          vcd_warn ("setting ENTRYSVD signature for *DEPRECATED* VCD 3.0 type SVCD");          strncpy(entries_vcd.ID, ENTRIES_ID_VCD3, 8);        }      entries_vcd.version = ENTRIES_VERSION_SVCD;      entries_vcd.sys_prof_tag = ENTRIES_SPTAG_SVCD;      break;    case VCD_TYPE_HQVCD:      strncpy(entries_vcd.ID, ENTRIES_ID_SVCD, 8);      entries_vcd.version = ENTRIES_VERSION_HQVCD;      entries_vcd.sys_prof_tag = ENTRIES_SPTAG_HQVCD;      break;          default:      vcd_assert_not_reached ();      break;    }  idx = 0;  track_idx = 2;  _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list)    {      mpeg_sequence_t *track = _cdio_list_node_data (node);      uint32_t lsect = track->relative_start_extent;      CdioListNode *node2;      lsect += obj->iso_size;      entries_vcd.entry[idx].n = cdio_to_bcd8(track_idx);      cdio_lba_to_msf(cdio_lsn_to_lba(lsect),                       &(entries_vcd.entry[idx].msf));      idx++;      lsect += obj->track_front_margin;      _CDIO_LIST_FOREACH (node2, track->entry_list)        {          entry_t *_entry = _cdio_list_node_data (node2);          /* additional entries */          vcd_assert (idx < MAX_ENTRIES);          entries_vcd.entry[idx].n = cdio_to_bcd8(track_idx);          cdio_lba_to_msf(lsect + cdio_lsn_to_lba(_entry->aps.packet_no),                          &(entries_vcd.entry[idx].msf));          idx++;        }      track_idx++;    }  entries_vcd.entry_count = uint16_to_be (idx);  memcpy(buf, &entries_vcd, sizeof(entries_vcd));}static void_set_bit (uint8_t bitset[], unsigned bitnum){  unsigned _byte = bitnum / 8;  unsigned _bit  = bitnum % 8;  bitset[_byte] |= (1 << _bit);}uint32_t get_psd_size (VcdObj *obj, bool extended){  if (extended)    vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X));  if (!_vcd_pbc_available (obj))    return 0;    if (extended)    return obj->psdx_size;  return obj->psd_size;}voidset_psd_vcd (VcdObj *obj, void *buf, bool extended){  CdioListNode *node;  if (extended)    vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X));  vcd_assert (_vcd_pbc_available (obj));  _CDIO_LIST_FOREACH (node, obj->pbc_list)    {      pbc_t *_pbc = _cdio_list_node_data (node);      char *_buf = buf;      unsigned offset = (extended ? _pbc->offset_ext : _pbc->offset);            vcd_assert (offset % INFO_OFFSET_MULT == 0);      _vcd_pbc_node_write (obj, _pbc, _buf + offset, extended);    }}voidset_lot_vcd(VcdObj *obj, void *buf, bool extended){  LotVcd_t *lot_vcd = NULL;  CdioListNode *node;  if (extended)    vcd_assert (_vcd_obj_has_cap_p (obj, _CAP_PBC_X));  vcd_assert (_vcd_pbc_available (obj));  lot_vcd = _vcd_malloc (sizeof (LotVcd_t));  memset(lot_vcd, 0xff, sizeof(LotVcd_t));  lot_vcd->reserved = 0x0000;  _CDIO_LIST_FOREACH (node, obj->pbc_list)    {      pbc_t *_pbc = _cdio_list_node_data (node);      unsigned int offset = extended ? _pbc->offset_ext : _pbc->offset;            vcd_assert (offset % INFO_OFFSET_MULT == 0);      if (_pbc->rejected)        continue;      offset /= INFO_OFFSET_MULT;      lot_vcd->offset[_pbc->lid - 1] = uint16_to_be (offset);    }  memcpy(buf, lot_vcd, sizeof(LotVcd_t));  free(lot_vcd);}voidset_info_vcd(VcdObj *obj, void *buf){  InfoVcd_t info_vcd;  CdioListNode *node = NULL;  int n = 0;  vcd_assert (sizeof (InfoVcd_t) == 2048);  vcd_assert (_cdio_list_length (obj->mpeg_track_list) <= 98);    memset (&info_vcd, 0, sizeof (info_vcd));  switch (obj->type)    {    case VCD_TYPE_VCD:      strncpy (info_vcd.ID, INFO_ID_VCD, sizeof (info_vcd.ID));      info_vcd.version = INFO_VERSION_VCD;      info_vcd.sys_prof_tag = INFO_SPTAG_VCD;      break;    case VCD_TYPE_VCD11:      strncpy (info_vcd.ID, INFO_ID_VCD, sizeof (info_vcd.ID));      info_vcd.version = INFO_VERSION_VCD11;      info_vcd.sys_prof_tag = INFO_SPTAG_VCD11;      break;    case VCD_TYPE_VCD2:      strncpy (info_vcd.ID, INFO_ID_VCD, sizeof (info_vcd.ID));      info_vcd.version = INFO_VERSION_VCD2;      info_vcd.sys_prof_tag = INFO_SPTAG_VCD2;      break;    case VCD_TYPE_SVCD:      strncpy (info_vcd.ID, INFO_ID_SVCD, sizeof (info_vcd.ID));      info_vcd.version = INFO_VERSION_SVCD;      info_vcd.sys_prof_tag = INFO_SPTAG_SVCD;      break;    case VCD_TYPE_HQVCD:      strncpy (info_vcd.ID, INFO_ID_HQVCD, sizeof (info_vcd.ID));      info_vcd.version = INFO_VERSION_HQVCD;      info_vcd.sys_prof_tag = INFO_SPTAG_HQVCD;      break;          default:      vcd_assert_not_reached ();      break;    }    iso9660_strncpy_pad (info_vcd.album_desc,                        obj->info_album_id,                       sizeof(info_vcd.album_desc), ISO9660_DCHARS);   /* fixme, maybe it's VCD_ACHARS? */  info_vcd.vol_count = uint16_to_be (obj->info_volume_count);  info_vcd.vol_id = uint16_to_be (obj->info_volume_number);  if (_vcd_obj_has_cap_p (obj, _CAP_PAL_BITS))    {      /* NTSC/PAL bitset */      n = 0;      _CDIO_LIST_FOREACH (node, obj->mpeg_track_list)        {          mpeg_track_t *track = _cdio_list_node_data (node);                    const struct vcd_mpeg_stream_vid_info *_info = &track->info->shdr[0];          if (vcd_mpeg_get_norm (_info) == MPEG_NORM_PAL              || vcd_mpeg_get_norm (_info) == MPEG_NORM_PAL_S)            _set_bit(info_vcd.pal_flags, n);          else if (_pal_p (_info))            {              vcd_warn ("INFO.{VCD,SVD}: assuming PAL-type resolution for track #%d"                        " -- are we creating a X(S)VCD?", n);              _set_bit(info_vcd.pal_flags, n);            }                  n++;        }    }  if (_vcd_obj_has_cap_p (obj, _CAP_PBC))    {      info_vcd.flags.restriction = obj->info_restriction;      info_vcd.flags.use_lid2 = obj->info_use_lid2;      info_vcd.flags.use_track3 = obj->info_use_seq2;      if (_vcd_obj_has_cap_p (obj, _CAP_PBC_X)          &&_vcd_pbc_available (obj))        info_vcd.flags.pbc_x = true;            info_vcd.psd_size = uint32_to_be (get_psd_size (obj, false));      info_vcd.offset_mult = _vcd_pbc_available (obj) ? INFO_OFFSET_MULT : 0;      info_vcd.lot_entries = uint16_to_be (_vcd_pbc_max_lid (obj));            if (_cdio_list_length (obj->mpeg_segment_list))        {          unsigned segments = 0;                  if (!_vcd_pbc_available (obj))            vcd_warn ("segment items available, but no PBC items set!"                      " SPIs will be unreachable");          _CDIO_LIST_FOREACH (node, obj->mpeg_segment_list)            {              mpeg_segment_t *segment = _cdio_list_node_data (node);              unsigned idx;              InfoSpiContents contents = { 0, };              contents.video_type =                 _derive_vid_type (segment->info,                                  _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD));              contents.audio_type =                 _derive_aud_type (segment->info,                                  _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD));              contents.ogt =                _derive_ogt_type (segment->info,                                  _vcd_obj_has_cap_p (obj, _CAP_4C_SVCD));              if (!contents.video_type && !contents.audio_type)                vcd_warn ("segment item '%s' seems contains neither video nor audio",                          segment->id);              for (idx = 0; idx < segment->segment_count; idx++)                {                  vcd_assert (segments + idx < MAX_SEGMENTS);                  info_vcd.spi_contents[segments + idx] = contents;                                  if (!contents.item_cont)                    contents.item_cont = true;                }              segments += idx;            }          info_vcd.item_count = uint16_to_be (segments);           cdio_lba_to_msf (cdio_lsn_to_lba(obj->mpeg_segment_start_extent),                            &info_vcd.first_seg_addr);        }    }  memcpy(buf, &info_vcd, sizeof(info_vcd));}static voidset_tracks_svd_v30 (VcdObj *obj, void *buf){  char tracks_svd_buf[ISO_BLOCKSIZE] = { 0, };  TracksSVD_v30 *tracks_svd = (void *) tracks_svd_buf;  CdioListNode *node;  double playtime;  int n;  strncpy (tracks_svd->file_id, TRACKS_SVD_FILE_ID,            sizeof (TRACKS_SVD_FILE_ID)-1);  tracks_svd->version = TRACKS_SVD_VERSION;  tracks_svd->tracks = _cdio_list_length (obj->mpeg_track_list);  n = 0;  playtime = 0;  _CDIO_LIST_FOREACH (node, obj->mpeg_track_list)    {      mpeg_track_t *track = _cdio_list_node_data (node);      int i;      playtime += track->info->playing_time;      tracks_svd->track[n].audio_info = track->info->ahdr[0].seen ? 0x2 : 0x0; /* fixme */      tracks_svd->track[n].audio_info |= track->info->ahdr[1].seen ? 0x20 : 0x0; /* fixme */      tracks_svd->track[n].ogt_info = 0x0;      for (i = 0; i < 4; i++)        if (track->info->ogt[i])          tracks_svd->track[n].ogt_info |= 1 << (i * 2); /* fixme */      /* setting playtime */            {        double i, f;        while (playtime >= 6000.0)          playtime -= 6000.0;        f = modf(playtime, &i);                cdio_lba_to_msf (i * 75, &tracks_svd->track[n].cum_playing_time);        tracks_svd->track[n].cum_playing_time.f =           cdio_to_bcd8 (floor (f * 75.0));      }            n++;    }    

⌨️ 快捷键说明

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