Example #1
0
rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) {

  rtsp_session_t *rtsp_session = calloc(1, sizeof(rtsp_session_t));
  xine_t *xine = stream->xine;
  char *server;
  char *mrl_line=strdup(mrl);
  rmff_header_t *h;
  int bandwidth_id;
  uint32_t bandwidth;

  bandwidth_id = xine->config->register_enum(xine->config, "media.network.bandwidth", 10,
			      rtsp_bandwidth_strs,
			      _("network bandwidth"),
			      _("Specify the bandwidth of your internet connection here. "
			        "This will be used when streaming servers offer different versions "
              "with different bandwidth requirements of the same stream."),
			      0, NULL, NULL);
  bandwidth = rtsp_bandwidths[bandwidth_id];

  rtsp_session->recv = xine_buffer_init(BUF_SIZE);

connect:

  /* connect to server */
  rtsp_session->s=rtsp_connect(stream, mrl_line, NULL);
  if (!rtsp_session->s)
  {
    xprintf(stream->xine, XINE_VERBOSITY_LOG,
	    _("rtsp_session: failed to connect to server %s\n"), mrl_line);
    xine_buffer_free(rtsp_session->recv);
    free(rtsp_session);
    return NULL;
  }

  /* looking for server type */
  if (rtsp_search_answers(rtsp_session->s,"Server"))
    server=strdup(rtsp_search_answers(rtsp_session->s,"Server"));
  else {
    if (rtsp_search_answers(rtsp_session->s,"RealChallenge1"))
      server=strdup("Real");
    else
      server=strdup("unknown");
  }

  if (strstr(server,"Real") || strstr(server,"Helix"))
  {
    /* we are talking to a real server ... */

    h=real_setup_and_get_header(rtsp_session->s, bandwidth);
    if (!h) {
      /* got an redirect? */
      if (rtsp_search_answers(rtsp_session->s, "Location"))
      {
        free(mrl_line);
	mrl_line=strdup(rtsp_search_answers(rtsp_session->s, "Location"));
        xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "rtsp_session: redirected to %s\n", mrl_line);
	rtsp_close(rtsp_session->s);
	free(server);
	goto connect; /* *shudder* i made a design mistake somewhere */
      } else
      {
        xprintf(stream->xine, XINE_VERBOSITY_LOG,
		_("rtsp_session: session can not be established.\n"));
        rtsp_close(rtsp_session->s);
        xine_buffer_free(rtsp_session->recv);
        free(rtsp_session);
        return NULL;
      }
    }

	  rtsp_session->header_left =
    rtsp_session->header_len  = rmff_dump_header(h,rtsp_session->header,HEADER_SIZE);
    if (rtsp_session->header_len < 0) {
      xprintf (stream->xine, XINE_VERBOSITY_LOG,
	       _("rtsp_session: rtsp server returned overly-large headers, session can not be established.\n"));
      goto session_abort;
    }

    xine_buffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len);
    rtsp_session->recv_size = rtsp_session->header_len;
    rtsp_session->recv_read = 0;

  } else
  {
    xprintf(stream->xine, XINE_VERBOSITY_LOG,
	    _("rtsp_session: rtsp server type '%s' not supported yet. sorry.\n"), server);
    session_abort:
    rtsp_close(rtsp_session->s);
    free(server);
    xine_buffer_free(rtsp_session->recv);
    free(rtsp_session);
    return NULL;
  }
  free(server);

  return rtsp_session;
}
Example #2
0
static void jpeg_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
  jpeg_decoder_t *this = (jpeg_decoder_t *) this_gen;

  if (!this->video_open) {
    lprintf("opening video\n");
    (this->stream->video_out->open) (this->stream->video_out, this->stream);
    this->video_open = 1;
  }

  xine_buffer_copyin(this->image, this->index, buf->mem, buf->size);
  this->index += buf->size;

  if (buf->decoder_flags & BUF_FLAG_FRAME_END && this->index > 0) {
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPARRAY buffer;

    int         i, linesize;
    int         width, height;
    vo_frame_t *img;
    int         max_width, max_height;
    uint8_t    *slice_start[1] = {NULL};
    int         slice_line = 0;

    /* query max. image size vo can handle */
    max_width = this->stream->video_out->get_property( this->stream->video_out,
                                                       VO_PROP_MAX_VIDEO_WIDTH);
    max_height = this->stream->video_out->get_property( this->stream->video_out,
                                                        VO_PROP_MAX_VIDEO_HEIGHT);

    /* init and parse header */

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    jpeg_memory_src(&cinfo, this->image, this->index);
    jpeg_read_header(&cinfo, TRUE);

    _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH,  cinfo.image_width);
    _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, cinfo.image_height);

    lprintf("header parsed\n");

    /* set decoding parameters */

    cinfo.out_color_space = JCS_YCbCr;

    /* request scaling when image is too large for vo */
    if (this->cls->enable_downscaling) {
      cinfo.output_width  = cinfo.image_width;
      cinfo.output_height = cinfo.image_height;
      cinfo.scale_num   = 1;
      cinfo.scale_denom = 1;
      while ((max_width  > 0 && cinfo.output_width  > max_width) ||
             (max_height > 0 && cinfo.output_height > max_height)) {
        cinfo.scale_denom   <<= 1;
        cinfo.output_width  >>= 1;
        cinfo.output_height >>= 1;
      }
      if (cinfo.scale_denom > 1) {
        xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
                LOG_MODULE ": downscaling image by 1:%d to %dx%d\n",
                cinfo.scale_denom, cinfo.output_width, cinfo.output_height);
      }
    }

    /* start decompress */

    jpeg_start_decompress(&cinfo);

    width = cinfo.output_width;
    height = cinfo.output_height;

    /* crop when image is too large for vo */
    if (max_width > 0 && cinfo.output_width > max_width)
      width = max_width;
    if (max_height > 0 && cinfo.output_height > max_height)
      height = max_height;

    img = this->stream->video_out->get_frame (this->stream->video_out,
                                              width, height,
                                              (double)width/(double)height,
					      XINE_IMGFMT_YUY2,
    					      VO_BOTH_FIELDS);

    linesize = cinfo.output_width * cinfo.output_components;
    buffer = (cinfo.mem->alloc_sarray)((void*)&cinfo, JPOOL_IMAGE, linesize, 1);
    if (img->proc_slice && !(img->height & 0xf)) {
      slice_start[0] = img->base[0];
    }

    /* cut to frame width */
    if (cinfo.output_width > img->width) {
      lprintf("cut right border %d pixels\n", cinfo.output_width - img->width);
      linesize = img->width * 3;
    }

    /* YUV444->YUV422 simple */
    while (cinfo.output_scanline < cinfo.output_height) {
      uint8_t *dst = img->base[0] + img->pitches[0] * cinfo.output_scanline;

      jpeg_read_scanlines(&cinfo, buffer, 1);

      /* cut to frame height */
      if (cinfo.output_scanline > img->height) {
        lprintf("cut bottom scanline %d\n", cinfo.output_scanline - 1);
        continue;
      }

      for (i = 0; i < linesize; i += 3) {
        *dst++ = buffer[0][i];
        if (i & 1) {
          *dst++ = buffer[0][i + 2];
        } else {
          *dst++ = buffer[0][i + 1];
        }
      }

      if (slice_start[0]) {
        slice_line++;
        if (slice_line == 16) {
          img->proc_slice(img, slice_start);
          slice_start[0] += 16 * img->pitches[0];
          slice_line = 0;
        }
      }
    }

    /* final slice */
    if (slice_start[0] && slice_line) {
      img->proc_slice(img, slice_start);
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);

    img->pts       = buf->pts;
    img->duration  = 3600;
    img->bad_frame = 0;

    _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration);

    img->draw(img, this->stream);
    img->free(img);

    this->index = 0;
  }