From c259a69c7e75f29d45fd0bbf47899d15e71e2e79 Mon Sep 17 00:00:00 2001
From: Llorx <dallorx@gmail.com>
Date: Sat, 6 Aug 2016 14:34:50 +0200
Subject: [PATCH] Bitrate on-the-fly PoC

---
 ffmpeg.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index e1d1e63..57fa3aa 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -32,6 +32,16 @@
 #include <limits.h>
 #include <stdint.h>
 
+#ifdef _WIN32
+	#include <winsock2.h>
+	#include <fcntl.h>
+#else
+	#include <sys/socket.h>
+	#include <netinet/in.h>
+	#include <stdio.h>
+	#include <arpa/inet.h>
+#endif
+
 #if HAVE_IO_H
 #include <io.h>
 #endif
@@ -106,6 +116,12 @@
 
 #include "libavutil/avassert.h"
 
+#ifdef _WIN32
+	SOCKET sockfd;
+#else
+	int sockfd;
+#endif
+
 const char program_name[] = "ffmpeg";
 const int program_birth_year = 2000;
 
@@ -4145,6 +4161,12 @@ static int transcode(void)
         goto fail;
 #endif
 
+	char socket_data[4];
+	int data;
+	uint32_t bitrate;
+	OutputStream *enc_ost;
+	AVCodecContext *enc_ctx;
+	
     while (!received_sigterm) {
         int64_t cur_time= av_gettime_relative();
 
@@ -4159,6 +4181,25 @@ static int transcode(void)
             break;
         }
 
+		data = recvfrom(sockfd, socket_data, 4, 0, NULL, NULL);
+		if (data >= 4) {
+			bitrate = *((uint32_t*)socket_data);
+			for (i = 0; i < nb_output_streams; i++) {
+				enc_ost = output_streams[i];
+
+				if (enc_ost->attachment_filename)
+					continue;
+
+				enc_ctx = enc_ost->stream_copy ? enc_ost->st->codec : enc_ost->enc_ctx;
+				if (enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+					enc_ctx->bit_rate = bitrate;
+					enc_ctx->rc_max_rate = bitrate;
+					enc_ctx->rc_buffer_size = bitrate/2;
+				}
+			}
+			av_log(NULL, AV_LOG_INFO, "New bitrate: %d\n", bitrate);
+		}
+		
         ret = transcode_step();
         if (ret < 0 && ret != AVERROR_EOF) {
             char errbuf[128];
@@ -4297,7 +4338,37 @@ static int64_t getmaxrss(void)
 static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl)
 {
 }
-
+static void start_bitrate_server() {
+	struct sockaddr_in servaddr;
+	#ifdef _WIN32
+		u_long iMode;
+		WSADATA wsa;
+		if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) {
+			printf("Failed. Error Code : %d",WSAGetLastError());
+			exit(EXIT_FAILURE);
+		}
+	#else
+		int nonBlocking;
+	#endif
+	if((sockfd = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET) {
+		printf("Could not create socket : %d" , WSAGetLastError());
+	}
+	servaddr.sin_family = AF_INET;
+	servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
+	servaddr.sin_port = htons( 32000 );
+	bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
+	#ifdef _WIN32
+		iMode = 1;
+		ioctlsocket(sockfd, FIONBIO, &iMode);
+	#else
+		nonBlocking = 1;
+		if (fcntl(sockfd, F_SETFL, O_NONBLOCK, nonBlocking) == -1) {
+			printf( "failed to set non-blocking socket\n" );
+			exit(1);
+		}
+	#endif
+	av_log(NULL, AV_LOG_INFO, "Created socket\n");
+}
 int main(int argc, char **argv)
 {
     int ret;
@@ -4351,6 +4422,8 @@ int main(int argc, char **argv)
 //         exit_program(1);
 //     }
 
+	start_bitrate_server();
+
     current_time = ti = getutime();
     if (transcode() < 0)
         exit_program(1);
-- 
2.9.2.windows.1