diff --git a/doc/ffserver.conf b/doc/ffserver.conf index 7aa87aeb16f0bae7cd359e013cb138c7db323798..15637efd752a9ed5c7962c773c083eb2fe552391 100644 --- a/doc/ffserver.conf +++ b/doc/ffserver.conf @@ -46,6 +46,10 @@ NoDaemon File /tmp/feed1.ffm FileMaxSize 200K +# You could specify +# ReadOnlyFile /saved/specialvideo.ffm +# This marks the file as readonly and it will not be deleted or updated + # Specify launch in order to start ffmpeg automatically #Launch @@ -110,6 +114,10 @@ VideoSize 160x128 # frames Video synchronization can only begin at an I frames. VideoGopSize 12 +# More MPEG4 parameters +# VideoHighQuality +# Video4MotionVector + # Choose your codecs: #AudioCodec mp2 #VideoCodec mpeg1video diff --git a/ffserver.c b/ffserver.c index e55169e164301299aa9877341b002d434a77a771..8b220b48f60d7fb2bc0bc2adc3027ec21b567b82 100644 --- a/ffserver.c +++ b/ffserver.c @@ -208,6 +208,7 @@ typedef struct FFStream { /* feed specific */ int feed_opened; /* true if someone is writing to the feed */ int is_feed; /* true if it is a feed */ + int readonly; /* True if writing is prohibited to the file */ int conns_served; int64_t bytes_served; int64_t feed_max_size; /* maximum storage size */ @@ -2389,6 +2390,10 @@ static int http_start_receive_data(HTTPContext *c) if (c->stream->feed_opened) return -1; + /* Don't permit writing to this one */ + if (c->stream->readonly) + return -1; + /* open feed */ fd = open(c->stream->feed_filename, O_RDWR); if (fd < 0) @@ -3455,12 +3460,24 @@ static void build_feed_streams(void) printf("Deleting feed file '%s' as it appears to be corrupt\n", feed->feed_filename); } - if (!matches) + if (!matches) { + if (feed->readonly) { + printf("Unable to delete feed file '%s' as it is marked readonly\n", + feed->feed_filename); + exit(1); + } unlink(feed->feed_filename); + } } if (!url_exist(feed->feed_filename)) { AVFormatContext s1, *s = &s1; + if (feed->readonly) { + printf("Unable to create feed file '%s' as it is marked readonly\n", + feed->feed_filename); + exit(1); + } + /* only write the header of the ffm file */ if (url_fopen(&s->pb, feed->feed_filename, URL_WRONLY) < 0) { fprintf(stderr, "Could not open output feed file '%s'\n", @@ -3815,6 +3832,13 @@ static int parse_ffconfig(const char *filename) snprintf(feed->child_argv[i], 256, "http://127.0.0.1:%d/%s", ntohs(my_http_addr.sin_port), feed->filename); } + } else if (!strcasecmp(cmd, "ReadOnlyFile")) { + if (feed) { + get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); + feed->readonly = 1; + } else if (stream) { + get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); + } } else if (!strcasecmp(cmd, "File")) { if (feed) { get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); @@ -4053,6 +4077,11 @@ static int parse_ffconfig(const char *filename) if (stream) { video_enc.flags |= CODEC_FLAG_HQ; } + } else if (!strcasecmp(cmd, "Video4MotionVector")) { + if (stream) { + video_enc.flags |= CODEC_FLAG_HQ; + video_enc.flags |= CODEC_FLAG_4MV; + } } else if (!strcasecmp(cmd, "VideoQDiff")) { get_arg(arg, sizeof(arg), &p); if (stream) {