예제 #1
0
파일: rtmp.c 프로젝트: kshostak/showtime
static event_t *
rtmp_process_event(rtmp_t *r, event_t *e, media_buf_t **mbp)
{
  media_pipe_t *mp = r->mp;

  if(event_is_type(e, EVENT_EXIT) ||
     event_is_type(e, EVENT_PLAY_URL) ||
     event_is_action(e, ACTION_SKIP_FORWARD))
    return e;
  
  if(event_is_action(e, ACTION_SKIP_BACKWARD)) {
    if(mp->mp_seek_base < MP_SKIP_LIMIT) {
      return e;
    }
    video_seek(r, mp, mbp, 0, "direct");
  }
  
  if(event_is_type(e, EVENT_CURRENT_TIME)) {
    event_ts_t *ets = (event_ts_t *)e;
    
    int sec = ets->ts / 1000000;

    if(sec != r->restartpos_last && r->can_seek) {
      r->restartpos_last = sec;
      metadb_set_video_restartpos(r->canonical_url, mp->mp_seek_base / 1000);
    }

  } else if(r->can_seek && event_is_type(e, EVENT_SEEK)) {
    event_ts_t *ets = (event_ts_t *)e;

    video_seek(r, mp, mbp, ets->ts, "direct");

  } else if(event_is_action(e, ACTION_STOP)) {
    mp_set_playstatus_stop(mp);
  } else if(event_is_type(e, EVENT_SELECT_SUBTITLE_TRACK)) {
    event_select_track_t *est = (event_select_track_t *)e;
    prop_set_string(mp->mp_prop_subtitle_track_current, est->id);
    if(!strcmp(est->id, "sub:off")) {
      mp_load_ext_sub(mp, NULL);
      } else {
      mp_load_ext_sub(mp, est->id);
    }

  }
  event_release(e);
  return NULL;
}
예제 #2
0
파일: rtmp.c 프로젝트: Daisho/showtime
static event_t *
rtmp_process_event(rtmp_t *r, event_t *e, media_buf_t **mbp)
{
  media_pipe_t *mp = r->mp;

  if(event_is_type(e, EVENT_EXIT) ||
     event_is_type(e, EVENT_PLAY_URL))
    return e;

  if(event_is_action(e, ACTION_PLAYPAUSE) ||
     event_is_action(e, ACTION_PLAY) ||
     event_is_action(e, ACTION_PAUSE)) {
    
    r->hold = action_update_hold_by_event(r->hold, e);
    mp_send_cmd_head(mp, &mp->mp_video, r->hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
    mp_send_cmd_head(mp, &mp->mp_audio, r->hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
    mp_set_playstatus_by_hold(mp, r->hold, NULL);
    r->lost_focus = 0;
    

  } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) {

    r->hold = 1;
    r->lost_focus = 1;
    mp_send_cmd_head(mp, &mp->mp_video, MB_CTRL_PAUSE);
    mp_send_cmd_head(mp, &mp->mp_audio, MB_CTRL_PAUSE);
    mp_set_playstatus_by_hold(mp, r->hold, e->e_payload);
    
  } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) {
    
    if(r->lost_focus) {
      r->hold = 0;
      r->lost_focus = 0;
      mp_send_cmd_head(mp, &mp->mp_video, MB_CTRL_PLAY);
      mp_send_cmd_head(mp, &mp->mp_audio, MB_CTRL_PLAY);
      mp_set_playstatus_by_hold(mp, r->hold, NULL);
    }
    
  } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) {
    
    r->hold = 1;
    r->lost_focus = 0;
    mp_send_cmd_head(mp, &mp->mp_video, MB_CTRL_PAUSE);
    mp_send_cmd_head(mp, &mp->mp_audio, MB_CTRL_PAUSE);
    mp_set_playstatus_by_hold(mp, r->hold, e->e_payload);

  } else if(event_is_type(e, EVENT_CURRENT_PTS)) {
    event_ts_t *ets = (event_ts_t *)e;
    
    r->seekbase = ets->ts;
    
    int sec = r->seekbase / 1000000;

    if(sec != r->restartpos_last && r->can_seek) {
      r->restartpos_last = sec;
      metadb_set_video_restartpos(r->canonical_url, r->seekbase / 1000);
    }

  } else if(r->can_seek && event_is_type(e, EVENT_SEEK)) {
    event_ts_t *ets = (event_ts_t *)e;

    r->epoch++;
      
    r->seekbase = video_seek(r, mp, mbp, ets->ts, 1, "direct");

  } else if(r->can_seek && event_is_action(e, ACTION_SEEK_FAST_BACKWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase - 60000000, 1, "-60s");

  } else if(r->can_seek && event_is_action(e, ACTION_SEEK_BACKWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase - 15000000, 1, "-15s");

  } else if(r->can_seek && event_is_action(e, ACTION_SEEK_FORWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase + 15000000, 1, "+15s");

  } else if(r->can_seek && event_is_action(e, ACTION_SEEK_FAST_FORWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase + 60000000, 1, "+60s");

  } else if(event_is_action(e, ACTION_STOP)) {
    mp_set_playstatus_stop(mp);
  } else if(event_is_type(e, EVENT_SELECT_SUBTITLE_TRACK)) {
    event_select_track_t *est = (event_select_track_t *)e;
    prop_set_string(mp->mp_prop_subtitle_track_current, est->id);
    if(!strcmp(est->id, "sub:off")) {
      mp_load_ext_sub(mp, NULL);
      } else {
      mp_load_ext_sub(mp, est->id);
    }

  }
  event_release(e);
  return NULL;
}
예제 #3
0
파일: rtmp.c 프로젝트: Daisho/showtime
static event_t *
rtmp_loop(rtmp_t *r, media_pipe_t *mp, char *url, char *errbuf, size_t errlen)
{
  RTMPPacket p = {0};
  int pos = -1, ret;
  uint32_t dts;
  event_t *e = NULL;

  mp_set_playstatus_by_hold(mp, 0, NULL);

  while(1) {


    if(pos == -1) {

      mp->mp_eof = 0;
      ret = RTMP_GetNextMediaPacket(r->r, &p);

      if(ret == 2) {
	/* Wait for queues to drain */
	mp->mp_eof = 1;
      again:
	e = mp_wait_for_empty_queues(mp);

	if(e != NULL) {
	  e = rtmp_process_event(r, e, NULL);
	  if(e == NULL)
	    goto again;
	}
	mp_set_playstatus_stop(mp);

	if(e == NULL)
	  e = event_create_type(EVENT_EOF);
	break;
      }

      if(ret == 0) {
	RTMP_Close(r->r);
	  
	RTMP_Init(r->r);

	memset(&p, 0, sizeof(p));

	TRACE(TRACE_DEBUG, "RTMP", "Reconnecting stream at pos %d", 
	      r->seekbase);

	if(!RTMP_SetupURL(r->r, url)) {
	  snprintf(errbuf, errlen, "Unable to setup RTMP session");
	  e = NULL;
	  break;
	}

	if(!RTMP_Connect(r->r, NULL)) {
	  snprintf(errbuf, errlen, "Unable to connect RTMP session");
	  e = NULL;
	  break;
	}

	if(!RTMP_ConnectStream(r->r, r->can_seek ? r->seekbase / 1000 : 0)) {
	  snprintf(errbuf, errlen, "Unable to stream RTMP session");
	  return NULL;
	}
	r->epoch++;


	r->lastdts = 0;
	r->seekbase = AV_NOPTS_VALUE;
	mp_flush(mp, 0);
	continue;
      }

      dts = p.m_nTimeStamp;

      switch(p.m_packetType) {
      case RTMP_PACKET_TYPE_INFO:
	if(handle_metadata(r, p.m_body, p.m_nBodySize, mp, errbuf, errlen)) {
	  RTMPPacket_Free(&p);
	  return NULL;
	}
	break;

      case RTMP_PACKET_TYPE_VIDEO:
	e = get_packet_v(r, (void *)p.m_body, p.m_nBodySize, dts, mp);
	break;

      case RTMP_PACKET_TYPE_AUDIO:
	e = get_packet_a(r, (void *)p.m_body, p.m_nBodySize, dts, mp);
	break;
	
      case 0x16:
	pos = 0;
	break;
      default:
	TRACE(TRACE_DEBUG, "RTMP", 
	      "Got unknown packet type %d\n", p.m_packetType);
	break;
      }
      if(pos == -1)
	RTMPPacket_Free(&p);
    }

    if(pos != -1) {
      if(pos + 11 < p.m_nBodySize) {
	uint32_t ds = AMF_DecodeInt24(p.m_body + pos + 1);
	  
	if(pos + 11 + ds + 4 > p.m_nBodySize) {
	  snprintf(errbuf, errlen, "Corrupt stream");
	  RTMPPacket_Free(&p);
	  return NULL;
	}

	dts = AMF_DecodeInt24(p.m_body + pos + 4);
	dts |= (p.m_body[pos + 7] << 24);

	if(p.m_body[pos] == RTMP_PACKET_TYPE_INFO) {
	  if(handle_metadata(r, p.m_body, p.m_nBodySize, mp, errbuf, errlen)) {
	    RTMPPacket_Free(&p);
	    return NULL;
	  }
	} else if(p.m_body[pos] == RTMP_PACKET_TYPE_VIDEO) {
	  e = get_packet_v(r, (void *)p.m_body + pos + 11, ds, dts, mp);
	} else if(p.m_body[pos] == RTMP_PACKET_TYPE_AUDIO) {
	  e = get_packet_a(r, (void *)p.m_body + pos + 11, ds, dts, mp);
	} else {
	  TRACE(TRACE_DEBUG, "RTMP", 
		"Got unknown packet type %d\n", p.m_body[pos]);
	}
	pos += 11 + ds + 4;
      } else {
	pos = -1;
	RTMPPacket_Free(&p);
      }
    }
    if(e != NULL)
      break;
  }
  return e;
}
예제 #4
0
파일: rtmp.c 프로젝트: aznboi665/showtime
static event_t *
rtmp_process_event(rtmp_t *r, event_t *e, media_buf_t **mbp)
{
  media_pipe_t *mp = r->mp;

  if(event_is_type(e, EVENT_EXIT) ||
     event_is_type(e, EVENT_PLAY_URL))
    return e;

  if(event_is_action(e, ACTION_PLAYPAUSE) ||
     event_is_action(e, ACTION_PLAY) ||
     event_is_action(e, ACTION_PAUSE)) {
    
    r->hold = action_update_hold_by_event(r->hold, e);
    mp_send_cmd_head(mp, &mp->mp_video, r->hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
    mp_send_cmd_head(mp, &mp->mp_audio, r->hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
    mp_set_playstatus_by_hold(mp, r->hold, NULL);
    r->lost_focus = 0;
    

  } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) {

    r->hold = 1;
    r->lost_focus = 1;
    mp_send_cmd_head(mp, &mp->mp_video, MB_CTRL_PAUSE);
    mp_send_cmd_head(mp, &mp->mp_audio, MB_CTRL_PAUSE);
    mp_set_playstatus_by_hold(mp, r->hold, e->e_payload);
    
  } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) {
    
    if(r->lost_focus) {
      r->hold = 0;
      r->lost_focus = 0;
      mp_send_cmd_head(mp, &mp->mp_video, MB_CTRL_PLAY);
      mp_send_cmd_head(mp, &mp->mp_audio, MB_CTRL_PLAY);
      mp_set_playstatus_by_hold(mp, r->hold, NULL);
    }
    
  } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) {
    
    r->hold = 1;
    r->lost_focus = 0;
    mp_send_cmd_head(mp, &mp->mp_video, MB_CTRL_PAUSE);
    mp_send_cmd_head(mp, &mp->mp_audio, MB_CTRL_PAUSE);
    mp_set_playstatus_by_hold(mp, r->hold, e->e_payload);

  } else if(event_is_type(e, EVENT_CURRENT_PTS)) {
    event_ts_t *ets = (event_ts_t *)e;
    
    r->seekbase = ets->pts;
    
  } else if(event_is_type(e, EVENT_SEEK)) {
    event_ts_t *ets = (event_ts_t *)e;

    r->epoch++;
      
    r->seekbase = video_seek(r, mp, mbp, ets->pts, 1, "direct");

  } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase - 60000000, 1, "-60s");

  } else if(event_is_action(e, ACTION_SEEK_BACKWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase - 15000000, 1, "-15s");

  } else if(event_is_action(e, ACTION_SEEK_FORWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase + 15000000, 1, "+15s");

  } else if(event_is_action(e, ACTION_SEEK_FAST_FORWARD)) {

    r->seekbase = video_seek(r, mp, mbp, r->seekbase + 60000000, 1, "+60s");

  } else if(event_is_action(e, ACTION_STOP)) {
    mp_set_playstatus_stop(mp);
  } else if(event_is_type(e, EVENT_SELECT_TRACK)) {
    event_select_track_t *est = (event_select_track_t *)e;
    prop_set_string(mp->mp_prop_subtitle_track_current, est->id);

    if(r->sub != NULL)
      subtitles_destroy(r->sub);
    
    r->sub = subtitles_load(est->id);
  }
  event_release(e);
  return NULL;
}