VLC libvlc_state_t State Machine? - libvlc

Does anyone know if the VLC project has a defined state machine for the libvlc_state_t states? The state machine states are exposed via libvlc and then again via bindings into other languages (for example, LibVLCSharp). The enum is documented here, but I can't find a description of transitions or other details.
Update
I'd like to see this get rolled into VLC docs at some point. While the state machine might seem obvious, I am encountering small oddities like the Buffering event getting called but the Media not seeming to pass through the Buffering state - it's still in the Playing state.
These little things add up and it would probably help improve developer experience to get them added. What I'm looking for as a solution is a typical state machine that includes at a minimum the states, the transitions, and notes about which events are actually fired on which transitions (and if they happen before or after the state actually changes). Anything around threading concerns (e.g. sync vs. async transitions) and allowable actions while in a given state are a bonus.

I did some work to capture the observed behavior. This is incomplete and imperfect, but perhaps it may help others as they build on top of libvlc/LibVLCSharp (I was on v3.5.1, VideoLAN.LibVLC.Windows v3.0.14). The dashed arrows pointing to the right are to show when certain events fire. Note that some of these behaviors are potentially specific to the type of media or the fact that reading is occurring through the MediaInput interface, so your mileage may vary.
A few notes:
Things did not seem to always work properly if you tried to e.g. seek while the media was Opening. For example, I saw .Time and .Position fall permanently out of sync. I strongly recommend waiting until after a Play() operation before doing much.
The Buffering state was not seen to be in use, but the Buffering event would fire at least the Opening and Playing states.
As others have noted, you can't simply call Play() once the media ends. You need to Stop() after EndReached fires, and - as with many of the callbacks - you need to make sure you handle this in a non-deadlocking way. It can and will silently deadlock. Even using Dispatcher may choose to run on the same thread, so you have to guarantee a separate thread. So far I've had good luck with e.g. ThreadPool.QueueUserWorkItem(_ => yourMediaPlayer.Stop()); You can then hook Stopped to trigger further behavior like Play().
I'm still not sure the exact behavior around ErrorEncountered and recovery to Play() again; it wasn't easy to trigger this behavior.
Ultimately this state machine allowed me to build one on top of it to handle behaviors like "make the file playable again when the end is reached".
Thanks #mfkl and many others for the hard work - with a bit of digging this has been a great library to build on!

media.State
Should give you what you want.
The libvlc_state_t C enum is simply defined as a C# enum in libvlcsharp, like so:
/// <summary>Note the order of libvlc_state_t enum must match exactly the order of</summary>
/// <remarks>
/// <para>mediacontrol_PlayerStatus,</para>
/// <para>input_state_e enums,</para>
/// <para>and VideoLAN.LibVLCSharp.State (at bindings/cil/src/media.cs).</para>
/// <para>Expected states by web plugins are:</para>
/// <para>IDLE/CLOSE=0, OPENING=1, PLAYING=3, PAUSED=4,</para>
/// <para>STOPPING=5, ENDED=6, ERROR=7</para>
/// </remarks>
public enum VLCState
{
/// <summary>
/// Nothing special happening
/// </summary>
NothingSpecial = 0,
/// <summary>
/// Opening media
/// </summary>
Opening = 1,
/// <summary>
/// Buffering media
/// </summary>
Buffering = 2,
/// <summary>
/// Playing media
/// </summary>
Playing = 3,
/// <summary>
/// Paused media
/// </summary>
Paused = 4,
/// <summary>
/// Stopped media
/// </summary>
Stopped = 5,
/// <summary>
/// Ended media
/// </summary>
Ended = 6,
/// <summary>
/// Error media
/// </summary>
Error = 7
}
You can also subscribe to the StateChanged event on the Media to get notified of changes in the State status.

Related

how to register a keystore extension in substrate benchmarking?

I'm writing benchmark for a pallet, in which I need to generate key pairs as input. However with --features runtime-benchmarking, I seems not able to use full-crypto and sp_core::Pair.
So the only way I found is to use RuntimeAppPublic::generate_pair, but it needs a keystore registered for the ext. But with benchmark! macro I wasn't able to do this.
So are there any suggestions? Either on generating keypairs without std or registering a keystore extension within the benchmark! framework.
Edit: I found something may be helpful in the doc.
/// You can construct benchmark by using the `impl_benchmark_test_suite` macro or
/// by manually implementing them like so:
///
/// ```ignore
/// #[test]
/// fn test_benchmarks() {
/// new_test_ext().execute_with(|| {
/// assert_ok!(Pallet::<Test>::test_benchmark_dummy());
/// ...
/// });
/// }
/// ```
From this doc, I think we can manipulate the test_ext easily for the test. But there are no information about the bench_xxx functions. As far as I can see in the cargo expand file, it maybe a bit different for benchmark.
It's about genesis config, closing.

Custom date format with NLog

It appears to me as tho the in-built date formats in NLog do not include the timezone correctly. We need to log UTC time WITH the trailing Z so that Splunk knows what the local time is, eg:
{date:universalTime=true:format=yyyy-MM-dd HH:mm:ss.ffffZ}
This produces the correct dates we need.
Rather than inserting this in all our configs across multiple apps, I'd prefer to define a variable that will do this, eg:
{ourdate}
I've had a hack around but I cant figure out how to do this. Is it possible?
Thanks
PS. {longdate} does include the timezone but it drops the milliseconds.
The easiest thing for you to do is probably to just bite bullet and use the regular NLog DateLayoutRenderer and specify the configuration values in every config file. If you'd rather keep your config files simple, you could write your own date LayoutRenderer that generates the date in a specific format.
Here is a rough implementation (not tested). It will always log the date in the format that you specified above. I based it on NLog's DateLayoutRenderer, the source of which you can find here:
https://github.com/NLog/NLog/tree/master/src/NLog/LayoutRenderers
You don't really need more options, because you can easily achieve the format you want using the built in DateLayoutRenderer. This implementation just saves you some effort in your NLog.config file(s).
namespace NLog.LayoutRenderers
{
using System.ComponentModel;
using System.Text;
using NLog.Config;
/// <summary>
/// Current date and time.
/// </summary>
[LayoutRenderer("utczdate")]
[ThreadAgnostic]
public class UTCZDateLayoutRenderer : LayoutRenderer
{
/// <summary>
/// Initializes a new instance of the <see cref="UTCZDateLayoutRenderer" /> class.
/// </summary>
public UTCZDateLayoutRenderer()
{
}
/// <summary>
/// Renders the current date and appends it to the specified <see cref="StringBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
/// <param name="logEvent">Logging event.</param>
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
var ts = logEvent.TimeStamp;
builder.Append(ts.ToString("yyyy-MM-dd HH:mm:ss.ffffZ", CultureInfo.InvariantCulture));
}
}
}
You can use this in your NLog.config file like this:
{utczdate}
Good luck!
Use ${date:universalTime=true:format=o}
Format 2015-11-06T14:24:52.4025753Z ISO 8601
You are wanting the Round-Trip ("O","o") Format Specifier
The "O" or "o" standard format specifier represents a custom date and time format string using a pattern that preserves time zone information and emits a result string that complies with ISO 8601.

CruseControl.Net mail check-in

How can I configure the "publisher" section in ccnet.config file in order to send email only to person who checked-in when the build fails?
Thanks,
John.
I don't think you can "out of the box".
You'll have to write your own publisher...and piggy back on "FailureUsers".
https://github.com/ccnet/CruiseControl.NET/blob/master/project/core/IIntegrationResult.cs
// Users who contributed modifications to a series of failing builds:
/// <summary>
/// Gets the failure users.
/// </summary>
/// <value></value>
/// <remarks></remarks>
ArrayList FailureUsers { get; } // This should really be a Set but sets are not available in .NET 1.1
Here is the tech-spec:
http://confluence.public.thoughtworks.org/display/CCNET/Custom+Builder+Plug-in
Here is an example of someone who wrote one....
http://krisselden.com/2007/01/29/adding-a-custom-cruisecontrolnet-publisher/

Create file template with generic macro

this is my template code:
using System;
using System.Runtime.Serialization;
using Nethos.Ferramentas.AtributosValidacao.Numeros;
using Nethos.Ferramentas.AtributosValidacao.Textos;
$HEADER$namespace $NAMESPACE$
{
/// <summary>
/// Classe responsável pela persistência dos dados.
/// Tabela: $CLASS$s (PK: Id)
/// </summary>
[DataContract]
[KnownType(typeof(NHibernate.Collection.Generic.PersistentGenericBag< $CLASS$ >))]
[KnownType(typeof(NHibernate.Collection.PersistentBag))]
[Serializable]
public class $CLASS$
{
$END$
}
}
but in the line "[KnownType(typeof(NHibernate.Collection.Generic.PersistentGenericBag< $CLASS$ >))]" not appear name of the class, just the letter "a"... what's the problem with my code template?
I suspect this is an issue that the original 8.0 release of ReSharper has with certain plugins, under certain conditions. If you open Visual Studio by double clicking a solution file, the plugin would get initialised too late, and cause exceptions (you can verify by running "devenv.exe /ReSharper.Internal" and look for exceptions). The exceptions can interfere with various parts of ReSharper, unfortunately, macros is one that I've seen.
This has been fixed with ReSharper 8.0.1. Please can you update and try again?

Application Object Won't Share

I'm having issues with my Application Object. I am currently using a Service to simulate incoming data from an electronic game board. This data is represented as a 2D boolean array. Every five seconds the Service uses a method of the Application Object to update the array (setDetectionMap()). This array is being read by a Thread in my main Activity using another method (getDetectionMap()). After some debugging I am almost positive that the main Activity is not seeing the changes. Here is the code for my Application Object:
public class ChessApplication extends Application{
private static ChessApplication singleton;
private boolean[][] detectionMap;
public static ChessApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton=this;
detectionMap=new boolean[8][8];
}
public boolean[][] getDetectionMap(){
return detectionMap;
}
public void setDetectionMap(boolean[][] newMap){
detectionMap=newMap;
Log.d("Chess Application","Board Changed");
}
}
I've checked my Manifest, I've rewritten my object declaration a dozen times, I've added LogCat tags to make sure that the code is executing when I think it should be, and I've even implemented the supposedly redundant Singleton code. Any ideas what could be causing this? Incidentally can anyone tell me how to view variable states as the activity is running? Thanks in advance.
Is your Activity calling getDetectionMap() to get the new map after the update occurs?
Because otherwise, it's holding onto a reference to the old boolean[][] array, wheras setDetectionMap(...) isn't actually updating the current data structure, it's just updating the "detectionMap" variable to point to a different one. As such, your main activity won't be aware of the swapout until the next time it calls getDetectionMap.
Easy fix: in setDetectionMap, manually copy values from newMap into detectionMap. Or, update the Activity's reference so it's looking at the right map.
One other observation entirely unrelated to the original question: It's quite unusual to override Application during Android development, and is usually considered a "code smell" unless you have a really good reason for doing so. In this case I imagine it's so that you can communicate between your service and Activity, but you create a middle-man where one isn't entirely necessary. Here's a useful SO thread on how to communicate directly between the two :)

Resources