]> rtime.felk.cvut.cz Git - frescor/demo.git/blobdiff - src/recorder/ffmpeg.c
recorder: Decrease CPU budget
[frescor/demo.git] / src / recorder / ffmpeg.c
index 99eda9cf67f941dde1a50044a57ac2b1f7f08f7b..d5b0c7f2d9793be5fd38e4b852e6b39ae248fd1f 100644 (file)
@@ -22,7 +22,7 @@
 /* needed for usleep() */
 #define _XOPEN_SOURCE 600
 
-#include "config.h"
+#include <ffmpeg-config.h>
 #include <ctype.h>
 #include <string.h>
 #include <math.h>
@@ -179,6 +179,8 @@ static int64_t start_time = 0;
 static int64_t rec_timestamp = 0;
 static int64_t input_ts_offset = 0;
 static int file_overwrite = 0;
+static int o_direct = 0;
+static const char *contract_label = "recorder";
 static int metadata_count;
 static AVMetadataTag *metadata;
 static int do_benchmark = 0;
@@ -1261,9 +1263,10 @@ static int output_packet(AVInputStream *ist, int ist_index,
                     data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2;
                     /* XXX: allocate picture correctly */
                     avcodec_get_frame_defaults(&picture);
-
                     ret = avcodec_decode_video2(ist->st->codec,
                                                 &picture, &got_picture, &avpkt);
+                   if (picture.key_frame)
+                           printf("*");
                     ist->st->quality= picture.quality;
                     if (ret < 0)
                         goto fail_decode;
@@ -1586,22 +1589,24 @@ timespec_subtract (struct timespec *result,
   return x->tv_sec < y->tv_sec;
 }
 
+#ifdef CONFIG_FFMPEG_WITH_FRSH
 frsh_vres_id_t disk_vres;
+frsh_contract_t cpu_contract;
 frsh_contract_t disk_contract;
-
+#endif
 
 static void
 print_timing(void)
 {
        static struct timespec start = {0,0};
        struct timespec end, d;
-       static int f = 0;       /* number of frames */
+       static int f = -1;      /* number interframe intevals elapsed */
        double ifi;
        static double ifi_avg=0, ifi_var=0;
 
        clock_gettime(CLOCK_MONOTONIC, &end);
        timespec_subtract(&d, &end, &start);
-       if (f++ == 0)
+       if (f++ < 0)
                goto out;       /* First run */
        ifi = (double)d.tv_sec + 1e-9*d.tv_nsec;
 #define SQ(x) ((x)*(x))        
@@ -1610,8 +1615,12 @@ print_timing(void)
        printf("%5d: interframe interval = 1/%5.2lf s  avg=1/%.2f  stddev=1/%3.2f\n",
               f, 1/ifi, 1/ifi_avg, 1/sqrt(ifi_var));
 
-       if (renegotiate == f)
+#ifdef CONFIG_FFMPEG_WITH_FRSH
+       if (renegotiate == f) {
                frsh_contract_renegotiate_sync(&disk_contract, disk_vres);
+               frsh_contract_renegotiate_sync(&disk_contract, disk_vres);
+       }
+#endif
 out:
        start = end;
 }
@@ -2886,6 +2895,11 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
     return codec->id;
 }
 
+static void opt_contract_label(const char *label)
+{
+    contract_label = label;
+}
+
 static void opt_input_file(const char *filename)
 {
     AVFormatContext *ic;
@@ -3502,10 +3516,22 @@ static void opt_output_file(const char *filename)
         }
 
         /* open the file */
-        if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
+        if (url_fopen(&oc->pb, filename, o_direct ? URL_RDWR|URL_DIRECT : URL_WRONLY) < 0) {
             fprintf(stderr, "Could not open '%s'\n", filename);
             av_exit(1);
         }
+
+       if (0) {
+               int i;
+               for (i=0; i<0x81; i++) {
+                       put_le32(oc->pb, i);
+                       if (i==0x42)
+                               put_flush_packet(oc->pb);
+               }
+               url_close_buf(oc->pb);
+               url_fclose(oc->pb);
+               exit(0);
+       }
     }
 
     memset(ap, 0, sizeof(*ap));
@@ -3881,6 +3907,8 @@ static const OptionDef options[] = {
     { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" },
     { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" },
     { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
+    { "contract_label", HAS_ARG, {(void*)opt_contract_label}, "contract label", "label" },
+    { "direct", OPT_BOOL, {(void*)&o_direct}, "write to output file using direct I/O (O_DIRECT)" },
     { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file:stream[:syncfile:syncstream]" },
     { "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "set meta data information of outfile from infile", "outfile:infile" },
     { "t", OPT_FUNC2 | HAS_ARG, {(void*)opt_recording_time}, "record or transcode \"duration\" seconds of audio/video", "duration" },
@@ -4000,7 +4028,6 @@ static const OptionDef options[] = {
 };
 
 #ifdef CONFIG_FFMPEG_WITH_FRSH
-
 void *av_encode_thread(void *arg)
 {
     int ret, terror;
@@ -4008,7 +4035,7 @@ void *av_encode_thread(void *arg)
 
     /* bind this thread to vres */
     thread_id = fosa_thread_self();
-    /* PXW(frsh_thread_bind(disk_vres, thread_id)); */
+    PXW(frsh_thread_bind(disk_vres, thread_id));
 
     ret = av_encode(output_files, nb_output_files,
                    input_files, nb_input_files,
@@ -4021,23 +4048,23 @@ int frsh_stuff()
     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;
 
     frsh_rel_time_t disk_budget, disk_period;
 
-    int ret, terror;
+    int ret;
 
-    PXW(frsh_init());
     cpu_budget = fosa_msec_to_rel_time(5);
-    cpu_period = fosa_msec_to_rel_time(1000/50);
+    cpu_period = fosa_msec_to_rel_time(1000/30);
 
-/* #define DISK_THROUGHPUT 20277LLU /\* units??? probably MB/s *\/ */
-/*     disk_budget = fosa_nsec_to_rel_time(1000000000LLU/\*nsec/s*\/ * 500000 /\*bytes/s*\/ */
-/*                                     / (DISK_THROUGHPUT*1000000) /\* bytes *\/); // is this correct? */
+#if 1
+#define DISK_THROUGHPUT 20277LLU /* units??? probably MB/s */
+    disk_budget = fosa_nsec_to_rel_time(1000000000LLU/*nsec/s*/ * 500000 /*bytes/s*/
+                                       / (DISK_THROUGHPUT*1000000) /* bytes */); // is this correct?
+#else
     disk_budget = fosa_msec_to_rel_time(1);
-    disk_period = fosa_msec_to_rel_time(1000/50);
+#endif
+    disk_period = fosa_msec_to_rel_time(1000/30);
     
     /* Contract negotiation for CPU */
     ret = frsh_contract_init(&cpu_contract);
@@ -4050,7 +4077,7 @@ int frsh_stuff()
                                         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, "recorder");
+                                              FRSH_RT_PROCESSOR, FRSH_CPU_ID_DEFAULT, contract_label);
     if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
 
     ret = frsh_contract_negotiate(&cpu_contract, &cpu_vres);
@@ -4068,7 +4095,8 @@ int frsh_stuff()
                                         FRSH_CT_REGULAR);
     if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
     ret = frsh_contract_set_resource_and_label(&disk_contract, 
-                                              FRSH_RT_DISK, 0, output_files[0]->filename);
+                                              FRSH_RT_DISK, 0, strstr(output_files[0]->filename, "://") == NULL ?
+                                              output_files[0]->filename : input_files[0]->filename);
     if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
 
     ret = frsh_contract_negotiate(&disk_contract, &disk_vres);
@@ -4085,6 +4113,7 @@ int frsh_stuff()
     printf("Ending contracts\n");
 
     ret = frsh_contract_cancel(cpu_vres);
+    ret = frsh_contract_cancel(disk_vres);
     if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
 
     printf("Finishing\n");
@@ -4122,6 +4151,14 @@ int main(int argc, char **argv)
 
     show_banner();
 
+#if CONFIG_FFMPEG_WITH_FRSH
+    {
+       int terror;
+       PXW(frsh_init());
+       printf("FRSH initialized\n");
+    }
+#endif
+
     /* parse options */
     parse_options(argc, argv, options, opt_output_file);