-#include "libavformat/avformat.h"
-#include "libavdevice/avdevice.h"
+/*
+ * Copyright (c) 2008 Luca Abeni
+ *
+ * This is free software; see GPL.txt
+ */
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <libavformat/avformat.h>
+#include <libavdevice/avdevice.h>
+#include <libswscale/swscale.h>
#include "input.h"
#include "output.h"
#include "codec.h"
#include "rt.h"
-static void sdp_print(AVFormatContext *s)
+#include "streamer_config.h"
+
+#ifdef CONFIG_OC_ULUT
+#include <ul_log.h>
+#include <ul_logreg.h>
+#endif
+
+#ifdef CONFIG_STREAMER_WITH_FRSH
+#include <frsh.h>
+#endif
+
+#ifdef CONFIG_STREAMER_WITH_FRSH
+/*temporrary solution to pass network parameters */
+extern long int udp_budget, udp_period;
+#endif /*CONFIG_STREAMER_WITH_FRSH*/
+
+static const char *sdp_file = "sdp.txt";
+static const char *vdev = "/dev/video0";
+static const char *dst = "127.0.0.1";
+static int dport = 20000;
+static int width = 352;
+static int height = 288;
+int fps = 25;
+static const char *impform = "video4linux2";
+AVFormatContext *s, *os;
+
+static void sdp_print(AVFormatContext *s, const char *fname)
{
char sdp[2048];
FILE *f;
- f = fopen("sdp.txt", "w");
+ f = fopen(fname, "w");
avf_sdp_create(&s, 1, sdp, sizeof(sdp));
fprintf(f, "%s\n", sdp);
fclose(f);
}
+static void
+usage(void)
+{
+ printf("usage: streamer [ options ]\n");
+ printf(" -w <number> send image width\n");
+ printf(" -h <number> send image height\n");
+ printf(" -r <number> refresh rate\n");
+ printf(" -r <path> video device [%s]\n", vdev);
+ printf(" -m <addr> destination IP address\n");
+ printf(" -i <string> input video device format [%s]\n", impform);
+ #ifdef CONFIG_STREAMER_WITH_FRSH
+ printf(" -b <number> network budget\n");
+ printf(" -p <number> network period for given budget\n");
+ #endif /*CONFIG_STREAMER_WITH_FRSH*/
+ #ifdef CONFIG_OC_ULUT
+ printf(" -l <number>|<domain>=<number>,...\n");
+ #endif /*CONFIG_OC_ULUT*/
+}
-int main(int argc, char *argv[])
+static int args_parse(int argc, char *argv[])
{
- AVFormatContext *s, *os;
- int done;
+ int v;
- avcodec_register_all();
- av_register_all();
- avdevice_register_all();
+ while ((v = getopt(argc, argv, "w:h:r:d:m:i:l:b:p:")) >= 0) {
+ switch (v) {
+ case 'w':
+ width = atoi(optarg);
+ break;
+ case 'h':
+ height = atoi(optarg);
+ break;
+ case 'r':
+ fps = atoi(optarg);
+ break;
+ case 'd':
+ vdev = optarg;
+ break;
+ case 'm':
+ dst = optarg;
+ break;
+ case 'i':
+ impform = optarg;
+ if(!strcmp(impform, "v4l"))
+ impform = "video4linux";
+ else if(!strcmp(impform, "v4l2"))
+ impform = "video4linux2";
+ break;
+ #ifdef CONFIG_STREAMER_WITH_FRSH
+ case 'b':
+ udp_budget = atol(optarg);
+ break;
+ case 'p':
+ udp_period = atol(optarg);
+ break;
+ #endif /*CONFIG_STREAMER_WITH_FRSH*/
- s = open_input_stream(argv[1]);
- if (s == NULL) {
- fprintf(stderr, "Cannot open input file %s\n", argv[1]);
+ #ifdef CONFIG_OC_ULUT
+ case 'l':
+ ul_log_domain_arg2levels(optarg);
+ break;
+ #endif /*CONFIG_OC_ULUT*/
- return -1;
+ default: /* unknown option */
+ fprintf(stderr, "%s: illegal option %c\n", argv[0], v);
+ usage();
+ exit(-1);
+ }
}
- codec_open(s);
- os = open_output_stream("224.10.20.30", 20000, CODEC_TYPE_VIDEO);
- if (os == NULL) {
- fprintf(stderr, "Cannot open output stream\n");
- return -1;
- }
- os->streams[0]->codec->width = s->streams[0]->codec->width;
- os->streams[0]->codec->height = s->streams[0]->codec->height;
- os->streams[0]->codec->time_base = s->streams[0]->codec->time_base;
- codec_connect(s->streams[0]->codec, os->streams[0]->codec);
- out_codec_open(os);
- dump_format(os, 0, os->filename, 1);
- sdp_print(os);
+ return 0;
+}
+
+int streamer_run_done_rq;
+
+void* streamer_run(void* args)
+{
+ int done;
+
done = 0;
- while (!done) {
+ while (!(done = streamer_run_done_rq)) {
AVPacket *pkt;
pkt = read_input_packet(s);
if (pkt == NULL) {
AVPacket *opkt;
pkt->pts += s->streams[pkt->stream_index]->start_time;
- rt_job_start(pkt->pts);
+ //rt_job_start(pkt->pts);
f = pkt_decode(s, pkt);
if (f) {
opkt = pkt_encode(os, f);
pkt_send(os, opkt);
}
}
- rt_job_end();
+ //rt_job_end();
av_free_packet(pkt);
}
}
+ return NULL;
+}
+
+void wait_for_ending_command(void) {
+ sigset_t sigset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGTERM);
+ sigwaitinfo(&sigset, NULL);
+}
+static void block_signals(void) {
+ sigset_t sigset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGTERM);
+ sigprocmask(SIG_BLOCK,&sigset,NULL);
+ pthread_sigmask(SIG_BLOCK,&sigset,NULL);
+}
+
+
+int main(int argc, char *argv[])
+{
+
+ //long int cpu_budget, cpu_period;
+ int ret;
+
+ block_signals();
+
+#ifdef CONFIG_STREAMER_WITH_FRSH
+ ret = frsh_init();
+ if (ret) PERROR_AND_EXIT(ret, "frsh_init1");
+
+ /* fill default network contract params */
+ udp_budget = 50000;
+ udp_period = 500;
+#endif /*CONFIG_STREAMER_WITH_FRSH*/
+
+ avcodec_register_all();
+ av_register_all();
+ avdevice_register_all();
+
+ args_parse(argc, argv);
+
+ s = open_input_stream(vdev, width, height, fps, impform);
+ if (s == NULL) {
+ fprintf(stderr, "Cannot open input file %s\n", vdev);
+
+ return -1;
+ }
+ codec_open(s);
+ os = open_output_stream(dst, dport, CODEC_TYPE_VIDEO);
+ if (os == NULL) {
+ fprintf(stderr, "Cannot open output stream\n");
+
+ return -1;
+ }
+ os->streams[0]->codec->width = s->streams[0]->codec->width;
+ os->streams[0]->codec->height = s->streams[0]->codec->height;
+ os->streams[0]->codec->time_base = s->streams[0]->codec->time_base;
+ codec_connect(s->streams[0]->codec, os->streams[0]->codec);
+ out_codec_open(os);
+ dump_format(os, 0, os->filename, 1);
+ sdp_print(os, sdp_file);
+
+#ifdef CONFIG_AQUOSA
+ frsh_thread_attr_t frsh_attr;
+ frsh_thread_id_t thread;
+ frsh_vres_id_t cpu_vres;
+ frsh_contract_t cpu_contract;
+ frsh_rel_time_t cpu_budget, cpu_period;
+
+ cpu_budget = fosa_msec_to_rel_time(50);
+ cpu_period = fosa_msec_to_rel_time(100);
+ /* Contract negotiation for CPU */
+ ret = frsh_contract_init(&cpu_contract);
+ if (ret) PERROR_AND_EXIT(ret, "CPU:frsh_contract_init");
+
+ ret = frsh_contract_set_basic_params(&cpu_contract,
+ &cpu_budget,
+ &cpu_period,
+ FRSH_WT_BOUNDED,
+ FRSH_CT_REGULAR);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
+ ret = frsh_contract_set_resource_and_label(&cpu_contract,
+ FRSH_RT_PROCESSOR, FRSH_CPU_ID_DEFAULT, "aqcpu_cont");
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
+
+ ret = frsh_contract_negotiate(&cpu_contract, &cpu_vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
+ printf("Aqcpu vres negotiated\n");
+
+ pthread_attr_init(&frsh_attr);
+ ret = frsh_thread_create_and_bind(cpu_vres, &thread, &frsh_attr,
+ streamer_run, (void*) NULL);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
+
+ wait_for_ending_command();
+
+ streamer_run_done_rq = 1;
+
+ pthread_join(thread.pthread_id, (void**) NULL);
+
+ printf("Ending contracts\n");
+
+ ret = frsh_contract_cancel(cpu_vres);
+ if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+
+ printf("Finishing\n");
+
+ close_output_stream(os);
+#else
+ pthread_attr_t attr;
+ pthread_t streamer_th;
+
+ pthread_attr_init(&attr);
+
+ ret = pthread_create(&streamer_th, &attr, streamer_run, (void*) NULL);
+ if (ret)
+ printf("Failed to create streamer thread\n.");
+
+ wait_for_ending_command();
+
+ streamer_run_done_rq = 1;
+
+ pthread_join(streamer_th, (void**) NULL);
+
+ printf("Finishing\n");
+
+ close_output_stream(os);
+#endif
+
return 0;
}