예제 #1
0
파일: main.c 프로젝트: etmtvdp/tvheadend
void
gtimer_arm_abs(gtimer_t *gti, gti_callback_t *callback, void *opaque,
	       time_t when)
{
  lock_assert(&global_lock);

  if(gti->gti_callback != NULL)
    LIST_REMOVE(gti, gti_link);
    
  gti->gti_callback = callback;
  gti->gti_opaque = opaque;
  gti->gti_expire = when;

  LIST_INSERT_SORTED(&gtimers, gti, gti_link, gtimercmp);
}
예제 #2
0
파일: vda.c 프로젝트: Ralbarker/showtime
static void
vda_callback(void *aux, CFDictionaryRef frame_info, OSStatus status, 
	     uint32_t infoFlags, CVImageBufferRef buf)
{
  vda_decoder_t *vdad = aux;
  CFNumberRef ref;
  vda_frame_t *vf;
  uint8_t skip;
  if(buf == NULL)
    return;

  ref = CFDictionaryGetValue(frame_info, CFSTR("skip"));
  CFNumberGetValue(ref, kCFNumberSInt8Type, &skip);

  if(skip)
    return;

  vf = malloc(sizeof(vda_frame_t));
  ref = CFDictionaryGetValue(frame_info, CFSTR("pts"));
  CFNumberGetValue(ref, kCFNumberSInt64Type, &vf->vf_pts);

  ref = CFDictionaryGetValue(frame_info, CFSTR("duration"));
  CFNumberGetValue(ref, kCFNumberSInt32Type, &vf->vf_duration);

  ref = CFDictionaryGetValue(frame_info, CFSTR("epoch"));
  CFNumberGetValue(ref, kCFNumberSInt8Type, &vf->vf_epoch);

  ref = CFDictionaryGetValue(frame_info, CFSTR("drive_clock"));
  CFNumberGetValue(ref, kCFNumberSInt8Type, &vf->vf_drive_clock);


  vf->vf_buf = buf;
  CFRetain(buf);

  hts_mutex_lock(&vdad->vdad_mutex);

  LIST_INSERT_SORTED(&vdad->vdad_frames, vf, vf_link, vf_cmp, vda_frame_t);

  if(vdad->vdad_max_ts != PTS_UNSET) {
    if(vf->vf_pts > vdad->vdad_max_ts) {
      vdad->vdad_flush_to = vdad->vdad_max_ts;
      vdad->vdad_max_ts = vf->vf_pts;
    }
  } else {
    vdad->vdad_max_ts = vf->vf_pts;
  }
  hts_mutex_unlock(&vdad->vdad_mutex);
}
예제 #3
0
파일: main.c 프로젝트: wooyay/tvheadend
void
gtimer_arm_abs2
  (gtimer_t *gti, gti_callback_t *callback, void *opaque, struct timespec *when)
{
  lock_assert(&global_lock);

  if (gti->gti_callback != NULL)
    LIST_REMOVE(gti, gti_link);

  gti->gti_callback = callback;
  gti->gti_opaque   = opaque;
  gti->gti_expire   = *when;

  LIST_INSERT_SORTED(&gtimers, gti, gti_link, gtimercmp);

  //tvhdebug("gtimer", "%p @ %ld.%09ld", gti, when->tv_sec, when->tv_nsec);

  if (LIST_FIRST(&gtimers) == gti)
    pthread_cond_signal(&gtimer_cond); // force timer re-check
}
예제 #4
0
파일: main.c 프로젝트: Glenn-1990/tvheadend
void
GTIMER_FCN(gtimer_arm_absn)
  (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t when)
{
  lock_assert(&global_lock);

  if (gti->gti_callback != NULL)
    LIST_REMOVE(gti, gti_link);

  gti->gti_callback = callback;
  gti->gti_opaque   = opaque;
  gti->gti_expire   = when;
#if ENABLE_GTIMER_CHECK
  gti->gti_id       = id;
#endif

  LIST_INSERT_SORTED(&gtimers, gti, gti_link, gtimercmp);

  if (LIST_FIRST(&gtimers) == gti)
    pthread_cond_signal(&gtimer_cond); // force timer re-check
}
예제 #5
0
파일: main.c 프로젝트: Glenn-1990/tvheadend
void
GTIMER_FCN(mtimer_arm_abs)
  (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t when)
{
  lock_assert(&global_lock);

  if (mti->mti_callback != NULL)
    LIST_REMOVE(mti, mti_link);

  mti->mti_callback = callback;
  mti->mti_opaque   = opaque;
  mti->mti_expire   = when;
#if ENABLE_GTIMER_CHECK
  mti->mti_id       = id;
#endif

  LIST_INSERT_SORTED(&mtimers, mti, mti_link, mtimercmp);

  if (LIST_FIRST(&mtimers) == mti)
    tvh_cond_signal(&mtimer_cond, 0); // force timer re-check
}
예제 #6
0
파일: htsp.c 프로젝트: PeteGashek/showtime
static void
htsp_tagAddUpdate(htsp_connection_t *hc, htsmsg_t *m, int create)
{
  const char *id;
  htsmsg_t *members;
  htsmsg_field_t *f;
  prop_t *metadata, *before, *nodes;
  char txt[200];
  int num = 0, i;
  htsp_tag_t *ht, *n;
  const char *title;
  if((id = htsmsg_get_str(m, "tagId")) == NULL)
    return;
  
  title =  htsmsg_get_str(m, "tagName");

  hts_mutex_lock(&hc->hc_meta_mutex);

  if(create) {

    ht = calloc(1, sizeof(htsp_tag_t));
    ht->ht_id = strdup(id);
    ht->ht_title = strdup(title ?: "");

    LIST_INSERT_SORTED(&hc->hc_tags, ht, ht_link, tag_compar);
    n = LIST_NEXT(ht, ht_link);

    ht->ht_root = prop_create_root(id);

    snprintf(txt, sizeof(txt), "htsp://%s:%d/tag/%s",
	     hc->hc_hostname, hc->hc_port, id);
    
    prop_set_string(prop_create(ht->ht_root, "url"), txt);
    prop_set_string(prop_create(ht->ht_root, "type"), "directory");

    if(prop_set_parent_ex(ht->ht_root, hc->hc_tags_nodes,
			  n ? n->ht_root : NULL, NULL))
      abort();
    
  } else {
예제 #7
0
파일: muxes.c 프로젝트: 1MAK1/tvheadend
/*
 * Create/Find region entry
 */
static region_t *_muxes_region_create 
  ( const char *type, const char *id, const char *desc )
{
  region_t *reg;
  region_list_t *list = NULL;
  if      (!strcmp(type, "dvb-s")) list = &regions_DVBS;
  else if (!strcmp(type, "dvb-t")) list = &regions_DVBT;
  else if (!strcmp(type, "dvb-c")) list = &regions_DVBC;
  else if (!strcmp(type, "atsc"))  list = &regions_ATSC;
  if (!list) return NULL;

  LIST_FOREACH(reg, list, link) {
    if (!strcmp(reg->id, id)) break;
  }

  if (!reg) {
    reg = calloc(1, sizeof(region_t));
    reg->id   = strdup(id);
    reg->name = strdup(desc);
    LIST_INSERT_SORTED(list, reg, link, _reg_cmp);
  }
  
  return reg;
}
예제 #8
0
파일: ps3_vdec.c 프로젝트: ridams/showtime
static void
picture_out(vdec_decoder_t *vdd)
{
  int r, lumasize;
  uint32_t addr;
  vdec_picture_format picfmt;
  vdec_pic_t *vp;
  char metainfo[64];
  pktmeta_t *pm;

  picfmt.alpha = 0;
  picfmt.format_type = VDEC_PICFMT_YUV420P;
  picfmt.color_matrix = VDEC_COLOR_MATRIX_BT709;

  r = vdec_get_pic_item(vdd->handle, &addr);
  if(r != 0)
    return;


  vdec_picture *pi = (void *)(intptr_t)addr;

  pm = &vdd->pktmeta[pi->userdata[0]];

  vdd->pending_flush |= pm->flush;

  if(/* pi->status != 0 ||*/ pi->attr != 0 || pm->skip) {
    vdec_get_picture(vdd->handle, &picfmt, NULL);
    reset_active_pictures(vdd, "pic err", 0);
    return;
  }

  if(vdd->pending_flush) {
    reset_active_pictures(vdd, "stream flush", 0);
    vdd->pending_flush = 0;
    vdd->max_order = -1;
  }

  int64_t pts = pm->nopts ? AV_NOPTS_VALUE : 
    pi->pts[0].low + ((uint64_t)pi->pts[0].hi << 32);

  int64_t dts = pm->nodts ? AV_NOPTS_VALUE : 
    pi->dts[0].low + ((uint64_t)pi->dts[0].hi << 32);
  int64_t order;

  if(pi->codec_type == VDEC_CODEC_TYPE_MPEG2) {
    vdec_mpeg2_info *mpeg2 = (void *)(intptr_t)pi->codec_specific_addr;

    lumasize = mpeg2->width * mpeg2->height;
    vp = alloc_picture(vdd, lumasize);

    vp->fi.fi_width = mpeg2->width;
    vp->fi.fi_height = mpeg2->height;
    vp->fi.fi_duration = mpeg2->frame_rate <= 8 ? 
      mpeg_durations[mpeg2->frame_rate] : 40000;

    if(pm->disable_deinterlacer) {
      vp->fi.fi_interlaced = 0;
    } else {
      vp->fi.fi_interlaced = !mpeg2->progressive_frame;
      vp->fi.fi_tff = mpeg2->top_field_first;
    }

    if(mpeg2->color_description)
      vp->fi.fi_color_space = mpeg2->matrix_coefficients;

    switch(pm->aspect_override) {

    default:
      switch(mpeg2->aspect_ratio) {
      case VDEC_MPEG2_ARI_SAR_1_1:
	vp->fi.fi_dar_num = mpeg2->width;
	vp->fi.fi_dar_den = mpeg2->height;
	break;
      case VDEC_MPEG2_ARI_DAR_4_3:
	vp->fi.fi_dar_num = 4;
	vp->fi.fi_dar_den = 3;
	break;
      case VDEC_MPEG2_ARI_DAR_16_9:
	vp->fi.fi_dar_num = 16;
	vp->fi.fi_dar_den = 9;
	break;
      case VDEC_MPEG2_ARI_DAR_2P21_1:
	vp->fi.fi_dar_num = 221;
	vp->fi.fi_dar_den = 100;
	break;
      }
      break;
    case 1:
      vp->fi.fi_dar_num = 4;
      vp->fi.fi_dar_den = 3;
      break;
    case 2:
      vp->fi.fi_dar_num = 16;
      vp->fi.fi_dar_den = 9;
      break;
    }

    snprintf(metainfo, sizeof(metainfo),
	     "MPEG2 %dx%d%c (Cell)",
	     mpeg2->width, mpeg2->height, vp->fi.fi_interlaced ? 'i' : 'p');

    if(pts == AV_NOPTS_VALUE && dts != AV_NOPTS_VALUE &&
       mpeg2->picture_coding_type[0] == 3)
      pts = dts;

#if VDEC_DETAILED_DEBUG
    TRACE(TRACE_DEBUG, "VDEC DEC", "%ld %d",
	  pts,
	  mpeg2->picture_coding_type[0]);
#endif

    order = vdd->order_base;
    vdd->order_base++;

  } else {
    vdec_h264_info *h264 = (void *)(intptr_t)pi->codec_specific_addr;

    lumasize = h264->width * h264->height;
    vp = alloc_picture(vdd, lumasize);

    vp->fi.fi_width = h264->width;
    vp->fi.fi_height = h264->height;
    vp->fi.fi_duration = h264->frame_rate <= 7 ? 
      mpeg_durations[h264->frame_rate + 1] : 40000;
    vp->fi.fi_interlaced = 0;
    vp->fi.fi_tff = 0;
    if(h264->color_description_present_flag)
      vp->fi.fi_color_space = h264->matrix_coefficients;

    vp->fi.fi_dar_num = h264->width;
    vp->fi.fi_dar_den = h264->height;

    if(h264->aspect_ratio_idc == 0xff) {
      vp->fi.fi_dar_num *= h264->sar_width;
      vp->fi.fi_dar_den *= h264->sar_height;
    } else {
      const uint8_t *p;
      p = h264_sar[h264->aspect_ratio_idc <= 16 ? h264->aspect_ratio_idc : 0];
      vp->fi.fi_dar_num *= p[0];
      vp->fi.fi_dar_den *= p[1];
    }

    if(h264->idr_picture_flag) {
      vdd->order_base += 0x100000000LL;
      vdd->poc_ext = 0;
    }

    uint32_t om = h264->pic_order_count[0] & 0x7fff;

    int p = om >> 13;
    if(p == ((vdd->poc_ext + 1) & 3)) {
      vdd->poc_ext = p;
      if(p == 0)
	vdd->order_base += 0x100000000LL;
    }

    if(p == 3 && vdd->poc_ext == 0) {
      order = vdd->order_base + om - 0x100000000LL;
    } else {
      order = vdd->order_base + om;
    }

    if(pts == AV_NOPTS_VALUE && dts != AV_NOPTS_VALUE) {
      if(h264->picture_type[0] == 2) {
	vdd->seen_b_frames = 100;
	pts = dts;
      }

      if(vdd->seen_b_frames)
	vdd->seen_b_frames--;

      if(!vdd->seen_b_frames)
	pts = dts;
    }

#if VDEC_DETAILED_DEBUG
    TRACE(TRACE_DEBUG, "VDEC DEC", "POC=%3d:%-3d IDR=%d PS=%d LD=%d %x 0x%llx %ld %d",
	  (uint16_t)h264->pic_order_count[0],
	  (uint16_t)h264->pic_order_count[1],
	  h264->idr_picture_flag,
	  h264->pic_struct,
	  h264->low_delay_hrd_flag,
	  h264->nalUnitPresentFlags,
	  order,
	  pts,
	  h264->picture_type[0]);
#endif

    if(vdd->level_major)
      snprintf(metainfo, sizeof(metainfo),
	       "h264 (Level %d.%d) %dx%d%c (Cell)",
	       vdd->level_major, vdd->level_minor,
	       h264->width, h264->height, vp->fi.fi_interlaced ? 'i' : 'p');
    else
      snprintf(metainfo, sizeof(metainfo),
	       "h264 %dx%d%c (Cell)",
	       h264->width, h264->height, vp->fi.fi_interlaced ? 'i' : 'p');

  }

  prop_set_string(vdd->metainfo, metainfo);

  vp->fi.fi_pix_fmt = PIX_FMT_YUV420P;
  vp->fi.fi_pts = pts;
  
  vp->fi.fi_epoch = pm->epoch;
  vp->fi.fi_prescaled = 0;
  vp->fi.fi_color_space = COLOR_SPACE_UNSET;
  vp->fi.fi_delta = pm->delta;
  vp->fi.fi_drive_clock = pm->drive_clock;

  vdec_get_picture(vdd->handle, &picfmt, rsx_to_ppu(vp->vp_offset));

  vp->order = order;

  hts_mutex_lock(&vdd->mtx);

  LIST_INSERT_SORTED(&vdd->pictures, vp, link, vp_cmp);

  if(vdd->max_order != -1) {
    if(vp->order > vdd->max_order) {
      vdd->flush_to = vdd->max_order;
      vdd->max_order = vp->order;
    }
  } else {
    vdd->max_order = vp->order;
  }
  hts_mutex_unlock(&vdd->mtx);

}
예제 #9
0
/*
 * Process a file
 */
static void
scanfile_load_file
  ( const char *type, fb_dir *dir, const char *name )
{
  int i, opos;
  fb_file *fp;
  scanfile_region_t *reg = NULL;
  scanfile_network_t *net;
  char *str;
  char buf[256], buf2[256], buf3[256];
  tvhtrace("scanfile", "load file %s", name);

  fp = fb_open2(dir, name, 1, 0);
  if (!fp) return;

  /* Region */
  strncpy(buf, name, sizeof(buf));
  if (!strcmp(type, "dvb-s")) {
    reg = scanfile_region_create(type, "geo", "Geo-synchronous Orbit");
  } else {
    str = buf;
    while (*str) {
      if (*str == '-') {
        *str = '\0';
        reg  = scanfile_region_create(type, buf, tldcode2longname(buf));
        *str = '-';
        break;
      }
      str++;
    }
  }
  if (!reg) {
    fb_close(fp);
    return;
  }

  /* Network */
  str = buf;
  while (*str) {
    if (!isprint(*str)) *str = '_';
    str++;
  }
  *str = '\0';
  if (!strcmp(type, "dvb-s") && scanfile_network_dvbs_pos(buf, &opos)) {
    snprintf(buf3, sizeof(buf3), "%c%3i.%i%c:%s", opos < 0 ? '<' : '>',
                                                   abs(opos) / 10, abs(opos) % 10,
                                                   opos < 0 ? 'W' :'E', buf);
    strcpy(buf, buf3);
  }
  snprintf(buf2, sizeof(buf2), "%s_%s", type, buf);
  net = calloc(1, sizeof(scanfile_network_t));
  net->sfn_id   = strdup(buf2);
  net->sfn_name = strdup(buf);
  LIST_INSERT_SORTED(&reg->sfr_networks, net, sfn_link, scanfile_network_cmp);

  /* Process file */
  while (!fb_eof(fp)) {

    /* Get line */
    memset(buf, 0, sizeof(buf));
    if (!fb_gets(fp, buf, sizeof(buf) - 1)) break;
    i = 0;
    while (buf[i]) {
      if (buf[i] == '#') 
        buf[i] = '\0';
      else
        i++;
    }
    while (i > 0 && buf[i-1] < 32) buf[--i] = 0;

    /* Process mux */
    switch (*buf) {
      case 'A':
      case 'C':
      case 'T':
      case 'S':
        scanfile_load_one(net, buf);
      default:
        break;
    }
  }
  fb_close(fp);
}
예제 #10
0
파일: muxes.c 프로젝트: 1MAK1/tvheadend
/*
 * Process a file
 */
static void _muxes_load_file
  ( const char *type, fb_dir *dir, const char *name )
{
  int i;
  fb_file *fp;
  region_t *reg = NULL;
  network_t *net;
  char *str;
  char buf[256], buf2[256];

  fp = fb_open2(dir, name, 1, 0);
  if (!fp) return;

  /* Region */
  strncpy(buf, name, sizeof(buf));
  if (!strcmp(type, "dvb-s")) {
    reg = _muxes_region_create(type, "geo", "Geo-synchronous Orbit");
  } else {
    str = buf;
    while (*str) {
      if (*str == '-') {
        *str = '\0';
        reg  = _muxes_region_create(type, buf, tldcode2longname(buf));
        *str = '-';
        break;
      }
      str++;
    }
  }
  if (!reg) {
    fb_close(fp);
    return;
  }

  /* Network */
  str = buf;
  while (*str) {
    if (!isalnum(*str)) *str = '_';
    str++;
  }
  *str = '\0';
  snprintf(buf2, sizeof(buf2), "%s_%s", type, buf);
  net = calloc(1, sizeof(network_t));
  net->id   = strdup(buf2);
  net->name = strdup(buf);
  LIST_INSERT_SORTED(&reg->networks, net, link, _net_cmp);

  /* Process file */
  while (!fb_eof(fp)) {

    /* Get line */
    memset(buf, 0, sizeof(buf));
    if (!fb_gets(fp, buf, sizeof(buf) - 1)) break;
    i = 0;
    while (buf[i]) {
      if (buf[i] == '#') 
        buf[i] = '\0';
      else
        i++;
    }
    while (i > 0 && buf[i-1] < 32) buf[--i] = 0;

    /* Process mux */
    switch (*buf) {
      case 'A':
      case 'C':
      case 'T':
      case 'S':
        _muxes_load_one(net, buf);
      default:
        break;
    }
  }
  fb_close(fp);
}