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

📄 vcd.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    $Id: vcd.c,v 1.4 2006/12/08 16:26:10 mshopf 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 <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h>#include <cdio/cdio.h>#include <cdio/iso9660.h>/* public headers */#include <libvcd/types.h>#include <libvcd/info.h>#include <libvcd/files.h>#include <libvcd/sector.h>#include <libvcd/logging.h>/* Private headers */#include "assert.h"#include "dict.h"#include "directory.h"#include "obj.h"#include "pbc.h"#include "salloc.h"#include "util.h"#include "vcd.h"static const char _rcsid[] = "$Id: vcd.c,v 1.4 2006/12/08 16:26:10 mshopf Exp $";static const char zero[CDIO_CD_FRAMESIZE_RAW] = { 0, };#define DEFAULT_ISO_PREPARER_ID       "GNU VCDImager " VERSION " " HOST_ARCH/* exported private functions */mpeg_sequence_t *_vcd_obj_get_sequence_by_id (VcdObj *obj, const char sequence_id[]){  CdioListNode *node;  vcd_assert (sequence_id != NULL);  vcd_assert (obj != NULL);  _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list)    {      mpeg_sequence_t *_sequence = _cdio_list_node_data (node);      if (_sequence->id && !strcmp (sequence_id, _sequence->id))        return _sequence;    }  return NULL;}mpeg_sequence_t *_vcd_obj_get_sequence_by_entry_id (VcdObj *obj, const char entry_id[]){  CdioListNode *node;  vcd_assert (entry_id != NULL);  vcd_assert (obj != NULL);  _CDIO_LIST_FOREACH (node, obj->mpeg_sequence_list)    {      mpeg_sequence_t *_sequence = _cdio_list_node_data (node);      CdioListNode *node2;      /* default entry point */      if (_sequence->default_entry_id           && !strcmp (entry_id, _sequence->default_entry_id))        return _sequence;      /* additional entry points */      _CDIO_LIST_FOREACH (node2, _sequence->entry_list)	{	  entry_t *_entry = _cdio_list_node_data (node2);	  if (_entry->id               && !strcmp (entry_id, _entry->id))	    return _sequence;	}    }  /* not found */  return NULL;}mpeg_segment_t *_vcd_obj_get_segment_by_id (VcdObj *obj, const char segment_id[]){  CdioListNode *node;  vcd_assert (segment_id != NULL);  vcd_assert (obj != NULL);  _CDIO_LIST_FOREACH (node, obj->mpeg_segment_list)    {      mpeg_segment_t *_segment = _cdio_list_node_data (node);      if (_segment->id && !strcmp (segment_id, _segment->id))        return _segment;    }  return NULL;}bool_vcd_obj_has_cap_p (const VcdObj *obj, enum vcd_capability_t capability){  switch (capability)    {    case _CAP_VALID:      switch (obj->type)        {        case VCD_TYPE_VCD:        case VCD_TYPE_VCD11:        case VCD_TYPE_VCD2:        case VCD_TYPE_SVCD:        case VCD_TYPE_HQVCD:          return true;          break;        case VCD_TYPE_INVALID:          return false;          break;        }      break;    case _CAP_MPEG2:      switch (obj->type)        {        case VCD_TYPE_VCD:        case VCD_TYPE_VCD11:        case VCD_TYPE_VCD2:        case VCD_TYPE_INVALID:          return false;          break;        case VCD_TYPE_SVCD:        case VCD_TYPE_HQVCD:          return true;          break;        }      break;    case _CAP_PBC:      switch (obj->type)        {        case VCD_TYPE_VCD:        case VCD_TYPE_VCD11:        case VCD_TYPE_INVALID:          return false;          break;        case VCD_TYPE_VCD2:        case VCD_TYPE_SVCD:        case VCD_TYPE_HQVCD:          return true;          break;        }      break;    case _CAP_PBC_X:      switch (obj->type)        {        case VCD_TYPE_VCD:        case VCD_TYPE_VCD11:        case VCD_TYPE_INVALID:        case VCD_TYPE_SVCD:        case VCD_TYPE_HQVCD:          return false;          break;        case VCD_TYPE_VCD2:          return true;          break;        }      break;    case _CAP_4C_SVCD:      switch (obj->type)        {        case VCD_TYPE_VCD:        case VCD_TYPE_VCD11:        case VCD_TYPE_INVALID:        case VCD_TYPE_VCD2:          return false;          break;        case VCD_TYPE_SVCD:        case VCD_TYPE_HQVCD:          return true;          break;        }      break;    case _CAP_PAL_BITS:      return _vcd_obj_has_cap_p (obj, _CAP_PBC); /* for now */      break;    case _CAP_MPEG1:      return !_vcd_obj_has_cap_p (obj, _CAP_MPEG2); /* for now */      break;    case _CAP_TRACK_MARGINS:      return !_vcd_obj_has_cap_p (obj, _CAP_MPEG2); /* for now */      break;    }  vcd_assert_not_reached ();  return false;}/* * public methods */ VcdObj *vcd_obj_new (vcd_type_t vcd_type){  VcdObj *new_obj = NULL;  static bool _first = true;    if (_first)    {#if defined(_DEVELOPMENT_)            vcd_warn ("initializing libvcd %s [%s]", VERSION, HOST_ARCH);      vcd_warn (" ");      vcd_warn (" this is the UNSTABLE development branch!");      vcd_warn (" use only if you know what you are doing");      vcd_warn (" see http://www.hvrlab.org/~hvr/vcdimager/ for more information");      vcd_warn (" ");#else      vcd_debug ("initializing libvcd %s [%s]", VERSION, HOST_ARCH);#endif      _first = false;    }  new_obj = _vcd_malloc (sizeof (VcdObj));  new_obj->type = vcd_type;  if (!_vcd_obj_has_cap_p (new_obj, _CAP_VALID))    {      vcd_error ("VCD type not supported");      free (new_obj);      return NULL;    }  if (vcd_type == VCD_TYPE_VCD)    vcd_warn ("VCD 1.0 support is experimental -- user feedback needed!");  new_obj->iso_volume_label = strdup ("");  new_obj->iso_publisher_id = strdup ("");  new_obj->iso_application_id = strdup ("");  new_obj->iso_preparer_id = _vcd_strdup_upper (DEFAULT_ISO_PREPARER_ID);  new_obj->info_album_id = strdup ("");  new_obj->info_volume_count = 1;  new_obj->info_volume_number = 1;  new_obj->custom_file_list = _cdio_list_new ();  new_obj->custom_dir_list = _cdio_list_new ();  new_obj->mpeg_sequence_list = _cdio_list_new ();  new_obj->mpeg_segment_list = _cdio_list_new ();  new_obj->pbc_list = _cdio_list_new ();  /* gap's defined by IEC-10149 / ECMA-130 */  /* pre-gap's for tracks but the first one */  new_obj->track_pregap = CDIO_PREGAP_SECTORS;   /* post-gap after last track */  new_obj->leadout_pregap = CDIO_POSTGAP_SECTORS;   if (_vcd_obj_has_cap_p (new_obj, _CAP_TRACK_MARGINS))    {      new_obj->track_front_margin = 30;      new_obj->track_rear_margin = 45;    }  else    {      new_obj->track_front_margin = 0;      new_obj->track_rear_margin = 0;    }  return new_obj;}int vcd_obj_remove_item (VcdObj *obj, const char id[]){  vcd_warn ("vcd_obj_remove_item('%s') not implemented yet!", id);  return -1;}static void_vcd_obj_remove_mpeg_track (VcdObj *obj, int track_id){  int length;  mpeg_sequence_t *track = NULL;  CdioListNode *node = NULL;  vcd_assert (track_id >= 0);  node = _vcd_list_at (obj->mpeg_sequence_list, track_id);    vcd_assert (node != NULL);  track = (mpeg_sequence_t *) _cdio_list_node_data (node);  vcd_mpeg_source_destroy (track->source, true);  length = track->info->packets;  length += obj->track_pregap + obj->track_front_margin + 0 + obj->track_rear_margin;  /* fixup offsets */  {    CdioListNode *node2 = node;    while ((node2 = _cdio_list_node_next (node2)) != NULL)      ((mpeg_sequence_t *) _cdio_list_node_data (node))->relative_start_extent -= length;  }  obj->relative_end_extent -= length;  /* shift up */  _cdio_list_node_free (node, true);}intvcd_obj_append_segment_play_item (VcdObj *obj, VcdMpegSource *mpeg_source,                                  const char item_id[]){  mpeg_segment_t *segment = NULL;  vcd_assert (obj != NULL);  vcd_assert (mpeg_source != NULL);  if (!_vcd_obj_has_cap_p (obj, _CAP_PBC))    {      vcd_error ("segment play items not supported for this vcd type");      return -1;    }  if (!item_id)    {      vcd_error ("no id given for segment play item");      return -1;    }  if (_vcd_pbc_lookup (obj, item_id))    {      vcd_error ("item id (%s) exists already", item_id);      return -1;    }  vcd_info ("scanning mpeg segment item #%d for scanpoints...",             _cdio_list_length (obj->mpeg_segment_list));  vcd_mpeg_source_scan (mpeg_source, !obj->relaxed_aps,                        obj->update_scan_offsets, NULL, NULL);  if (vcd_mpeg_source_get_info (mpeg_source)->packets == 0)    {      vcd_error ("mpeg is empty?");      return -1;    }  /* create list node */  segment = _vcd_malloc (sizeof (mpeg_sequence_t));  segment->source = mpeg_source;  segment->id = strdup (item_id);   segment->info = vcd_mpeg_source_get_info (mpeg_source);  segment->segment_count = _vcd_len2blocks (segment->info->packets, 150);  segment->pause_list = _cdio_list_new ();  vcd_debug ("SPI length is %d sector(s), allocated %d segment(s)",             segment->info->packets,             segment->segment_count);  _cdio_list_append (obj->mpeg_segment_list, segment);  return 0;}intvcd_obj_append_sequence_play_item (VcdObj *obj, VcdMpegSource *mpeg_source,                                   const char item_id[],                                   const char default_entry_id[]){  unsigned length;  mpeg_sequence_t *sequence = NULL;  int track_no = _cdio_list_length (obj->mpeg_sequence_list);  vcd_assert (obj != NULL);  vcd_assert (mpeg_source != NULL);  if (item_id && _vcd_pbc_lookup (obj, item_id))    {      vcd_error ("item id (%s) exist already", item_id);      return -1;    }  if (default_entry_id && _vcd_pbc_lookup (obj, default_entry_id))    {      vcd_error ("default entry id (%s) exist already", default_entry_id);      return -1;    }  if (default_entry_id && item_id && !strcmp (item_id, default_entry_id))    {      vcd_error ("default entry id == item id (%s)", item_id);      return -1;    }  vcd_info ("scanning mpeg sequence item #%d for scanpoints...", track_no);  vcd_mpeg_source_scan (mpeg_source, !obj->relaxed_aps,                        obj->update_scan_offsets, NULL, NULL);  sequence = _vcd_malloc (sizeof (mpeg_sequence_t));  sequence->source = mpeg_source;  if (item_id)    sequence->id = strdup (item_id);  if (default_entry_id)    sequence->default_entry_id = strdup (default_entry_id);    sequence->info = vcd_mpeg_source_get_info (mpeg_source);  length = sequence->info->packets;  sequence->entry_list = _cdio_list_new ();  sequence->pause_list = _cdio_list_new ();  obj->relative_end_extent += obj->track_pregap;  sequence->relative_start_extent = obj->relative_end_extent;  obj->relative_end_extent += obj->track_front_margin + length + obj->track_rear_margin;  /* sanity checks */  if (length < 75)    vcd_warn ("mpeg stream shorter than 75 sectors");  if (!_vcd_obj_has_cap_p (obj, _CAP_PAL_BITS)      && vcd_mpeg_get_norm (&sequence->info->shdr[0]) != MPEG_NORM_FILM

⌨️ 快捷键说明

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