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

📄 player_session.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 * 
 * The Original Code is MPEG4IP.
 * 
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
 * 
 * Contributor(s): 
 *              Bill May        wmay@cisco.com
 */
/* 
 * player_session.cpp - describes player session class, which is the
 * main access point for the player
 */
#include "systems.h"
#include "player_session.h"
#include "player_media.h"
#include "player_sdp.h"
#include "player_util.h"
#include "audio.h"
#include "video.h"

#ifdef _WIN32
DEFINE_MESSAGE_MACRO(sync_message, "avsync")
#else
#define sync_message(loglevel, fmt...) message(loglevel, "avsync", fmt)
#endif
/*
 * c callback for sync thread
 */

CPlayerSession::CPlayerSession (CMsgQueue *master_mq, 
				SDL_sem *master_sem,
				const char *name)
{
  m_sdp_info = NULL;
  m_my_media = NULL;
  m_rtsp_client = NULL;
  m_video_sync = NULL;
  m_audio_sync = NULL;
  m_sync_thread = NULL;
  m_sync_sem = NULL;
  m_content_base = NULL;
  m_master_msg_queue = master_mq;
  m_master_msg_queue_sem = master_sem;
  m_paused = 0;
  m_streaming = 0;
  m_session_name = strdup(name);
  m_audio_volume = 75;
  m_current_time = 0;
  m_seekable = 0;
  m_session_state = SESSION_PAUSED;
  m_screen_pos_x = 0;
  m_screen_pos_y = 0;
  m_clock_wrapped = -1;
  m_hardware_error = 0;
  m_fullscreen = 0;
  m_session_control_is_aggregate = 0;
  for (int ix = 0; ix < SESSION_DESC_COUNT; ix++) {
    m_session_desc[ix] = NULL;
  }
  m_media_close_callback = NULL;
  m_media_close_callback_data = NULL;
  m_streaming_media_set_up = 0;
  m_unused_ports = NULL;
  m_first_time_played = 0;
  m_latency = 0;
}

CPlayerSession::~CPlayerSession ()
{
  int hadthread = 0;
#ifndef _WINDOWS
  if (m_sync_thread) {
    send_sync_thread_a_message(MSG_STOP_THREAD);
    SDL_WaitThread(m_sync_thread, NULL);
    m_sync_thread = NULL;
    hadthread = 1;
  }
#else
  send_sync_thread_a_message(MSG_STOP_THREAD);
  hadthread = 1;
#endif



  if (m_streaming_media_set_up != 0 &&
      session_control_is_aggregate()) {
    rtsp_command_t cmd;
    rtsp_decode_t *decode;
    memset(&cmd, 0, sizeof(rtsp_command_t));
    rtsp_send_aggregate_teardown(m_rtsp_client,
				 m_sdp_info->control_string,
				 &cmd,
				 &decode);
    free_decode_response(decode);
  }


  if (m_rtsp_client) {
    free_rtsp_client(m_rtsp_client);
    m_rtsp_client = NULL;
  }

  while (m_my_media != NULL) {
    CPlayerMedia *p;
    p = m_my_media;
    m_my_media = p->get_next();
    delete p;
  }  

  if (m_sdp_info) {
    sdp_free_session_desc(m_sdp_info);
    m_sdp_info = NULL;
  }

  if (m_sync_sem) {
    SDL_DestroySemaphore(m_sync_sem);
    m_sync_sem = NULL;
  }
  
  if (m_video_sync != NULL) {
    delete m_video_sync;
    m_video_sync = NULL;
  }

  if (m_audio_sync != NULL) {
    delete m_audio_sync;
    m_audio_sync = NULL;
  }
  if (m_session_name) {
    free((void *)m_session_name);
    m_session_name = NULL;
  }
  if (m_content_base) {
    free((void *) m_content_base);
    m_content_base = NULL;
  }
  for (int ix = 0; ix < SESSION_DESC_COUNT; ix++) {
    if (m_session_desc[ix] != NULL) 
      free((void *)m_session_desc[ix]);
    m_session_desc[ix] = NULL;
  }
  
  if (m_media_close_callback != NULL) {
    m_media_close_callback(m_media_close_callback_data);
  }

  while (m_unused_ports != NULL) {
    CIpPort *first;
    first = m_unused_ports;
    m_unused_ports = first->get_next();
    delete first;
  }
  if (hadthread != 0) {
    SDL_Quit();
  }
}

int CPlayerSession::create_streaming_broadcast (session_desc_t *sdp,
						char *ermsg,
						uint32_t errlen)
{
  session_set_seekable(0);
  m_sdp_info = sdp;
  m_streaming = 1;
  m_rtp_over_rtsp = 0;
  return (0);
}
/*
 * create_streaming - create a session for streaming.  Create an
 * RTSP session with the server, get the SDP information from it.
 */
int CPlayerSession::create_streaming_ondemand (const char *url, 
					       char *errmsg,
					       uint32_t errlen, 
					       int use_tcp)
{
  rtsp_command_t cmd;
  rtsp_decode_t *decode;
  sdp_decode_info_t *sdpdecode;
  int dummy;
  int err;

  // streaming has seek capability (at least on demand)
  session_set_seekable(1);
  player_debug_message("Creating streaming %s", url);
  memset(&cmd, 0, sizeof(rtsp_command_t));

  /*
   * create RTSP session
   */
  if (use_tcp != 0) {
    m_rtsp_client = rtsp_create_client_for_rtp_tcp(url, &err);
  } else {
    m_rtsp_client = rtsp_create_client(url, &err);
  }
  if (m_rtsp_client == NULL) {
    snprintf(errmsg, errlen, "Failed to create RTSP client");
    player_error_message("Failed to create rtsp client - error %d", err);
    return (err);
  }
  m_rtp_over_rtsp = use_tcp;

  cmd.accept = "application/sdp";

  /*
   * Send the RTSP describe.  This should return SDP information about
   * the session.
   */
  if (rtsp_send_describe(m_rtsp_client, &cmd, &decode) !=
      RTSP_RESPONSE_GOOD) {
    int retval;
    if (decode != NULL) {
      retval = (((decode->retcode[0] - '0') * 100) +
		((decode->retcode[1] - '0') * 10) +
		(decode->retcode[2] - '0'));
    } else {
      retval = -1;
    }
    snprintf(errmsg, errlen, "RTSP describe error %d %s", retval,
	     decode->retresp != NULL ? decode->retresp : "");
    player_error_message("Describe response not good\n");
    free_decode_response(decode);
    return (retval);
  }

  sdpdecode = set_sdp_decode_from_memory(decode->body);
  if (sdpdecode == NULL) {
    snprintf(errmsg, errlen, "Memory failure");
    player_error_message("Couldn't get sdp decode\n");
    free_decode_response(decode);
    return (-1);
  }

  /*
   * Decode the SDP information into structures we can use.
   */
  err = sdp_decode(sdpdecode, &m_sdp_info, &dummy);
  free(sdpdecode);
  if (err != 0) {
    snprintf(errmsg, errlen, "Couldn't decode session description %s",
	     decode->body);
    player_error_message("Couldn't decode sdp %s", decode->body);
    free_decode_response(decode);
    return (-1);
  }
  if (dummy != 1) {
    snprintf(errmsg, errlen, "Incorrect number of sessions in sdp decode %d",
	     dummy);
    player_error_message(errmsg);
    free_decode_response(decode);
    return (-1);
  }

  if (m_sdp_info->control_string != NULL) {
    set_session_control(1);
  }
  /*
   * Make sure we can use the urls in the sdp info
   */
  if (decode->content_location != NULL) {
    // Note - we may have problems if the content location is not absolute.
    m_content_base = strdup(decode->content_location);
  } else if (decode->content_base != NULL) {
    m_content_base = strdup(decode->content_base);
  } else {
    int urllen = strlen(url);
    if (url[urllen] != '/') {
      char *temp;
      temp = (char *)malloc(urllen + 2);
      strcpy(temp, url);
      strcat(temp, "/");
      m_content_base = temp;
    } else {
      m_content_base = strdup(url);
    }
  }

  convert_relative_urls_to_absolute(m_sdp_info,
				    m_content_base);

  free_decode_response(decode);
  m_streaming = 1;
  return (0);
}

CVideoSync * CPlayerSession::set_up_video_sync (void)
{
  if (m_video_sync == NULL) {
    m_video_sync = create_video_sync(this);
  }
  return m_video_sync;
}

CAudioSync *CPlayerSession::set_up_audio_sync (void)
{
  if (m_audio_sync == NULL) {
    m_audio_sync = create_audio_sync(this, m_audio_volume);
  }
  return m_audio_sync;
}
/*
 * set_up_sync_thread.  Creates the sync thread, and a sync class
 * for each media
 */
void CPlayerSession::set_up_sync_thread(void) 
{
  CPlayerMedia *media;

  media = m_my_media;
  while (media != NULL) {
    if (media->is_video()) {

⌨️ 快捷键说明

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