Exemple #1
0
/** Find the track associated with a PS stream_id */
static VC_CONTAINER_TRACK_T *ps_find_track( VC_CONTAINER_T *ctx, uint32_t stream_id,
   uint32_t substream_id, bool b_create )
{
   VC_CONTAINER_TRACK_T *track = 0;
   unsigned int i;

   for(i = 0; i < ctx->tracks_num; i++)
      if(ctx->tracks[i]->priv->module->stream_id == stream_id && 
         ctx->tracks[i]->priv->module->substream_id == substream_id) break;

   if(i < ctx->tracks_num) /* We found it */
      track = ctx->tracks[i];

   if(!track && b_create && i < PS_TRACKS_MAX)
   {
      /* Allocate and initialise a new track */
      ctx->tracks[i] = track =
         vc_container_allocate_track(ctx, sizeof(*ctx->tracks[0]->priv->module));
      if(track)
      {
         track->priv->module->stream_id = stream_id;
         track->priv->module->substream_id = substream_id;
         ctx->tracks_num++;
      }
   }

   if(!track && b_create)
      LOG_DEBUG(ctx, "could not create track for stream id: %i", stream_id);

   return track;
}
static VC_CONTAINER_STATUS_T dummy_writer_control( VC_CONTAINER_T *p_ctx,
   VC_CONTAINER_CONTROL_T operation, va_list args )
{
   VC_CONTAINER_TRACK_T *track;
   VC_CONTAINER_PARAM_UNUSED(args);

   switch(operation)
   {
   case VC_CONTAINER_CONTROL_TRACK_ADD:
      if(p_ctx->tracks_num >= 2) return VC_CONTAINER_ERROR_OUT_OF_RESOURCES;

      /* Allocate and initialise track data */
      p_ctx->tracks[p_ctx->tracks_num] = track = vc_container_allocate_track(p_ctx, 0);
      if(!track) return VC_CONTAINER_ERROR_OUT_OF_MEMORY;

      p_ctx->tracks_num++;
      return VC_CONTAINER_SUCCESS;

   case VC_CONTAINER_CONTROL_TRACK_ADD_DONE:
      return VC_CONTAINER_SUCCESS;

   default: return VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION;
   }
}
Exemple #3
0
VC_CONTAINER_STATUS_T binary_reader_open( VC_CONTAINER_T *p_ctx )
{
   const char *extension = vc_uri_path_extension(p_ctx->priv->uri);
   VC_CONTAINER_MODULE_T *module = 0;
   VC_CONTAINER_STATUS_T status = VC_CONTAINER_ERROR_FORMAT_INVALID;
   VC_CONTAINER_ES_TYPE_T es_type = 0;
   VC_CONTAINER_FOURCC_T codec = 0;
   unsigned int i;

   /* Check if the user has specified a container */
   vc_uri_find_query(p_ctx->priv->uri, 0, "container", &extension);

   /* Check if the extension is supported */
   if(!extension || !vc_uri_path(p_ctx->priv->uri))
      return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
   for(i = 0; extension_to_format_table[i].ext; i++)
   {
      if(strcasecmp(extension, extension_to_format_table[i].ext))
         continue;

      es_type = extension_to_format_table[i].type;
      codec = extension_to_format_table[i].codec;
      break;
   }
   if(!extension_to_format_table[i].ext) return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;

   /* If this a .bin file we look in our bin list */
   for(i = 0; !codec && bin_extension_to_format_table[i].ext; i++)
   {
      if(!strstr(vc_uri_path(p_ctx->priv->uri), bin_extension_to_format_table[i].ext) &&
         !strstr(extension, bin_extension_to_format_table[i].ext))
         continue;

      es_type = bin_extension_to_format_table[i].type;
      codec = bin_extension_to_format_table[i].codec;
      break;
   }
   if(!codec) return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;

   /* Allocate our context */
   module = malloc(sizeof(*module));
   if(!module) { status = VC_CONTAINER_ERROR_OUT_OF_MEMORY; goto error; }
   memset(module, 0, sizeof(*module));
   p_ctx->priv->module = module;
   p_ctx->tracks_num = 1;
   p_ctx->tracks = &module->track;
   p_ctx->tracks[0] = vc_container_allocate_track(p_ctx, 0);
   if(!p_ctx->tracks[0]) return VC_CONTAINER_ERROR_OUT_OF_MEMORY;
   p_ctx->tracks[0]->format->es_type = es_type;
   p_ctx->tracks[0]->format->codec = codec;
   p_ctx->tracks[0]->is_enabled = true;
   module->default_block_size = DEFAULT_BLOCK_SIZE;
   if(codec == VC_CONTAINER_CODEC_JPEG)
      module->default_block_size = DEFAULT_JPEG_BLOCK_SIZE;
   module->block_size = module->default_block_size;
   module->init = 1;

   /*
    *  We now have all the information we really need to start playing the stream
    */

   p_ctx->priv->pf_close = binary_reader_close;
   p_ctx->priv->pf_read = binary_reader_read;
   p_ctx->priv->pf_seek = binary_reader_seek;
   return VC_CONTAINER_SUCCESS;

 error:
   LOG_DEBUG(p_ctx, "binary: error opening stream (%i)", status);
   return status;
}
Exemple #4
0
/**************************************************************************//**
 * Open the container.
 * Uses the I/O URI and/or data to configure the container.
 *
 * @param p_ctx   The reader context.
 * @return  The resulting status of the function.
 */
VC_CONTAINER_STATUS_T rtp_reader_open( VC_CONTAINER_T *p_ctx )
{
   VC_CONTAINER_MODULE_T *module = 0;
   VC_CONTAINER_TRACK_T *track = 0;
   VC_CONTAINER_TRACK_MODULE_T *t_module = 0;
   VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
   VC_CONTAINERS_LIST_T *parameters = NULL;
   uint32_t payload_type;
   uint32_t initial_seq_num;

   /* Check the URI scheme looks valid */
   if (!vc_uri_scheme(p_ctx->priv->uri) ||
       (strcasecmp(vc_uri_scheme(p_ctx->priv->uri), RTP_SCHEME) &&
        strcasecmp(vc_uri_scheme(p_ctx->priv->uri), RTP_PKT_SCHEME)))
      return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;

   /* Make the query/parameter list more easily searchable */
   parameters = fill_parameter_list(p_ctx->priv->uri);
   if (!parameters) { status = VC_CONTAINER_ERROR_OUT_OF_MEMORY; goto error; }

   /* Payload type parameter is mandatory and must fit in 7 bits */
   if (!rtp_get_parameter_u32(parameters, PAYLOAD_TYPE_NAME, &payload_type) || payload_type > 127)
   {
      status = VC_CONTAINER_ERROR_FORMAT_INVALID;
      goto error;
   }

   /* Allocate our context */
   module = (VC_CONTAINER_MODULE_T *)malloc(sizeof(VC_CONTAINER_MODULE_T));
   if (!module) { status = VC_CONTAINER_ERROR_OUT_OF_MEMORY; goto error; }

   memset(module, 0, sizeof(*module));
   p_ctx->priv->module = module;
   p_ctx->tracks = &module->track;

   /* Allocate the track, including space for reading an RTP packet on the end */
   track = vc_container_allocate_track(p_ctx, sizeof(VC_CONTAINER_TRACK_MODULE_T) + MAXIMUM_PACKET_SIZE);
   if (!track)
   {
      status = VC_CONTAINER_ERROR_OUT_OF_MEMORY;
      goto error;
   }
   module->track = track;
   p_ctx->tracks_num = 1;
   t_module = track->priv->module;

   /* Initialise the track data */
   t_module->buffer = (uint8_t *)(t_module + 1);
   status = decode_payload_type(p_ctx, track, parameters, payload_type);
   if (status != VC_CONTAINER_SUCCESS)
      goto error;

   vc_container_assert(t_module->timestamp_clock != 0);

   /* Default to a generic, unstructured payload handler */
   if (!t_module->payload_handler)
      t_module->payload_handler = generic_payload_handler;

   if (rtp_get_parameter_x32(parameters, SSRC_NAME, &t_module->expected_ssrc))
      SET_BIT(t_module->flags, TRACK_SSRC_SET);

   t_module->probation = MIN_SEQUENTIAL;
   if (rtp_get_parameter_u32(parameters, SEQ_NAME, &initial_seq_num))
   {
      /* If an initial sequence number is provided, avoid probation period */
      t_module->max_seq_num = (uint16_t)initial_seq_num;
      t_module->probation = 0;
   }

   track->is_enabled = true;

   vc_containers_list_destroy(parameters);

   p_ctx->priv->pf_close = rtp_reader_close;
   p_ctx->priv->pf_read = rtp_reader_read;
   p_ctx->priv->pf_seek = rtp_reader_seek;
   p_ctx->priv->pf_control = rtp_reader_control;

   return VC_CONTAINER_SUCCESS;

error:
   if (parameters) vc_containers_list_destroy(parameters);
   if(status == VC_CONTAINER_SUCCESS || status == VC_CONTAINER_ERROR_EOS)
      status = VC_CONTAINER_ERROR_FORMAT_INVALID;
   LOG_DEBUG(p_ctx, "error opening RTP (%i)", status);
   rtp_reader_close(p_ctx);
   return status;
}