1 /*
2  * Copyright 2013-2016, Björn Ståhl
3  * License: 3-Clause BSD, see COPYING file in arcan source repository.
4  * Reference: http://arcan-fe.com
5  */
6 
7 #include <libavcodec/avcodec.h>
8 #include <libavformat/avformat.h>
9 #include <libavformat/avio.h>
10 #include <libavutil/imgutils.h>
11 
12 #include <sys/stat.h>
13 #include <assert.h>
14 #include <stdbool.h>
15 #include <stdint.h>
16 #include <unistd.h>
17 
18 #include <arcan_shmif.h>
19 #include "frameserver.h"
20 #include "encode_presets.h"
21 
vcodec_defaults(struct codec_ent * dst,unsigned width,unsigned height,float fps,unsigned vbr)22 static void vcodec_defaults(struct codec_ent* dst, unsigned width,
23 	unsigned height, float fps, unsigned vbr)
24 {
25 	AVCodecContext* ctx   = dst->storage.video.context;
26 
27 	ctx->width     = width;
28 	ctx->height    = height;
29 	ctx->bit_rate  = vbr;
30 	ctx->pix_fmt   = AV_PIX_FMT_YUV420P;
31 	ctx->gop_size  = 12;
32 	ctx->time_base.den = fps;
33 	ctx->time_base.num = 1;
34 
35 	AVFrame* pframe = av_frame_alloc();
36 	pframe->width = width;
37 	pframe->height = height;
38 	pframe->format = ctx->pix_fmt;
39 	av_image_alloc(pframe->data, pframe->linesize,
40 		width, height, ctx->pix_fmt, 32);
41 
42 	dst->storage.video.pframe = pframe;
43 }
44 
default_vcodec_setup(struct codec_ent * dst,unsigned width,unsigned height,float fps,unsigned vbr,bool stream)45 static bool default_vcodec_setup(struct codec_ent* dst, unsigned width,
46 	unsigned height, float fps, unsigned vbr, bool stream)
47 {
48 	AVCodecContext* ctx = dst->storage.video.context;
49 
50 	assert(width % 2 == 0);
51 	assert(height % 2 == 0);
52 	assert(fps > 0 && fps <= 60);
53 	assert(ctx);
54 
55 	vcodec_defaults(dst, width, height, fps, vbr);
56 /* terrible */
57 	if (vbr <= 10){
58 		vbr = 150 * 1024;
59 	}
60 
61 	ctx->bit_rate = vbr;
62 
63 	if (avcodec_open2(dst->storage.video.context,
64 		dst->storage.video.codec, NULL) != 0){
65 		dst->storage.video.codec   = NULL;
66 		dst->storage.video.context = NULL;
67 		avcodec_close(dst->storage.video.context);
68 		return false;
69 	}
70 
71 	return true;
72 }
73 
default_acodec_setup(struct codec_ent * dst,unsigned channels,unsigned samplerate,unsigned abr)74 static bool default_acodec_setup(struct codec_ent* dst, unsigned channels,
75 	unsigned samplerate, unsigned abr)
76 {
77 	AVCodecContext* ctx = dst->storage.audio.context;
78 	AVCodec* codec = dst->storage.audio.codec;
79 
80 	assert(channels == 2);
81 	assert(samplerate > 0 && samplerate <= 48000);
82 	assert(codec);
83 
84 	ctx->channels       = channels;
85 	ctx->channel_layout = av_get_default_channel_layout(channels);
86 
87 	ctx->sample_rate    = samplerate;
88 	ctx->time_base      = av_d2q(1.0 / (double) samplerate, 1000000);
89 	ctx->sample_fmt     = codec->sample_fmts[0];
90 
91 /* kept for documentation, now we assume the swr_convert just
92  * handles all sample formats for us,
93  * if we prefer or require a certain on in the future, the following code
94  * shows how:
95 	for (int i = 0; codec->sample_fmts[i] != -1 && ctx->sample_fmt ==
96 	AV_SAMPLE_FMT_NONE; i++){
97 		if (codec->sample_fmts[i] == AV_SAMPLE_FMT_S16 ||
98 		codec->sample_fmts[i] == AV_SAMPLE_FMT_FLTP)
99 			ctx->sample_fmt = codec->sample_fmts[i];
100 	}
101 
102 	if (ctx->sample_fmt == AV_SAMPLE_FMT_NONE){
103 		LOG("(encoder) Couldn't find supported matching sample format for
104 		codec, giving up.\n");
105 		return false;
106 	}
107 */
108 
109 /* rough quality estimate */
110 	if (abr <= 10)
111 		ctx->bit_rate = 1024 * ( 320 - 240 * ((float)(11.0 - abr) / 11.0) );
112 	else
113 		ctx->bit_rate = abr;
114 
115 /* AAC may need this */
116 	ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
117 
118 	LOG("(encode) audio encoder setup @ %d hz, requested quality: %d, "
119 		"got %d kbit/s using %s\n", samplerate, abr,
120 		(int)(ctx->bit_rate / 1000), codec->name);
121 
122 	if (avcodec_open2(dst->storage.audio.context,
123 		dst->storage.audio.codec, NULL) != 0){
124 		avcodec_close(dst->storage.audio.context);
125 		dst->storage.audio.context = NULL;
126 		dst->storage.audio.codec   = NULL;
127 		return false;
128 	}
129 
130 	return true;
131 }
132 
default_format_setup(struct codec_ent * dst)133 static bool default_format_setup(struct codec_ent* dst)
134 {
135 	int rc = avformat_write_header(dst->storage.container.context, NULL);
136 	LOG("(encode) header status (%d)\n", rc);
137 	return rc == 0;
138 }
139 
setup_cb_x264(struct codec_ent * dst,unsigned width,unsigned height,float fps,unsigned vbr,bool stream)140 static bool setup_cb_x264(struct codec_ent* dst, unsigned width,
141 	unsigned height, float fps, unsigned vbr, bool stream)
142 {
143 	AVDictionary* opts = NULL;
144 	float vbrf = 1000 * (height >= 720 ? 2.0 : 1.0);
145 
146 	vcodec_defaults(dst, width, height, fps, vbr);
147 	if (vbr == 10){
148 		av_dict_set(&opts, "preset", "medium", 0);
149 		av_dict_set(&opts, "crf", "4", 0);
150 		vbr = vbrf * 1200;
151 	} else if (vbr == 9){
152 		av_dict_set(&opts, "preset", "medium", 0);
153 		av_dict_set(&opts, "crf", "8", 0);
154 		vbr = vbrf * 1100;
155 	} else if (vbr == 8){
156 		av_dict_set(&opts, "preset", "medium", 0);
157 		av_dict_set(&opts, "crf", "14", 0);
158 		vbr = vbrf * 1000;
159 	} else if (vbr == 7){
160 		av_dict_set(&opts, "preset", "medium", 0);
161 		av_dict_set(&opts, "crf", "18", 0);
162 		vbr = vbrf * 900;
163 	} else if (vbr == 6){
164 		av_dict_set(&opts, "preset", "fast", 0	);
165 		av_dict_set(&opts, "crf", "22", 0);
166 		vbr = vbrf * 800;
167 	} else if (vbr == 5){
168 		av_dict_set(&opts, "preset", "fast", 0	);
169 		av_dict_set(&opts, "crf", "24", 0);
170 		vbr = vbrf * 700;
171 	} else if (vbr == 4){
172 		av_dict_set(&opts, "preset", "faster", 0);
173 		av_dict_set(&opts, "crf", "26", 0);
174 		vbr = vbrf * 600;
175 	} else if (vbr == 3){
176 		av_dict_set(&opts, "preset", "faster", 0	);
177 		av_dict_set(&opts, "crf", "32", 0);
178 		vbr = vbrf * 550;
179 	} else if (vbr == 2){
180 		av_dict_set(&opts, "preset", "superfast", 0);
181 		av_dict_set(&opts, "crf", "36", 0);
182 		vbr = vbrf * 400;
183 	} else if (vbr == 1){
184 		av_dict_set(&opts, "preset", "superfast", 0);
185 		av_dict_set(&opts, "crf", "44", 0);
186 		vbr = vbrf * 350;
187 	} else if (vbr == 0){
188 		av_dict_set(&opts, "preset", "superfast", 0);
189 		av_dict_set(&opts, "crf", "48", 0);
190 		vbr = vbrf * 300;
191 	} else {
192 		av_dict_set(&opts, "preset", "medium", 0);
193 		av_dict_set(&opts, "crf", "25", 0);
194 	}
195 
196 	if (stream)
197 		av_dict_set(&opts, "preset", "faster", 0);
198 
199 	dst->storage.video.context->bit_rate = vbr;
200 
201 	LOG("(encode) video setup @ %d * %d, %f fps, %d kbit / s.\n",
202 		width, height, fps, vbr / 1000);
203 
204 	if (avcodec_open2(dst->storage.video.context,
205 		dst->storage.video.codec, &opts) != 0){
206 		avcodec_close(dst->storage.video.context);
207 		dst->storage.video.context = NULL;
208 		dst->storage.video.codec   = NULL;
209 		return false;
210 	}
211 
212 	return true;
213 }
214 
215 /* would be nice with some decent evaluation of all the parameters and
216  * their actual cost / benefit. */
setup_cb_vp8(struct codec_ent * dst,unsigned width,unsigned height,float fps,unsigned vbr,bool stream)217 static bool setup_cb_vp8(struct codec_ent* dst, unsigned width,
218 	unsigned height, float fps, unsigned vbr, bool stream)
219 {
220 	AVDictionary* opts = NULL;
221 	const char* const lif = fps > 30.0 ? "25" : "16";
222 
223 	vcodec_defaults(dst, width, height, fps, vbr);
224 
225 /* options we want to set irrespective of bitrate */
226 	if (height > 720){
227 		av_dict_set(&opts, "slices", "4", 0);
228 		av_dict_set(&opts, "qmax", "54", 0);
229 		av_dict_set(&opts, "qmin", "11", 0);
230 		av_dict_set(&opts, "vprofile", "1", 0);
231 
232 	} else if (height > 480){
233 		av_dict_set(&opts, "slices", "4", 0);
234 		av_dict_set(&opts, "qmax", "54", 0);
235 		av_dict_set(&opts, "qmin", "11", 0);
236 		av_dict_set(&opts, "vprofile", "1", 0);
237 
238 	} else if (height > 360){
239 		av_dict_set(&opts, "slices", "4", 0);
240 		av_dict_set(&opts, "qmax", "54", 0);
241 		av_dict_set(&opts, "qmin", "11", 0);
242 		av_dict_set(&opts, "vprofile", "1", 0);
243 	}
244 	else {
245 		av_dict_set(&opts, "qmax", "63", 0);
246 		av_dict_set(&opts, "qmin", "0", 0);
247 		av_dict_set(&opts, "vprofile", "0", 0);
248 	}
249 
250 	av_dict_set(&opts, "lag-in-frames", lif, 0);
251 	av_dict_set(&opts, "g", "120", 0);
252 
253 
254 	if (vbr <= 10){
255 /* "HD" */
256 		if (height > 360)
257 			vbr = 1024 + 1024 * ( (float)(vbr+1) /11.0 * 2.0 );
258 /* "LD" */
259 		else
260 			vbr = 365 + 365 * ( (float)(vbr+1) /11.0 * 2.0 );
261 
262 		vbr *= 1024; /* to bit/s */
263 	}
264 
265 	av_dict_set(&opts, "quality", "realtime", 0);
266 	dst->storage.video.context->bit_rate = vbr;
267 
268 	LOG("(encode) video setup @ %d * %d, %f fps, %d kbit / s.\n",
269 		width, height, fps, vbr / 1024);
270 	if (avcodec_open2(dst->storage.video.context,
271 		dst->storage.video.codec, &opts) != 0){
272 		avcodec_close(dst->storage.video.context);
273 		dst->storage.video.context = NULL;
274 		dst->storage.video.codec   = NULL;
275 		return false;
276 	}
277 
278 	return true;
279 }
280 
281 static struct codec_ent vcodec_tbl[] = {
282 	{.kind = CODEC_VIDEO,
283 					.name = "libvpx",
284 					.shortname = "VP8",
285 					.id = AV_CODEC_ID_VP8,
286 					.setup.video = setup_cb_vp8},
287 
288 	{.kind = CODEC_VIDEO,
289 					.name = "libx264",
290 					.shortname = "H264",
291 					.id = AV_CODEC_ID_H264,
292 					.setup.video = setup_cb_x264},
293 
294 	{.kind = CODEC_VIDEO,
295 				 	.name = "ffv1",
296 					.shortname = "FFV1",
297 				 	.id = AV_CODEC_ID_FFV1,
298 				 	.setup.video = default_vcodec_setup },
299 };
300 
301 static struct codec_ent acodec_tbl[] = {
302 	{.kind = CODEC_AUDIO, .name = "libvorbis",
303 					.shortname = "VORBIS",
304 					.id = 0,
305 					.setup.audio = default_acodec_setup},
306 
307 	{.kind = CODEC_AUDIO,
308 				 	.name = "libmp3lame",
309 					.shortname = "MP3",
310 					.id = 0,
311 					.setup.audio = default_acodec_setup},
312 
313 	{.kind = CODEC_AUDIO,
314 					.name = "flac",
315 					.shortname = "FLAC",
316 			 		.id = AV_CODEC_ID_FLAC,
317 				 	.setup.audio = default_acodec_setup},
318 
319 	{.kind = CODEC_AUDIO,
320 				 	.name = "aac",
321 	 				.shortname = "AAC",
322 					.id = AV_CODEC_ID_AAC,
323 					.setup.audio = default_acodec_setup},
324 
325 	{.kind = CODEC_AUDIO,
326 				 	.name = "pcm_s16le_planar",
327 				 	.shortname = "RAW",
328 					.id = 0,
329 					.setup.audio = default_acodec_setup}
330 };
331 
lookup_default(const char * const req,struct codec_ent * tbl,size_t nmemb,bool audio)332 static struct codec_ent lookup_default(const char* const req,
333 	struct codec_ent* tbl, size_t nmemb, bool audio)
334 {
335 	struct codec_ent res = {.name = req};
336 	AVCodec** dst = audio ? &res.storage.audio.codec : &res.storage.video.codec;
337 
338 	if (req){
339 /* make sure that if the user supplies a name already in the standard table,
340  * that we get the same prefix setup function */
341 		for (int i = 0; i < nmemb; i++)
342 			if (tbl[i].name != NULL && (strcmp(req, tbl[i].name) == 0 ||
343 				strcmp(req, tbl[i].shortname) == 0) ){
344 				memcpy(&res, &tbl[i], sizeof(struct codec_ent));
345 				*dst = avcodec_find_encoder_by_name(res.name);
346 			}
347 
348 /* if the codec specified is unknown (to us) then let
349  * avcodec try and sort it up, return default setup */
350 		if (*dst == NULL){
351 			*dst = avcodec_find_encoder_by_name(req);
352 		}
353 	}
354 
355 /* if the user didn't supply an explicit codec, or one was not found,
356  * search the table for reasonable default */
357 	for (int i = 0; i < nmemb && *dst == NULL; i++)
358 		if (tbl[i].name != NULL && tbl[i].id == 0){
359 			memcpy(&res, &tbl[i], sizeof(struct codec_ent));
360 			*dst = avcodec_find_encoder_by_name(tbl[i].name);
361 		}
362 		else{
363 			memcpy(&res, &tbl[i], sizeof(struct codec_ent));
364 			*dst = avcodec_find_encoder(tbl[i].id);
365 		}
366 
367 	return res;
368 }
369 
encode_getvcodec(const char * const req,int flags)370 struct codec_ent encode_getvcodec(const char* const req, int flags)
371 {
372  	struct codec_ent a = lookup_default(req, vcodec_tbl,
373 		sizeof(vcodec_tbl) / sizeof(vcodec_tbl[0]), false);
374 	if (a.storage.video.codec && !a.setup.video)
375 		a.setup.video = default_vcodec_setup;
376 
377 	if (!a.storage.video.codec)
378 		return a;
379 
380 	a.storage.video.context = avcodec_alloc_context3( a.storage.video.codec );
381 	if (flags & AVFMT_GLOBALHEADER)
382 		a.storage.video.context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
383 
384 	return a;
385 }
386 
encode_getacodec(const char * const req,int flags)387 struct codec_ent encode_getacodec(const char* const req, int flags)
388 {
389 	struct codec_ent res = lookup_default(req, acodec_tbl,
390 		sizeof(acodec_tbl) / sizeof(acodec_tbl[0]), true);
391 
392 	if (res.storage.audio.codec && !res.setup.audio)
393 		res.setup.audio = default_acodec_setup;
394 
395 	if (!res.storage.audio.codec)
396 		return res;
397 
398 	res.storage.audio.context = avcodec_alloc_context3( res.storage.audio.codec);
399 	if ( (flags & AVFMT_GLOBALHEADER) > 0){
400 		res.storage.audio.context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
401 	}
402 
403 	return res;
404 }
405 
fds(void * infd,int64_t pos,int whence)406 static int64_t fds(void* infd, int64_t pos, int whence)
407 {
408 	int fd = *(int*) infd;
409 
410 	int64_t ret;
411 
412 	if (whence == AVSEEK_SIZE){
413 		struct stat st;
414 		ret = fstat(fd, &st);
415 
416 		return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size);
417 	}
418 
419 	ret = lseek(fd, pos, whence);
420 	return ret < 0 ? AVERROR(errno) : ret;
421 }
422 
fdw(void * fd,uint8_t * buf,int buf_size)423 static int fdw(void* fd, uint8_t* buf, int buf_size)
424 {
425 	return write(*(int*)fd, buf, buf_size);
426 }
427 
fdr(void * fd,uint8_t * buf,int buf_size)428 static int fdr(void* fd, uint8_t* buf, int buf_size)
429 {
430 	return read(*(int*)fd, buf, buf_size);
431 }
432 
433 /* slightly difference scanning function here so can't re-use lookup_default */
encode_getcontainer(const char * const requested,int dst,const char * remote)434 struct codec_ent encode_getcontainer(const char* const requested,
435 	int dst, const char* remote)
436 {
437 	AVFormatContext* ctx;
438 	struct codec_ent res = {0};
439 
440 	if (requested && strcmp(requested, "stream") == 0){
441 		res.storage.container.format = av_guess_format("flv", NULL, NULL);
442 
443 		if (!res.storage.container.format)
444 			LOG("(encode) couldn't setup streaming output.\n");
445 		else {
446 			ctx = avformat_alloc_context();
447 			ctx->oformat = res.storage.container.format;
448 			res.storage.container.context = ctx;
449 			res.setup.muxer = default_format_setup;
450 			int rv = avio_open2(&ctx->pb, remote, AVIO_FLAG_WRITE, NULL, NULL);
451 			LOG("(encode) attempting to open: %s, result: %d\n", remote, rv);
452 		}
453 
454 		return res;
455 	}
456 
457 	if (requested)
458 		res.storage.container.format = av_guess_format(requested, NULL, NULL);
459 
460 	if (!res.storage.container.format){
461 		LOG("(encode) couldn't find a suitable container matching (%s),"
462 			"	reverting to matroska (MKV)\n", requested);
463 		res.storage.container.format = av_guess_format("matroska", NULL, NULL);
464 	} else
465 		LOG("(encode) requested container (%s) found.\n", requested);
466 
467 /* no stream, nothing requested that matched and default didn't work.
468  * Give up and cascade. */
469 	if (!res.storage.container.format){
470 		LOG("(encode) couldn't find a suitable container.\n");
471 		return res;
472 	}
473 
474 	avformat_alloc_output_context2(&ctx, res.storage.container.format,
475 	NULL, NULL);
476 
477 /*
478  * Since there's no sane way for us to just pass a file descriptor and
479  * not be limited to pipe behaviors, we have to provide an entire
480  * custom avio class..
481  */
482 	int* fdbuf = malloc(sizeof(int));
483 	*fdbuf = dst;
484 	ctx->pb = avio_alloc_context(av_malloc(4096), 4096, 1, fdbuf, fdr, fdw, fds);
485 
486 	res.storage.container.context = ctx;
487 	res.setup.muxer = default_format_setup;
488 
489 	return res;
490 }
491