INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: Encoder in managed code  (Read 3791 times)

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Encoder in managed code
« on: April 10, 2012, 01:39:18 am »

Hello, I'm intending to write an encoder plugin for FlacCL (which uses GPU acceleration to encode FLAC files), over using the External Encoder option in MC. I found the sample which flips the order of wav samples, but it's in C++ and doesn't really document the interfaces which need to be exported (the whole plugin seems to be the SDK!? the code's very tightly coupled.)

Any directions before I take the painful approach? I'm sure someone else must have done this before :P
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #1 on: April 10, 2012, 01:39:54 am »

And, if you're wondering, it's managed code because the encoder is written in C# and OpenCL. Nothing stopping me from using C++/CLI, but...
Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 42372
  • Shoes gone again!
Re: Encoder in managed code
« Reply #2 on: April 10, 2012, 10:30:34 am »

Make sure you're using this header for the interface:
http://jriver.com/DevZone/JREncoder.h

You'll have to export an unmanaged C++ class derived from IJREncoder.

That class can be a thin wrapper around your managed code.
Logged
Matt Ashland, JRiver Media Center

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #3 on: April 11, 2012, 12:06:08 am »

Oh, it's the first time I saw the link. I got http://wiki.jriver.com/index.php/Encoder_Plug-in_SDK and http://wiki.jriver.com/index.php/DevZone via a Google search, which didn't point to that file.

The interface looks useable - I'll see what I can hack out and hopefully I'll get a Google Code project or something up for people.
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #4 on: April 11, 2012, 08:29:29 pm »

I've got a question -- writing the code triggered it.

   virtual BOOL StartBufferBased(WAVEFORMATEX * pwfeFormat, __int64 nApproximateTotalBytes) = 0;
   virtual BOOL EncodeBufferBased(BYTE * pBuffer, int nBufferBytes) = 0;
   virtual BOOL FinishBufferBased() = 0;

Since EncodeBufferBased is how MC puts samples to the plugin, how does the plugin return the encoded data?
Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 42372
  • Shoes gone again!
Re: Encoder in managed code
« Reply #5 on: April 11, 2012, 08:40:09 pm »

Since EncodeBufferBased is how MC puts samples to the plugin, how does the plugin return the encoded data?

Encoders always write their output to a file.

In other words, the encoder does not return the encoded data.

I'm going from memory, but I believe you'll be given the output filename with SetInfo(JR_ENCODER_INFO_DESTINATION_FILENAME) and later asked for the filename back (in case you changed it) with GetInfo(JR_ENCODER_INFO_DESTINATION_FILENAME).
Logged
Matt Ashland, JRiver Media Center

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #6 on: April 11, 2012, 08:40:59 pm »

Right -- I'll try that, keep you posted.
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #7 on: April 11, 2012, 09:11:10 pm »

Another question: when MC calls GetInfo(JR_ENCODER_INFO_WAV_FILE_INPUT), I'm guessing it expects a bool/int value: but the return type of the function is a LPCSTR. Do I cast it or return a string value "false" or "0" or "no" (and likewise "true", "1", or "yes"?)
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #8 on: April 11, 2012, 09:31:11 pm »

PackageInstaller wasn't running my DllRegisterServer and DllUnregisterServer, so I did a dumpbin /exports on the MC17 dll:

          2    1 00003050 DllRegisterServer
          3    2 00003060 DllUnregisterServer

Perhaps it may be useful to document that unlike the normal Windows DllRegisterServer and DllUnregisterServer, the calling convention is __cdecl and not __stdcall. Just a note for anyone who may run into this in future.
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #9 on: April 11, 2012, 10:23:37 pm »

Another question: when MC calls GetInfo(JR_ENCODER_INFO_WAV_FILE_INPUT), I'm guessing it expects a bool/int value: but the return type of the function is a LPCSTR. Do I cast it or return a string value "false" or "0" or "no" (and likewise "true", "1", or "yes"?)

I poked around and found that MC uses "0" and "1" to be returned as a BSTR.
Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 42372
  • Shoes gone again!
Re: Encoder in managed code
« Reply #10 on: April 11, 2012, 10:39:20 pm »

PackageInstaller wasn't running my DllRegisterServer and DllUnregisterServer, so I did a dumpbin /exports on the MC17 dll:

          2    1 00003050 DllRegisterServer
          3    2 00003060 DllUnregisterServer

Perhaps it may be useful to document that unlike the normal Windows DllRegisterServer and DllUnregisterServer, the calling convention is __cdecl and not __stdcall. Just a note for anyone who may run into this in future.

PackageInstaller (or regsvr) just looks for an export named "DllRegisterServer" from the Dll.  Is it possible you were exporting something like DllRegisterServer@4 instead?  You could use a .def file to avoid name decoration.

As for the calling convention, I'm not sure what we're using, but will double-check tomorrow.
Logged
Matt Ashland, JRiver Media Center

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #11 on: April 11, 2012, 10:41:19 pm »

Yup, it was, and DllRegisterServer@4 is the default (decorated) name when __stdcall is used. __cdecl doesn't have name decoration, so it remains the same.

Nonetheless, since both functions take no arguments, if memory serves, the calling convention is inconsequential.
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #12 on: April 12, 2012, 08:52:16 am »

I've spent most of today doing the encoder, and as of now I've managed to at least get the encoder to produce a valid output file with the tags properly copied over.

I just need to make the encoder config persistent and for me to retain those settings when the encoder is called instead of resorting to defaults. Thanks for your help so far.
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #13 on: April 12, 2012, 08:34:45 pm »

I've got a working binary ready for people to test, if anyone's interested. PM me with an email address or something for me to send a signed installer to you.

I'll be publishing this on Google Code as soon as I've cleaned up my code mess.
Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 42372
  • Shoes gone again!
Re: Encoder in managed code
« Reply #14 on: April 12, 2012, 09:02:01 pm »

I just need to make the encoder config persistent and for me to retain those settings when the encoder is called instead of resorting to defaults. Thanks for your help so far.

You're probably ahead of me on this, but settings should be saved to a string with GetInfo(...) / SetInfo(...) calls.  This allows Media Center to store the settings, and keep different settings for different tasks.
Logged
Matt Ashland, JRiver Media Center

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #15 on: April 12, 2012, 09:02:42 pm »

Yup, I did that. I noted the comment at the top of the header.
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #16 on: April 12, 2012, 09:06:39 pm »

Oh, and one documentation point that could go somewhere - the filename in JR_ENCODER_INFO_DESTINATION_FILENAME does not contain the target encode extension. For MC to copy the correct tag, the plugin needs to update that value to add the extension (.flac in my case) before completing the encode so that the tags will be transferred to the generated file.

If the file is left alone, MC will still rename the file afterward with the correct extension, but the tag will not be transferred.
Logged

lowjoel

  • World Citizen
  • ***
  • Posts: 159
Re: Encoder in managed code
« Reply #17 on: April 30, 2012, 12:03:09 am »

I'm please to announce that I've published my code up on Google Code: http://code.google.com/p/jrmc-oss-plugins/. Pardon the very uncreative name...

In addition to this encoder plugin, I've also included a modified version of an old plugin (?? I can't really remember where I got the base code from, maybe somewhere on this board) which will allow MC to push messages to WLM (or compatible listener - I personally use Pidgin with the MusicTracker plugin) to publish the Now Playing item to Windows Live Messenger.
Logged
Pages: [1]   Go Up