Ejemplo n.º 1
0
std::unique_ptr<Reply> M4Handler::HandleMessage(Message* message) {
  SinkMediaManager* sink_media_manager = ToSinkMediaManager(manager_);
  auto payload = ToPropertyMapPayload(message->payload());
  if (!payload) {
    WDS_ERROR("Failed to obtain payload in M4 handler.");
    return nullptr;
  }

  auto presentation_url =
      static_cast<rtsp::PresentationUrl*>(payload->GetProperty(rtsp::PresentationURLPropertyType).get());
  if (presentation_url) {
    sink_media_manager->SetPresentationUrl(presentation_url->presentation_url_1());
  }

  auto video_formats =
      static_cast<rtsp::VideoFormats*>(payload->GetProperty(rtsp::VideoFormatsPropertyType).get());

  if (!video_formats) {
    WDS_ERROR("Failed to obtain 'wfd-video-formats' in M4 handler.");
    return nullptr;
  }

  const auto& selected_formats = video_formats->GetH264Formats();
  if (selected_formats.size() != 1) {
    WDS_ERROR("Failed to obtain optimal video format from 'wfd-video-formats' in M4 handler.");
    return nullptr;
  }

  if (!sink_media_manager->SetOptimalVideoFormat(selected_formats[0])) {
    auto reply = std::unique_ptr<Reply>(new Reply(rtsp::STATUS_SeeOther));
    auto payload = new rtsp::PropertyErrorPayload();
    std::vector<unsigned short> error_codes = {rtsp::STATUS_UnsupportedMediaType};
    auto property_errors =
        std::make_shared<rtsp::PropertyErrors>(rtsp::VideoFormatsPropertyType, error_codes);
    payload->AddPropertyError(property_errors);
    reply->set_payload(std::unique_ptr<rtsp::Payload>(payload));
    return reply;
  }

  return std::unique_ptr<Reply>(new Reply(rtsp::STATUS_OK));
}
Ejemplo n.º 2
0
H264VideoFormat FindOptimalVideoFormat(
    const NativeVideoFormat& native,
    const std::vector<H264VideoCodec>& local_codecs,
    const std::vector<H264VideoCodec>& remote_codecs,
    bool* success) {
  std::vector<H264VideoFormat> local_formats, remote_formats;
  for (const auto& codec : local_codecs)
    PopulateVideoFormatList(codec, local_formats);
  for (const auto& codec : remote_codecs)
    PopulateVideoFormatList(codec, remote_formats);

  std::sort(local_formats.begin(), local_formats.end(),
      video_format_sort_func);
  std::sort(remote_formats.begin(), remote_formats.end(),
      video_format_sort_func);

  auto it = local_formats.begin();
  auto end = local_formats.end();

  H264VideoFormat format(CBP,
      k3_1, CEA640x480p60);

  while(it != end) {
    auto match = std::find(
        remote_formats.begin(),
        remote_formats.end(),
        *it);

    if (match != remote_formats.end()) {
      format = *match;
      break;
    }
    ++it;
  }

  // Should not happen, 640x480p60 should be always supported!
  if (it == end) {
    WDS_ERROR("Failed to find compatible video format.");
    if (success)
      *success = false;
    return format;
  }

  // if remote device supports higher codec profile / level
  // downgrade them to what we support locally.
  if (format.profile > (*it).profile)
    format.profile = (*it).profile;
  if (format.level > (*it).level)
    format.level = (*it).level;
  if (success)
    *success = true;
  return format;
}
Ejemplo n.º 3
0
  std::unique_ptr<Reply> HandleMessage(Message* message) override {
    auto payload = ToPropertyMapPayload(message->payload());
    if (!payload) {
      WDS_ERROR("Failed to obtain payload in M5 handler.");
      return nullptr;
    }
    auto property =
        static_cast<rtsp::TriggerMethod*>(payload->GetProperty(rtsp::TriggerMethodPropertyType).get());

    auto reply = std::unique_ptr<Reply>(new Reply(rtsp::STATUS_OK));
    reply->header().set_cseq(message->cseq());
    if (property->method() != rtsp::TriggerMethod::SETUP) {
      reply->set_response_code(rtsp::STATUS_SeeOther);
    }

    return reply;
  }
Ejemplo n.º 4
0
int main (int argc, char *argv[])
{
    InitGlibLogging();

    GError *error = NULL;
    GOptionContext *context;
    GMainLoop* ml = NULL;
    
    gchar* wfd_device_option = NULL;
    gchar* wfd_stream_option = NULL;
    gchar* hostname_option = NULL;
    gint port = 0;
    
    GOptionEntry main_entries[] =
    {
        { "device", 0, 0, G_OPTION_ARG_STRING, &wfd_device_option, "Specify WFD device type: testsource or sink", "(testsource|sink)"},
        { "stream", 0, 0, G_OPTION_ARG_STRING, &wfd_stream_option, "Specify WFD stream type for testsource: audio, video, both or desktop capture", "(audio|video|both|desktop)"},
        { "hostname", 0, 0, G_OPTION_ARG_STRING, &hostname_option, "Specify optional hostname or ip address to stream to or listen on", "host"},
        { "port", 0, 0, G_OPTION_ARG_INT, &port, "Specify optional UDP port number to stream to or listen on", "port"},
        { NULL }
    };

    context = g_option_context_new ("- WFD source/sink demo application\n\nExample:\ngst-test --device=testsource --stream=both --hostname=127.0.0.1 --port=5000\ngst-test --device=sink --port=5000");
    g_option_context_add_main_entries (context, main_entries, NULL);
    
   if (!g_option_context_parse (context, &argc, &argv, &error)) {
        WDS_ERROR ("option parsing failed: %s", error->message);
        g_option_context_free(context);
        exit (1);
    }
    g_option_context_free(context);

    wfd_test_stream_t wfd_stream = WFD_UNKNOWN_STREAM;
    if (g_strcmp0(wfd_stream_option, "audio") == 0)
        wfd_stream = WFD_TEST_AUDIO;
    else if (g_strcmp0(wfd_stream_option, "video") == 0)
        wfd_stream = WFD_TEST_VIDEO;
    else if (g_strcmp0(wfd_stream_option, "both") == 0)
        wfd_stream = WFD_TEST_BOTH;
    else if (g_strcmp0(wfd_stream_option, "desktop") == 0)
        wfd_stream = WFD_DESKTOP;

    std::string hostname;
    if (hostname_option)
        hostname = hostname_option;

    g_free(wfd_stream_option);
    g_free(hostname_option);

    gst_init (&argc, &argv);

    std::unique_ptr<MiracGstSink> sink_pipeline;
    std::unique_ptr<MiracGstTestSource> source_pipeline;

    if (g_strcmp0(wfd_device_option, "testsource") == 0) {
        source_pipeline.reset(new MiracGstTestSource(wfd_stream, hostname, port));
        source_pipeline->SetState(GST_STATE_PLAYING);
        WDS_LOG("Source UDP port: %d", source_pipeline->UdpSourcePort());
    } else if (g_strcmp0(wfd_device_option, "sink") == 0) {
        sink_pipeline.reset(new MiracGstSink(hostname, port));
        WDS_LOG("Listening on port %d", sink_pipeline->sink_udp_port());
    }

    g_free(wfd_device_option);

    ml = g_main_loop_new(NULL, TRUE);
    g_unix_signal_add(SIGINT, _sig_handler, ml);
    g_unix_signal_add(SIGTERM, _sig_handler, ml);

    g_main_loop_run(ml);

    g_main_loop_unref(ml);
    
    return 0;
}