/****************************************************************************
* Copyright 2019 Nreal Techonology Limited. All rights reserved.
*
* This file is part of NRSDK.
*
* https://www.nreal.ai/
*
*****************************************************************************/
namespace NRKernal.Record
{
using UnityEngine;
using System;
using System.Collections.Generic;
using AOT;
using System.Runtime.InteropServices;
/// A video encoder.
public class AudioEncoder : IEncoderBase
{
private NativeEncoder mNativeEncoder;
public NativeEncodeConfig EncodeConfig;
private IntPtr androidMediaProjection { get; set; }
private bool m_IsStarted = false;
private AudioDataCallBack mDataCallBack = null;
private static List gInactiveAudioEncoders = new List();
#if !UNITY_EDITOR
private const int STARTENCODEEVENT = 0x2001;
private const int STOPENCODEEVENT = 0x2002;
private delegate void RenderEventDelegate(int eventID);
private static RenderEventDelegate RenderThreadHandle = new RenderEventDelegate(RunOnRenderThread);
private static IntPtr RenderThreadHandlePtr = Marshal.GetFunctionPointerForDelegate(RenderThreadHandle);
#endif
/// Default constructor.
public AudioEncoder()
{
#if !UNITY_EDITOR
mNativeEncoder = NativeEncoder.GetInstance();
mNativeEncoder.Register(this);
#endif
}
#if !UNITY_EDITOR
[MonoPInvokeCallback(typeof(RenderEventDelegate))]
private static void RunOnRenderThread(int eventID)
{
if (eventID == STARTENCODEEVENT)
{
lock (gInactiveAudioEncoders)
{
for (int i = 0; i < gInactiveAudioEncoders.Count; i++)
{
NativeEncoder.GetInstance().StartAudioRecorder(gInactiveAudioEncoders[i].mDataCallBack);
}
gInactiveAudioEncoders.Clear();
}
}
}
#endif
/// Configurations the given parameter.
/// The parameter.
public void Config(CameraParameters param)
{
EncodeConfig = new NativeEncodeConfig(param);
androidMediaProjection = (param.mediaProjection != null) ? param.mediaProjection.GetRawObject() : IntPtr.Zero;
}
/// Adjust the volume of encoder.
/// Recorder index.
/// The factor of volume.
public void AdjustVolume(RecorderIndex recordIdx, float factor)
{
#if !UNITY_EDITOR
mNativeEncoder.AdjustVolume(recordIdx, factor);
#endif
}
/// Starts this object.
public void Start(AudioDataCallBack onAudioDataCallback = null)
{
if (m_IsStarted)
{
return;
}
NRDebugger.Info("[AudioEncoder] Start");
NRDebugger.Info("[AudioEncoder] Config {0}", EncodeConfig.ToString());
mDataCallBack = onAudioDataCallback;
lock (gInactiveAudioEncoders)
{
gInactiveAudioEncoders.Add(this);
}
#if !UNITY_EDITOR
mNativeEncoder.SetConfigration(EncodeConfig, androidMediaProjection);
//mNativeEncoder.StartAudioRecorder(mDataCallBack);
GL.IssuePluginEvent(RenderThreadHandlePtr, STARTENCODEEVENT);
#endif
m_IsStarted = true;
}
/// Stops this object.
public void Stop()
{
if (!m_IsStarted)
{
return;
}
NRDebugger.Info("[AudioEncoder] Stop");
lock (gInactiveAudioEncoders)
{
gInactiveAudioEncoders.Remove(this);
}
#if !UNITY_EDITOR
mNativeEncoder.StopAudioRecorder(mDataCallBack);
#endif
m_IsStarted = false;
}
/// Releases this object.
public void Release()
{
NRDebugger.Info("[AudioEncoder] Release...");
#if !UNITY_EDITOR
mNativeEncoder.UnRegister(this);
mNativeEncoder.Destroy();
#endif
}
}
}