// %BANNER_BEGIN%
// ---------------------------------------------------------------------
// %COPYRIGHT_BEGIN%
// Copyright (c) (2018-2022) Magic Leap, Inc. All Rights Reserved.
// Use of this file is governed by the Software License Agreement, located here: https://www.magicleap.com/software-license-agreement-ml2
// Terms and conditions applicable to third-party materials accompanying this distribution may also be found in the top-level NOTICE file appearing herein.
// %COPYRIGHT_END%
// ---------------------------------------------------------------------
// %BANNER_END%
namespace UnityEngine.XR.MagicLeap
{
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.XR.MagicLeap.Native;
///
/// MLMedia APIs.
///
public partial class MLMedia
{
///
/// Media player script that allows playback of a streaming video (either from file or web URL)
/// This script will update the main texture parameter of the Renderer attached as a sibling
/// with the video frame from playback. Audio is also handled through this class and will
/// playback audio from the file.
///
public partial class ParserCEA708
{
private class NativeBindings : MagicLeapNativeBindings
{
public delegate void OnEmitEventDelegate(ulong parserHandle, ref Cea708CaptionEvent captionEvent, IntPtr data);
private const int MLCea708CaptionWindowsMax = 8;
private const int MLCea708CaptionEmitCommandBufferMaxSize = 20;
///
/// CEA708 Caption Color.
/// MLCea708CaptionColor from ml_media_cea708_caption.h.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionColor
{
///
/// Opacity setting.
///
public Cea708CaptionColorOpacity Opacity;
///
/// Red component.
///
public int Red;
///
/// Green component.
///
public int Green;
///
/// Blue component.
///
public int Blue;
}
///
/// CEA708 Caption Pen Attributes.
/// MLCea708CaptionPenAttr from ml_media_cea708_caption.h.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionPenAttr
{
///
/// Pen size.
///
public Cea708CaptionPenSize PenSize;
///
/// Pen offset.
///
public Cea708CaptionPenOffset PenOffset;
///
/// Text tag.
///
public int TextTag;
///
/// Font tag.
///
public int FontTag;
///
/// Edge type.
///
public int EdgeType;
///
/// Underline setting.
///
[MarshalAs(UnmanagedType.I1)]
public bool Underline;
///
/// Italic setting.
///
[MarshalAs(UnmanagedType.I1)]
public bool Italic;
}
///
/// CEA708 Caption Pen Color.
/// MLCea708CaptionPenColor from ml_media_cea708_caption.h.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionPenColor
{
///
/// Foreground color.
///
public Cea708CaptionColor ForegroundColor;
///
/// Background color.
///
public Cea708CaptionColor BackgroundColor;
///
/// Edge color.
///
public Cea708CaptionColor EdgeColor;
}
///
/// CEA708 Caption Pen Location.
/// MLCea708CaptionPenLocation from ml_media_cea708_caption.h.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionPenLocation
{
///
/// Pen row.
///
public int Row;
///
/// Pen column.
///
public int Column;
}
///
/// CEA708 Caption Window Attributes.
/// MLCea708CaptionWindowAttr from ml_media_cea708_caption.h.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionWindowAttr
{
///
/// Window fill color.
///
public Cea708CaptionColor FillColor;
///
/// Window border color.
///
public Cea708CaptionColor BorderColor;
///
/// Window border type.
///
public int BorderType;
///
/// Window word wrap setting.
///
[MarshalAs(UnmanagedType.I1)]
public bool WordWrap;
///
/// Window print direction.
///
public int PrintDirection;
///
/// Window scroll direction.
///
public int ScrollDirection;
///
/// Window justification setting.
///
public int Justify;
///
/// Window effect direction.
///
public int EffectDirection;
///
/// Window effect speed.
///
public int EffectSpeed;
///
/// Window display effect.
///
public int DisplayEffect;
}
///
/// CEA708 Caption Window.
/// MLCea708CaptionWindow from ml_media_cea708_caption.h.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionWindow
{
///
/// Window ID.
///
public int ID;
///
/// Window visible setting.
///
[MarshalAs(UnmanagedType.I1)]
public bool Visible;
///
/// Window row lock setting.
///
[MarshalAs(UnmanagedType.I1)]
public bool RowLock;
///
/// Window column lock setting.
///
[MarshalAs(UnmanagedType.I1)]
public bool ColumnLock;
///
/// Window Priority.
///
public int Priority;
///
/// Window relative positioning setting.
///
[MarshalAs(UnmanagedType.I1)]
public bool RelativePositioning;
///
/// Window anchor vertical.
///
public int AnchorVertical;
///
/// Window anchor horizontal.
///
public int AnchorHorizontal;
///
/// Window anchor ID.
///
public int AnchorID;
///
/// Window row count.
///
public int RowCount;
///
/// Window column count.
///
public int ColumnCount;
///
/// Window pen style.
///
public int PenStyle;
///
/// Window style.
///
public int WindowStyle;
}
///
/// Internal CEA708 Caption Event.
/// MLCea708CaptionEvent from ml_media_cea708_caption.h.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionEventInternal
{
///
/// Emitted CEA708 caption event type.
///
public Cea708CaptionEmitCommand Type;
///
/// Emitted CEA708 caption event specific data, based on the event type.
/// If the type is Cea708CaptionEmitCommand.Buffer, Object will point to a null terminated string of maximum size MLCea708CaptionEmitCommandBufferMaxSize bytes.
/// If the type is Cea708CaptionEmitCommand.Control, Object will point to one byte character.
/// If the type is Cea708CaptionEmitCommand.CWX, Object will point to an integer.
/// If the type is Cea708CaptionEmitCommand.CLW, Object will point to an integer.
/// If the type is Cea708CaptionEmitCommand.DSW, Object will point to an integer.
/// If the type is Cea708CaptionEmitCommand.HDW, Object will point to an integer.
/// If the type is Cea708CaptionEmitCommand.TGW, Object will point to an integer.
/// If the type is Cea708CaptionEmitCommand.DLW, Object will point to an integer.
/// If the type is Cea708CaptionEmitCommand.DLY, Object will point to an integer.
/// If the type is Cea708CaptionEmitCommand.DLC, Object will be NULL.
/// If the type is Cea708CaptionEmitCommand.RST, Object will be NULL.
/// If the type is Cea708CaptionEmitCommand.SPA, Object will point to Cea708CaptionPenAttr.
/// If the type is Cea708CaptionEmitCommand.SPC, Object will point to Cea708CaptionPenColor.
/// If the type is Cea708CaptionEmitCommand.SPL, Object will point to Cea708CaptionPenLocation.
/// If the type is Cea708CaptionEmitCommand.SWA, Object will point to Cea708CaptionWindowAttr.
/// If the type is Cea708CaptionEmitCommand.DFX, Object will point to Cea708CaptionWindow.
///
public IntPtr Object;
}
///
/// CEA708 Caption Event.
///
[StructLayout(LayoutKind.Sequential)]
public struct Cea708CaptionEvent
{
///
/// Emitted CEA708 caption event type.
///
public Cea708CaptionEmitCommand Type;
///
/// Emitted CEA708 caption event specific data, based on the event type.
/// If the type is Cea708CaptionEmitCommand.Buffer, Object will be a string.
/// If the type is Cea708CaptionEmitCommand.Control, Object will be a byte.
/// If the type is Cea708CaptionEmitCommand.CWX, Object will be an integer.
/// If the type is Cea708CaptionEmitCommand.CLW, Object will be an integer.
/// If the type is Cea708CaptionEmitCommand.DSW, Object will be an integer.
/// If the type is Cea708CaptionEmitCommand.HDW, Object will be an integer.
/// If the type is Cea708CaptionEmitCommand.TGW, Object will be an integer.
/// If the type is Cea708CaptionEmitCommand.DLW, Object will be an integer.
/// If the type is Cea708CaptionEmitCommand.DLY, Object will be an integer.
/// If the type is Cea708CaptionEmitCommand.DLC, Object will be null.
/// If the type is Cea708CaptionEmitCommand.RST, Object will be null.
/// If the type is Cea708CaptionEmitCommand.SPA, Object will be a Cea708CaptionPenAttr.
/// If the type is Cea708CaptionEmitCommand.SPC, Object will be a Cea708CaptionPenColor.
/// If the type is Cea708CaptionEmitCommand.SPL, Object will be a Cea708CaptionPenLocation.
/// If the type is Cea708CaptionEmitCommand.SWA, Object will be a Cea708CaptionWindowAttr.
/// If the type is Cea708CaptionEmitCommand.DFX, Object will be a Cea708CaptionWindow.
///
public IntPtr Data;
}
[DllImport(MLMediaCEA708DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern MLResult.Code MLMediaCea708ParserCreate(out ulong parserHandle);
[DllImport(MLMediaCEA708DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern MLResult.Code MLMediaCea708ParserDestroy(ulong parserHandle);
[DllImport(MLMediaCEA708DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern MLResult.Code MLMediaCea708ParserSetEmitEventCallback(ulong parserHandle, OnEmitEventDelegate calback, IntPtr data);
[DllImport(MLMediaCEA708DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern MLResult.Code MLMediaCea708ParserParse(ulong parserHandle, IntPtr subtitleData, uint subtitleDataSize);
///
/// Callback for the OnDisplayChanged event.
///
[AOT.MonoPInvokeCallback(typeof(NativeBindings.OnEmitEventDelegate))]
public static void OnEmitEvent(ulong parserHandle, ref Cea708CaptionEvent captionEvent, IntPtr data)
{
GCHandle gcHandle = GCHandle.FromIntPtr(data);
ParserCEA708 parser708 = gcHandle.Target as ParserCEA708;
if (parser708 == null)
{
return;
}
object obj = null;
switch (captionEvent.Type)
{
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.Buffer:
obj = MLConvert.DecodeUTF8(captionEvent.Data, MLCea708CaptionEmitCommandBufferMaxSize);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.Control:
obj = Marshal.ReadByte(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.CWX:
obj = Marshal.ReadInt32(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.CLW:
obj = Marshal.ReadInt32(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DSW:
obj = Marshal.ReadInt32(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.HDW:
obj = Marshal.ReadInt32(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.TGW:
obj = Marshal.ReadInt32(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DLW:
obj = Marshal.ReadInt32(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DLY:
obj = Marshal.ReadInt32(captionEvent.Data);
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DLC:
obj = null;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.RST:
obj = null;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SPA:
obj = Marshal.PtrToStructure(captionEvent.Data, typeof(Cea708CaptionPenAttr));
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SPC:
obj = Marshal.PtrToStructure(captionEvent.Data, typeof(Cea708CaptionPenColor));
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SPL:
obj = Marshal.PtrToStructure(captionEvent.Data, typeof(Cea708CaptionPenLocation));
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SWA:
obj = Marshal.PtrToStructure(captionEvent.Data, typeof(Cea708CaptionWindowAttr));
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DFX:
obj = Marshal.PtrToStructure(captionEvent.Data, typeof(Cea708CaptionWindow));
break;
}
MLThreadDispatch.Call(captionEvent.Type, obj, parser708.OnEmitEvent);
int winBitmap;
switch (captionEvent.Type)
{
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.Buffer:
if (parser708.cea708WindowID == -1)
{
parser708.cea708Strings[0] += (string)obj;
parser708.subtitleText = parser708.cea708Strings[0];
MLThreadDispatch.Call(parser708.subtitleText, parser708.OnText);
}
else
{
if (parser708.cea708WindowID == 0)
{
parser708.cea708Strings[0] += (string)obj;
parser708.subtitleText = parser708.cea708Strings[0];
MLThreadDispatch.Call(parser708.subtitleText, parser708.OnText);
}
else if (parser708.cea708WindowID == 1)
{
parser708.cea708Strings[1] += (string)obj;
parser708.subtitleText = parser708.cea708Strings[1];
MLThreadDispatch.Call(parser708.subtitleText, parser708.OnText);
}
}
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.Control:
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.CWX:
parser708.cea708WindowID = (int)obj;
if (parser708.cea708WindowID == 0)
{
parser708.cea708Strings[0] = string.Empty;
}
else if (parser708.cea708WindowID == 1)
{
parser708.cea708Strings[1] = string.Empty;
}
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.CLW:
winBitmap = (int)obj;
if (parser708.cea708WindowID == -1)
{
parser708.cea708Strings[0] = string.Empty;
}
for (int i = 0; i < MLCea708CaptionWindowsMax; i++)
{
if ((winBitmap & (1 << i)) != 0)
{
if (i == 0 || i == 1)
{
parser708.cea708Strings[i] = string.Empty;
}
}
}
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DSW:
winBitmap = (int)obj;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.HDW:
winBitmap = (int)obj;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.TGW:
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DLW:
winBitmap = (int)obj;
for (int i = 0; i < MLCea708CaptionWindowsMax; i++)
{
if (((winBitmap & (1 << i)) == 0) && (i == 0 || i == 1))
{
parser708.cea708Strings[i] = string.Empty;
}
}
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DLY:
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DLC:
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.RST:
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SPA:
Cea708CaptionPenAttr pen = (Cea708CaptionPenAttr)obj;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SPC:
Cea708CaptionPenColor penColor = (Cea708CaptionPenColor)obj;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SPL:
Cea708CaptionPenLocation penLoc = (Cea708CaptionPenLocation)obj;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.SWA:
Cea708CaptionWindowAttr winAttr = (Cea708CaptionWindowAttr)obj;
break;
case MLMedia.ParserCEA708.Cea708CaptionEmitCommand.DFX:
Cea708CaptionWindow win = (Cea708CaptionWindow)obj;
break;
default:
Debug.LogError("Error: ParserCEA708 unknown event type: " + captionEvent.Type);
break;
}
}
}
}
}
}