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

📄 media_utils.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 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
 */
/*
 * media_utils.cpp - various utilities, globals (ick).
 */
#include <stdlib.h>
#include <sdp/sdp.h>
#include <libhttp/http.h>
#include "media_utils.h"
#include "player_session.h"
#include "player_media.h"
#include "codec/mp3/mp3_rtp_bytestream.h"
#include "avi_file.h"
#include "mp4_file.h"
#include "qtime_file.h"
#include "our_config_file.h"
#include "rtp_bytestream.h"
#include "codec/aa/isma_rtp_bytestream.h"
#include "codec_plugin_private.h"
#include <gnu/strcasestr.h>
#include "rfc3119_bytestream.h"
#include "mpeg3_rtp_bytestream.h"
#include "mpeg3_file.h"
#include "audio.h"
#include "mpeg2t.h"
/*
 * This needs to be global so we can store any ports that we don't
 * care about but need to reserve
 */
enum {
  VIDEO_MPEG4_ISO,
  VIDEO_DIVX,
  VIDEO_MPEG4_ISO_OR_DIVX,
  VIDEO_MPEG12,
};

enum {
  MPEG4IP_AUDIO_AAC,
  MPEG4IP_AUDIO_MP3,
  MPEG4IP_AUDIO_WAV,
  MPEG4IP_AUDIO_MPEG4_GENERIC,
  MPEG4IP_AUDIO_MP3_ROBUST,
  MPEG4IP_AUDIO_GENERIC,
};
/*
 * these are lists of supported audio and video codecs
 */
static struct codec_list_t {
  const char *name;
  int val;
} video_codecs[] = {
  {"mp4 ", VIDEO_MPEG4_ISO},
  {"mp4v", VIDEO_MPEG4_ISO},
  {"MPG4", VIDEO_MPEG4_ISO},
  {"MP4V-ES", VIDEO_MPEG4_ISO_OR_DIVX},
  {"MPEG4-GENERIC", VIDEO_DIVX},
  {"divx", VIDEO_DIVX},
  {"dvx1", VIDEO_DIVX},
  {"div4", VIDEO_DIVX},
  {NULL, -1},
},
  audio_codecs[] = {
    {"MPEG4-GENERIC", MPEG4IP_AUDIO_MPEG4_GENERIC},
    {"MPA", MPEG4IP_AUDIO_MP3 },
    {"mpa-robust", MPEG4IP_AUDIO_MP3_ROBUST}, 
    {"L16", MPEG4IP_AUDIO_GENERIC },
    {"L8", MPEG4IP_AUDIO_GENERIC },
    {NULL, -1},
  };



static int lookup_codec_by_name (const char *name,
				 struct codec_list_t *codec_list)
{
  for (struct codec_list_t *cptr = codec_list; cptr->name != NULL; cptr++) {
    if (strcasecmp(name, cptr->name) == 0) {
      return (cptr->val);
    }
  }
  return (-1);
}
  
int lookup_audio_codec_by_name (const char *name)
{
  return (lookup_codec_by_name(name, audio_codecs));
}

int lookup_video_codec_by_name (const char *name)
{
  return (lookup_codec_by_name(name, video_codecs));
}
				

static int create_media_from_sdp (CPlayerSession *psptr,
				  const char *name,
				  session_desc_t *sdp,
				  char *errmsg,
				  uint32_t errlen,
				  int have_audio_driver,
				  int broadcast,
				  control_callback_vft_t *cc_vft)
{
  int err;
  int media_count = 0;
  int invalid_count = 0;
  int have_audio_but_no_driver = 0;
  char buffer[80];
  codec_plugin_t *codec;
  format_list_t *fmt;
  int audio_count, video_count;
  int audio_offset, video_offset;
  int ix;

  if (sdp->session_name != NULL) {
    snprintf(buffer, sizeof(buffer), "Name: %s", sdp->session_name);
    psptr->set_session_desc(0, buffer);
  }
  if (sdp->session_desc != NULL) {
    snprintf(buffer, sizeof(buffer), "Description: %s", sdp->session_desc);
    psptr->set_session_desc(1, buffer);
  }
  if (sdp->media != NULL &&
      sdp->media->next == NULL &&
      strcasecmp(sdp->media->media, "video") == 0 &&
      sdp->media->fmt != NULL &&
      strcmp(sdp->media->fmt->fmt, "33") == 0) {
    // we have a mpeg2 transport stream
  }
  media_desc_t *sdp_media;
  audio_count = video_count = 0;
  for (sdp_media = psptr->get_sdp_info()->media;
       sdp_media != NULL;
       sdp_media = sdp_media->next) {
    if (strcasecmp(sdp_media->media, "audio") == 0) {
      if (have_audio_driver == 0) {
	have_audio_but_no_driver = 1;
      } else {
	audio_count++;
      }
    } else if (strcasecmp(sdp_media->media, "video") == 0) {
      video_count++;
    }
  }

  video_query_t *vq;
  audio_query_t *aq;

  if (video_count > 0) {
    vq = (video_query_t *)malloc(sizeof(video_query_t) * video_count);
  } else {
    vq = NULL;
  }
  if (audio_count > 0) {
    aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_count);
  } else {
    aq = NULL;
  }
      
  video_offset = audio_offset = 0;
  for (sdp_media = psptr->get_sdp_info()->media;
       sdp_media != NULL;
       sdp_media = sdp_media->next) {

    if (have_audio_driver != 0 &&
	strcasecmp(sdp_media->media, "audio") == 0) {
      fmt = sdp_media->fmt;
      codec = NULL;
      while (codec == NULL && fmt != NULL) {
	codec = check_for_audio_codec(NULL, 
				      fmt,
				      -1,
				      -1,
				      NULL,
				      0);
	if (codec == NULL) fmt = fmt->next;
      }
      if (codec == NULL) {
	invalid_count++;
	continue;
      } else {
	// set up audio qualifier
	aq[audio_offset].track_id = audio_offset;
	aq[audio_offset].compressor = NULL;
	aq[audio_offset].type = -1;
	aq[audio_offset].profile = -1;
	aq[audio_offset].fptr = fmt;
	aq[audio_offset].sampling_freq = -1;
	aq[audio_offset].chans = -1;
	aq[audio_offset].enabled = 0;
	aq[audio_offset].reference = NULL;
	audio_offset++;
      }
    } else if (strcasecmp(sdp_media->media, "video") == 0) {
	fmt = sdp_media->fmt;
	codec = NULL;
	while (codec == NULL && fmt != NULL) {
	  codec = check_for_video_codec(NULL, 
					fmt,
					-1,
					-1,
					NULL,
					0);
	  if (codec == NULL) fmt = fmt->next;
	}
	if (codec == NULL) {
	  invalid_count++;
	  continue;
	} else {
	  vq[video_offset].track_id = video_offset;
	  vq[video_offset].compressor = NULL;
	  vq[video_offset].type = -1;
	  vq[video_offset].profile = -1;
	  vq[video_offset].fptr = fmt;
	  vq[video_offset].h = -1;
	  vq[video_offset].w = -1;
	  vq[video_offset].frame_rate = -1;
	  vq[video_offset].enabled = 0;
	  vq[video_offset].reference = NULL;
	  video_offset++;
	}
      } else {
	player_error_message("Skipping media type `%s\'", sdp_media->media);
	continue;
      }
    }
  // okay - from here, write the callback call, and go ahead...
  if (cc_vft != NULL &&
      cc_vft->media_list_query != NULL) {
    (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq);
  } else {
    if (video_offset > 0) {
      vq[0].enabled = 1;
    }
    if (audio_offset > 0) {
      aq[0].enabled = 1;
    }
  }
  for (ix = 0; ix < video_offset; ix++) {
    if (vq[ix].enabled != 0) {
      CPlayerMedia *mptr = new CPlayerMedia(psptr);
      err = mptr->create_streaming(vq[ix].fptr->media, 
				   errmsg, 
				   errlen,
				   broadcast, 
				   config.get_config_value(CONFIG_USE_RTP_OVER_RTSP),
				   media_count);
      if (err < 0) {
	return (-1);
      }
      if (err > 0) {
	delete mptr;
      } else 
	media_count++;
    }
  }
  for (ix = 0; ix < audio_offset; ix++) {
    if (aq[ix].enabled != 0) {
      CPlayerMedia *mptr = new CPlayerMedia(psptr);
      err = mptr->create_streaming(aq[ix].fptr->media, 
				   errmsg, 
				   errlen,
				   broadcast, 
				   config.get_config_value(CONFIG_USE_RTP_OVER_RTSP),
				   media_count);
      if (err < 0) {
	return (-1);
      }
      if (err > 0) {
	delete mptr;
      } else 
	media_count++;
    }
  }
  if (aq != NULL) free(aq);
  if (vq != NULL) free(vq);

  if (media_count == 0) {
    snprintf(errmsg, errlen, "No known codecs found in SDP");
    return (-1);
  }
  psptr->streaming_media_set_up();
  if (have_audio_but_no_driver > 0) {
    snprintf(errmsg, errlen, "Not playing audio codecs - no driver");
    return (1);
  }
  if (invalid_count > 0) {
    snprintf(errmsg, errlen, 
	     "There were unknowns codecs during decode - playing valid ones");
    return (1);
  }
  return (0);
}
static int create_media_for_streaming_broadcast (CPlayerSession *psptr,
						 const char *name,
						 session_desc_t *sdp,
						 char *errmsg,
						 uint32_t errlen,
						 int have_audio_driver,
						 control_callback_vft_t *cc_vft)
{
  int err;
  // need to set range in player session...
  err = psptr->create_streaming_broadcast(sdp, errmsg, errlen);
  if (err != 0) {
    return (-1);
  }
  return (create_media_from_sdp(psptr, 
				name, 
				sdp, 
				errmsg, 
				errlen,
				have_audio_driver, 
				0,
				cc_vft));
}
/*
 * create_media_for_streaming_ondemand - create streaming media session
 * for an on demand program.
 */
static int create_media_for_streaming_ondemand (CPlayerSession *psptr, 
						const char *name,
						char *errmsg,
						uint32_t errlen,
						control_callback_vft_t *cc_vft)
{
  int err;
  session_desc_t *sdp;
  /*
   * This will open the rtsp session
   */
  err = psptr->create_streaming_ondemand(name, 
					 errmsg,
					 errlen,
					 config.get_config_value(CONFIG_USE_RTP_OVER_RTSP));
  if (err != 0) {
    return (-1);
  }
  sdp = psptr->get_sdp_info();
  int have_audio_driver = do_we_have_audio();
  return (create_media_from_sdp(psptr,
				name, 
				sdp, 
				errmsg,
				errlen,
				have_audio_driver, 
				1,
				cc_vft));
}

/*

⌨️ 快捷键说明

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