示例#1
0
static void build_flv_meta_data(obs_output_t context,
		uint8_t **output, size_t *size)
{
	obs_encoder_t vencoder = obs_output_get_video_encoder(context);
	obs_encoder_t aencoder = obs_output_get_audio_encoder(context);
	video_t       video    = obs_encoder_video(vencoder);
	audio_t       audio    = obs_encoder_audio(aencoder);
	char buf[4096];
	char *enc = buf;
	char *end = enc+sizeof(buf);

	enc_str(&enc, end, "onMetaData");

	*enc++ = AMF_ECMA_ARRAY;
	enc    = AMF_EncodeInt32(enc, end, 14);

	enc_num_val(&enc, end, "duration", 0.0);
	enc_num_val(&enc, end, "fileSize", 0.0);

	enc_num_val(&enc, end, "width",  (double)video_output_width(video));
	enc_num_val(&enc, end, "height", (double)video_output_height(video));
	enc_str_val(&enc, end, "videocodecid", "avc1");
	enc_num_val(&enc, end, "videodatarate", encoder_bitrate(vencoder));
	enc_num_val(&enc, end, "framerate", video_output_framerate(video));

	enc_str_val(&enc, end, "audiocodecid", "mp4a");
	enc_num_val(&enc, end, "audiodatarate", encoder_bitrate(aencoder));
	enc_num_val(&enc, end, "audiosamplerate",
			(double)audio_output_samplerate(audio));
	enc_num_val(&enc, end, "audiosamplesize", 16.0);
	enc_num_val(&enc, end, "audiochannels",
			(double)audio_output_channels(audio));

	enc_bool_val(&enc, end, "stereo", audio_output_channels(audio) == 2);
	enc_str_val(&enc, end, "encoder", MODULE_NAME);

	*enc++  = 0;
	*enc++  = 0;
	*enc++  = AMF_OBJECT_END;

	*size   = enc-buf;
	*output = bmemdup(buf, *size);
}
示例#2
0
static void *aac_create(obs_data_t settings, obs_encoder_t encoder)
{
	struct aac_encoder *enc;
	int                bitrate = (int)obs_data_getint(settings, "bitrate");
	audio_t            audio   = obs_encoder_audio(encoder);

	if (!bitrate) {
		aac_warn("aac_create", "Invalid bitrate specified");
		return NULL;
	}

	avcodec_register_all();

	enc          = bzalloc(sizeof(struct aac_encoder));
	enc->encoder = encoder;
	enc->aac     = avcodec_find_encoder(AV_CODEC_ID_AAC);
	if (!enc->aac) {
		aac_warn("aac_create", "Couldn't find encoder");
		goto fail;
	}

	blog(LOG_INFO, "Using ffmpeg \"%s\" aac encoder", enc->aac->name);

	enc->context = avcodec_alloc_context3(enc->aac);
	if (!enc->context) {
		aac_warn("aac_create", "Failed to create codec context");
		goto fail;
	}

	enc->context->bit_rate    = bitrate * 1000;
	enc->context->channels    = (int)audio_output_channels(audio);
	enc->context->sample_rate = audio_output_samplerate(audio);
	enc->context->sample_fmt  = enc->aac->sample_fmts ?
		enc->aac->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;

	init_sizes(enc, audio);

	/* enable experimental FFmpeg encoder if the only one available */
	enc->context->strict_std_compliance = -2;

	enc->context->flags = CODEC_FLAG_GLOBAL_HEADER;

	if (initialize_codec(enc))
		return enc;

fail:
	aac_destroy(enc);
	return NULL;
}
示例#3
0
static void *libfdk_create(obs_data_t settings, obs_encoder_t encoder)
{
	bool hasFdkHandle = false;
	libfdk_encoder_t *enc = 0;
	int bitrate = (int)obs_data_getint(settings, "bitrate") * 1000;
	int afterburner = obs_data_getbool(settings, "afterburner") ? 1 : 0;
	audio_t audio = obs_encoder_audio(encoder);
	int mode = 0;
	AACENC_ERROR err;

	if (!bitrate) {
		blog(LOG_ERROR, "Invalid bitrate");
		return NULL;
	}

	enc = bzalloc(sizeof(libfdk_encoder_t));
	enc->encoder = encoder;

	enc->channels = (int)audio_output_channels(audio);
	enc->sample_rate = audio_output_samplerate(audio);

	switch(enc->channels) {
	case 1:
		mode = MODE_1;
		break;
	case 2:
		mode = MODE_2;
		break;
	case 3:
		mode = MODE_1_2;
		break;
	case 4:
		mode = MODE_1_2_1;
		break;
	case 5:
		mode = MODE_1_2_2;
		break;
	case 6:
		mode = MODE_1_2_2_1;
		break;
	default:
		blog(LOG_ERROR, "Invalid channel count");
		goto fail;
	}

	CHECK_LIBFDK(aacEncOpen(&enc->fdkhandle, 0, enc->channels));
	hasFdkHandle = true;

	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AOT,
	                                 2)); // MPEG-4 AAC-LC
	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_SAMPLERATE,
	                                 enc->sample_rate));
	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELMODE, mode));
	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELORDER, 1));
	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATEMODE, 0));
	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATE, bitrate));
	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_TRANSMUX, 0));
	CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AFTERBURNER,
	                                 afterburner));

	CHECK_LIBFDK(aacEncEncode(enc->fdkhandle, NULL, NULL, NULL, NULL));

	CHECK_LIBFDK(aacEncInfo(enc->fdkhandle, &enc->info));

	enc->frame_size_bytes = enc->info.frameLength * 2 * enc->channels;

	enc->packet_buffer_size = enc->channels * 768;
	if(enc->packet_buffer_size < 8192)
		enc->packet_buffer_size = 8192;

	enc->packet_buffer = bmalloc(enc->packet_buffer_size);

	blog(LOG_INFO, "libfdk_aac encoder created");

	return enc;

fail:

	if(hasFdkHandle)
		aacEncClose(&enc->fdkhandle);

	if(enc->packet_buffer)
		bfree(enc->packet_buffer);

	if(enc)
		bfree(enc);

	blog(LOG_WARNING, "libfdk_aac encoder creation failed");

	return 0;
}