char * AMF_EncodeString ( char *output, char *outend, const AVal *bv ) { if ( ( bv->av_len < 65536 && output + 1 + 2 + bv->av_len > outend ) || output + 1 + 4 + bv->av_len > outend ) { return NULL; } if ( bv->av_len < 65536 ) { *output++ = AMF_STRING; output = AMF_EncodeInt16 ( output, outend, bv->av_len ); } else { *output++ = AMF_LONG_STRING; output = AMF_EncodeInt32 ( output, outend, bv->av_len ); } memcpy ( output, bv->av_val, bv->av_len ); output += bv->av_len; return output; }
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); }
char* OBS::EncMetaData(char *enc, char *pend, bool bFLVFile) { int maxBitRate = GetVideoEncoder()->GetBitRate(); int fps = GetFPS(); int audioBitRate = GetAudioEncoder()->GetBitRate(); CTSTR lpAudioCodec = GetAudioEncoder()->GetCodec(); double audioCodecID; const AVal *av_codecFourCC; #ifdef USE_AAC if(scmpi(lpAudioCodec, TEXT("AAC")) == 0) { av_codecFourCC = &av_mp4a; audioCodecID = 10.0; } else #endif { av_codecFourCC = &av_mp3; audioCodecID = 2.0; } if(bFLVFile) { *enc++ = AMF_ECMA_ARRAY; enc = AMF_EncodeInt32(enc, pend, 14); } else *enc++ = AMF_OBJECT; enc = AMF_EncodeNamedNumber(enc, pend, &av_duration, 0.0); enc = AMF_EncodeNamedNumber(enc, pend, &av_fileSize, 0.0); enc = AMF_EncodeNamedNumber(enc, pend, &av_width, double(outputCX)); enc = AMF_EncodeNamedNumber(enc, pend, &av_height, double(outputCY)); /*if(bFLVFile) enc = AMF_EncodeNamedNumber(enc, pend, &av_videocodecid, 7.0);//&av_avc1);// else*/ enc = AMF_EncodeNamedString(enc, pend, &av_videocodecid, &av_avc1);//7.0);// enc = AMF_EncodeNamedNumber(enc, pend, &av_videodatarate, double(maxBitRate)); enc = AMF_EncodeNamedNumber(enc, pend, &av_framerate, double(fps)); /*if(bFLVFile) enc = AMF_EncodeNamedNumber(enc, pend, &av_audiocodecid, audioCodecID);//av_codecFourCC);// else*/ enc = AMF_EncodeNamedString(enc, pend, &av_audiocodecid, av_codecFourCC);//audioCodecID);// enc = AMF_EncodeNamedNumber(enc, pend, &av_audiodatarate, double(audioBitRate)); //ex. 128kb\s enc = AMF_EncodeNamedNumber(enc, pend, &av_audiosamplerate, 44100.0); enc = AMF_EncodeNamedNumber(enc, pend, &av_audiosamplesize, 16.0); enc = AMF_EncodeNamedNumber(enc, pend, &av_audiochannels, 2.0); enc = AMF_EncodeNamedBoolean(enc, pend, &av_stereo, true); enc = AMF_EncodeNamedString(enc, pend, &av_encoder, &av_OBSVersion); *enc++ = 0; *enc++ = 0; *enc++ = AMF_OBJECT_END; return enc; }
static bool build_flv_meta_data(obs_output_t *context, uint8_t **output, size_t *size, size_t a_idx) { obs_encoder_t *vencoder = obs_output_get_video_encoder(context); obs_encoder_t *aencoder = obs_output_get_audio_encoder(context, a_idx); 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); struct dstr encoder_name = {0}; if (a_idx > 0 && !aencoder) return false; enc_str(&enc, end, "onMetaData"); *enc++ = AMF_ECMA_ARRAY; enc = AMF_EncodeInt32(enc, end, a_idx == 0 ? 14 : 9); enc_num_val(&enc, end, "duration", 0.0); enc_num_val(&enc, end, "fileSize", 0.0); if (a_idx == 0) { enc_num_val(&enc, end, "width", (double)obs_encoder_get_width(vencoder)); enc_num_val(&enc, end, "height", (double)obs_encoder_get_height(vencoder)); enc_str_val(&enc, end, "videocodecid", "avc1"); enc_num_val(&enc, end, "videodatarate", encoder_bitrate(vencoder)); enc_num_val(&enc, end, "framerate", video_output_get_frame_rate(video)); } enc_str_val(&enc, end, "audiocodecid", "mp4a"); enc_num_val(&enc, end, "audiodatarate", encoder_bitrate(aencoder)); enc_num_val(&enc, end, "audiosamplerate", (double)obs_encoder_get_sample_rate(aencoder)); enc_num_val(&enc, end, "audiosamplesize", 16.0); enc_num_val(&enc, end, "audiochannels", (double)audio_output_get_channels(audio)); enc_bool_val(&enc, end, "stereo", audio_output_get_channels(audio) == 2); enc_bool_val(&enc, end, "2.1", audio_output_get_channels(audio) == 3); enc_bool_val(&enc, end, "3.1", audio_output_get_channels(audio) == 4); enc_bool_val(&enc, end, "4.0", audio_output_get_channels(audio) == 4); enc_bool_val(&enc, end, "4.1", audio_output_get_channels(audio) == 5); enc_bool_val(&enc, end, "5.1", audio_output_get_channels(audio) == 6); enc_bool_val(&enc, end, "7.1", audio_output_get_channels(audio) == 8); dstr_printf(&encoder_name, "%s (libobs version ", MODULE_NAME); #ifdef HAVE_OBSCONFIG_H dstr_cat(&encoder_name, OBS_VERSION); #else dstr_catf(&encoder_name, "%d.%d.%d", LIBOBS_API_MAJOR_VER, LIBOBS_API_MINOR_VER, LIBOBS_API_PATCH_VER); #endif dstr_cat(&encoder_name, ")"); enc_str_val(&enc, end, "encoder", encoder_name.array); dstr_free(&encoder_name); *enc++ = 0; *enc++ = 0; *enc++ = AMF_OBJECT_END; *size = enc-buf; *output = bmemdup(buf, *size); return true; }
// Encoding functions uint8_t inline *amf_write_i32(uint8_t *s, uint8_t *e, int i) { return (uint8_t*)AMF_EncodeInt32((char*)s, (char*)e, i); }