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

📄 vcd.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 5 页
字号:
          vcd_error ("directory section to big for a SVCD");        break;      default:        vcd_assert_not_reached ();      }        /* un-alloc small area */        _vcd_salloc_free (obj->iso_bitmap, 18, dirs_size + 2);        /* alloc it again! */    _dict_insert (obj, "dir", 18, dirs_size, SM_EOR|SM_EOF);    _dict_insert (obj, "ptl", 18 + dirs_size, 1, SM_EOR|SM_EOF);    _dict_insert (obj, "ptm", 18 + dirs_size + 1, 1, SM_EOR|SM_EOF);  }}static void_finalize_vcd_iso_track (VcdObj *obj){  _vcd_pbc_finalize (obj);  _finalize_vcd_iso_track_allocation (obj);  _finalize_vcd_iso_track_filesystem (obj);}static int_callback_wrapper (VcdObj *obj, int force){  const int cb_frequency = 75;  if (obj->last_cb_call + cb_frequency > obj->sectors_written && !force)    return 0;  obj->last_cb_call = obj->sectors_written;  if (obj->progress_callback) {    progress_info_t _pi;    _pi.sectors_written = obj->sectors_written;    _pi.total_sectors = obj->relative_end_extent + obj->iso_size;     _pi.in_track = obj->in_track;    _pi.total_tracks = _cdio_list_length (obj->mpeg_sequence_list) + 1;    return obj->progress_callback (&_pi, obj->callback_user_data);  }  else    return 0;}static int_write_m2_image_sector (VcdObj *obj, const void *data, uint32_t extent,                        uint8_t fnum, uint8_t cnum, uint8_t sm, uint8_t ci) {  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };  vcd_assert (extent == obj->sectors_written);  _vcd_make_mode2(buf, data, extent, fnum, cnum, sm, ci);  vcd_image_sink_write (obj->image_sink, buf, extent);    obj->sectors_written++;  return _callback_wrapper (obj, false);}static int_write_m2_raw_image_sector (VcdObj *obj, const void *data, uint32_t extent){  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };  vcd_assert (extent == obj->sectors_written);  _vcd_make_raw_mode2(buf, data, extent);  vcd_image_sink_write (obj->image_sink, buf, extent);  obj->sectors_written++;  return _callback_wrapper (obj, false);}static void_write_source_mode2_raw (VcdObj *obj, VcdDataSource *source, uint32_t extent){  int n;  uint32_t sectors;  sectors = vcd_data_source_stat (source) / M2RAW_SECTOR_SIZE;  vcd_data_source_seek (source, 0);   for (n = 0;n < sectors;n++) {    char buf[M2RAW_SECTOR_SIZE] = { 0, };    vcd_data_source_read (source, buf, M2RAW_SECTOR_SIZE, 1);    if (_write_m2_raw_image_sector (obj, buf, extent+n))      break;  }  vcd_data_source_close (source);}static void_write_source_mode2_form1 (VcdObj *obj, VcdDataSource *source, uint32_t extent){  int n;  uint32_t sectors, size, last_block_size;  size = vcd_data_source_stat (source);  sectors = _vcd_len2blocks (size, CDIO_CD_FRAMESIZE);  last_block_size = size % CDIO_CD_FRAMESIZE;  if (!last_block_size)    last_block_size = CDIO_CD_FRAMESIZE;  vcd_data_source_seek (source, 0);   for (n = 0;n < sectors;n++) {    char buf[CDIO_CD_FRAMESIZE] = { 0, };    vcd_data_source_read (source, buf,                           ((n + 1 == sectors)                            ? last_block_size                           : CDIO_CD_FRAMESIZE), 1);    if (_write_m2_image_sector (obj, buf, extent+n, 1, 0,                                 ((n+1 < sectors)                                  ? SM_DATA                                  : SM_DATA |SM_EOF),                                0))      break;  }  vcd_data_source_close (source);}static int_write_sequence (VcdObj *obj, int track_idx){  mpeg_sequence_t *track =     _cdio_list_node_data (_vcd_list_at (obj->mpeg_sequence_list, track_idx));  CdioListNode *pause_node;  int n, lastsect = obj->sectors_written;  char buf[2324];  struct {    int audio;    int video;    int zero;    int ogt;    int unknown;  } mpeg_packets = {0, };  {    char *norm_str = NULL;    const struct vcd_mpeg_stream_vid_info *_info = &track->info->shdr[0];    switch (vcd_mpeg_get_norm (_info)) {    case MPEG_NORM_PAL:      norm_str = strdup ("PAL SIF (352x288/25fps)");      break;    case MPEG_NORM_NTSC:      norm_str = strdup ("NTSC SIF (352x240/29.97fps)");      break;    case MPEG_NORM_FILM:      norm_str = strdup ("FILM SIF (352x240/24fps)");      break;    case MPEG_NORM_PAL_S:      norm_str = strdup ("PAL 2/3 D1 (480x576/25fps)");      break;    case MPEG_NORM_NTSC_S:      norm_str = strdup ("NTSC 2/3 D1 (480x480/29.97fps)");      break;	    case MPEG_NORM_OTHER:      {        char buf[1024] = { 0, };        switch (_info->vsize)          {          case 480:          case 240:            snprintf (buf, sizeof (buf), "NTSC UNKNOWN (%dx%d/%2.2ffps)",                      _info->hsize, _info->vsize, _info->frate);            break;          case 288:          case 576:            snprintf (buf, sizeof (buf), "PAL UNKNOWN (%dx%d/%2.2ffps)",                      _info->hsize, _info->vsize, _info->frate);            break;          default:            snprintf (buf, sizeof (buf), "UNKNOWN (%dx%d/%2.2ffps)",                      _info->hsize, _info->vsize, _info->frate);            break;          }        norm_str = strdup (buf);      }      break;    }    {      char buf[1024] = { 0, }, buf2[1024] = { 0, };      int i;      for (i = 0; i < 3; i++)        if (track->info->ahdr[i].seen)          {            const char *_mode_str[] = {              0,              "stereo",              "jstereo",              "dual",              "single",              0            };            snprintf (buf, sizeof (buf), "audio[%d]: l%d/%2.1fkHz/%dkbps/%s ",                       i,                      track->info->ahdr[i].layer,                      track->info->ahdr[i].sampfreq / 1000.0,                      track->info->ahdr[i].bitrate / 1024,                      _mode_str[track->info->ahdr[i].mode]);                                strncat (buf2, buf, sizeof(buf2) - strlen(buf2) - 1);          }            vcd_info ("writing track %d, %s, %s, %s...", track_idx + 2,                (track->info->version == MPEG_VERS_MPEG1 ? "MPEG1" : "MPEG2"),                norm_str, buf2);    }    free (norm_str);  }  for (n = 0; n < obj->track_pregap; n++)    _write_m2_image_sector (obj, zero, lastsect++, 0, 0, SM_FORM2, 0);  for (n = 0; n < obj->track_front_margin;n++)    _write_m2_image_sector (obj, zero, lastsect++, track_idx + 1,                            0, SM_FORM2|SM_REALT, 0);  pause_node = _cdio_list_begin (track->pause_list);  for (n = 0; n < track->info->packets; n++) {    int ci = 0, sm = 0, cnum = 0, fnum = 0;    struct vcd_mpeg_packet_info pkt_flags;    bool set_trigger = false;    vcd_mpeg_source_get_packet (track->source, n, buf, &pkt_flags,                                 obj->update_scan_offsets);    while (pause_node)      {        pause_t *_pause = _cdio_list_node_data (pause_node);        if (!pkt_flags.has_pts)          break; /* no pts */        if (pkt_flags.pts < _pause->time)          break; /* our time has not come yet */        /* seems it's time to trigger! */        set_trigger = true;        vcd_debug ("setting auto pause trigger for time %f (pts %f) @%d",                    _pause->time, pkt_flags.pts, n);        pause_node = _cdio_list_node_next (pause_node);      }    switch (vcd_mpeg_packet_get_type (&pkt_flags))       {    case PKT_TYPE_VIDEO:      mpeg_packets.video++;      sm = SM_FORM2|SM_REALT|SM_VIDEO;      ci = CI_VIDEO;      cnum = CN_VIDEO;      break;    case PKT_TYPE_OGT:      mpeg_packets.ogt++;      sm = SM_FORM2|SM_REALT|SM_VIDEO;      ci = CI_OGT;      cnum = CN_OGT;      break;        case PKT_TYPE_AUDIO:      mpeg_packets.audio++;      sm = SM_FORM2|SM_REALT|SM_AUDIO;      ci = CI_AUDIO;      cnum = CN_AUDIO;      if (pkt_flags.audio[1] || pkt_flags.audio[2])        {          ci = CI_AUDIO2;          cnum = CN_AUDIO2;        }      break;    case PKT_TYPE_ZERO:      mpeg_packets.zero++;      mpeg_packets.unknown--;    case PKT_TYPE_EMPTY:      mpeg_packets.unknown++;      sm = SM_FORM2|SM_REALT;      ci = CI_EMPTY;      cnum = CN_EMPTY;      break;    case PKT_TYPE_INVALID:      vcd_error ("invalid mpeg packet found at packet# %d"                 " -- please fix this mpeg file!", n);      vcd_mpeg_source_close (track->source);      return 1;      break;    default:      vcd_assert_not_reached ();    }    if (n == track->info->packets - 1)      {        sm |= SM_EOR;        if (!obj->track_rear_margin) /* if no rear margin... */          sm |= SM_EOF;      }    if (set_trigger)      sm |= SM_TRIG;    fnum = track_idx + 1;          if (_vcd_obj_has_cap_p (obj, _CAP_4C_SVCD)        && !obj->svcd_vcd3_mpegav) /* IEC62107 SVCDs have a                                       simplified subheader */      {        fnum = 1;        ci = CI_MPEG2;      }    if (_write_m2_image_sector (obj, buf, lastsect++, fnum, cnum, sm, ci))      break;  }  vcd_mpeg_source_close (track->source);  for (n = 0; n < obj->track_rear_margin; n++)    {      const uint8_t ci = 0, cnum = 0;      uint8_t fnum = track_idx + 1;      uint8_t sm = SM_FORM2 | SM_REALT;      if (n + 1 == obj->track_rear_margin)        sm |= SM_EOF;      _write_m2_image_sector (obj, zero, lastsect++, fnum, cnum, sm, ci);    }  vcd_debug ("MPEG packet statistics: %d video, %d audio, %d zero, %d ogt, %d unknown",             mpeg_packets.video, mpeg_packets.audio, mpeg_packets.zero, mpeg_packets.ogt,             mpeg_packets.unknown);  return 0;}static int_write_segment (VcdObj *obj, mpeg_segment_t *_segment){  CdioListNode *pause_node;  unsigned packet_no;  int n = obj->sectors_written;  vcd_assert (_segment->start_extent == n);  pause_node = _cdio_list_begin (_segment->pause_list);  for (packet_no = 0;       packet_no < (_segment->segment_count * VCDINFO_SEGMENT_SECTOR_SIZE);       packet_no++)    {      uint8_t buf[M2F2_SECTOR_SIZE] = { 0, };      uint8_t fn, cn, sm, ci;      if (packet_no < _segment->info->packets)        {          struct vcd_mpeg_packet_info pkt_flags;          bool set_trigger = false;          bool _need_eor = false;          vcd_mpeg_source_get_packet (_segment->source, packet_no,                                      buf, &pkt_flags, obj->update_scan_offsets);          fn = 1;          cn = CN_EMPTY;          sm = SM_FORM2 | SM_REALT;          ci = CI_EMPTY;            while (pause_node)            {              pause_t *_pause = _cdio_list_node_data (pause_node);              if (!pkt_flags.has_pts)                break; /* no pts */              if (pkt_flags.pts < _pause->time)                break; /* our time has not come yet */              /* seems it's time to trigger! */              set_trigger = true;              vcd_debug ("setting auto pause trigger for time %f (pts %f) @%d",                          _pause->time, pkt_flags.pts, n);              pause_node = _cdio_list_node_next (pause_node);            }                      switch (vcd_mpeg_packet_get_type (&pkt_flags))             {            case PKT_TYPE_VIDEO:              sm = SM_FORM2 | SM_REALT | SM_VIDEO;              ci = CI_VIDEO;              cn = CN_VIDEO;              if (pkt_flags.video[1])                ci = CI_STILL, cn = CN_STILL;              else if (pkt_flags.video[2])                ci = CI_STILL2, cn = CN_STILL2;              if (pkt_flags.video[1] || pkt_flags.video[2])                { /* search for endcode -- hack */                  int idx;                                  for (idx = 0; idx <= 2320; idx++)                    if (buf[idx] == 0x00                        && buf[idx + 1] == 0x00                        && buf[idx + 2] == 0x01                        && buf[idx + 3] == 0xb7)                      {                        _need_eor = true;                        break;                      }                }              break;            case PKT_TYPE_AUDIO:              sm = SM_FORM2 | SM_REALT | SM_AUDIO;                                ci = CI_AUDIO;              cn = CN_AUDIO;              break;            case PKT_TYPE_EMPTY:              ci = CI_EMPTY;              cn = CN_EMPTY;              break;            default:              /* fixme -- check.... */              break;            }          if (_vcd_obj_has_cap_p (obj, _CAP_4C_SVCD))            {              cn = 1;              sm = SM_FORM2 | SM_REALT | SM_VIDEO;              ci = CI_MPEG2;            }          if (packet_no + 1 == _segment->info->packets)            sm |= SM_EOF;          if (set_trigger)            sm |= SM_TRIG;          if (_need_eor)            {

⌨️ 快捷键说明

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