Xuggle can't open in-memory input
Asked Answered
R

2

6

I am working on a program that integrates Hadoop's MapReduce framework with Xuggle. For that, I am implementing a IURLProtocolHandlerFactory class that reads and writes from and to in-memory Hadoop data objects.

You can see the relevant code here: https://gist.github.com/4191668

The idea is to register each BytesWritable object in the IURLProtocolHandlerFactory class with a UUID so that when I later refer to that name while opening the file it returns a IURLProtocolHandler instance that is attached to that BytesWritable object and I can read and write from and to memory.

The problem is that I get an exception like this:

java.lang.RuntimeException: could not open: byteswritable:d68ce8fa-c56d-4ff5-bade-a4cfb3f666fe
at com.xuggle.mediatool.MediaReader.open(MediaReader.java:637)

(see also under the posted link)

When debugging I see that the objects are correctly found in the factory, what's more, they are even being read from in the protocol handler. If I remove the listeners from/to the output file, the same happens, so the problem is already with the input. Digging deeper in the code of Xuggle I reach the JNI code (which tries to open the file) and I can't get further than this. This apparently returns an error code.

XugglerJNI.IContainer_open__SWIG_0

I would really appreciate some hint where to go next, how should I continue debugging. Maybe my implementation has a flaw, but I can't see it.

Richardo answered 8/12, 2012 at 23:40 Comment(0)
F
2

I think the problem you are running into is that a lot of the types of inputs/outputs are converted to a native file descriptor in the IContainer JNI code, but the thing you are passing cannot be converted. It may not be possible to create your own IURLProtocolHandler in this way, because it would, after a trip through XuggleIO.map(), just end up calling IContainer again and then into the IContainer JNI code which will probably try to get a native file descriptor and call avio_open().

However, there may be a couple of things that you can open in IContainer which are not files/have no file descriptors, and which would be handled correctly. The things you can open can be seen in the IContainer code, namely java.io.DataOutput and java.io.DataOutputStream (and the corresponding inputs). I recommend making your DataInput/DataOutput implementation which wraps around BytesReadable/BytesWriteable, and opening it in IContainer.

If that doesn't work, then write your inputs to a temp file and read the outputs from a temp file :)

Frugal answered 19/12, 2012 at 19:37 Comment(1)
All right then. It seemed to be such a nice and clean idea to write my own IURLProtocolHandlerFactory for both read and write. I saw I would implement a DataInput for my own input and still use IURLProtocolHandlerFactory for ourput, but I was secretly hoping it's possible to keep in clean and nice. Then that's the point of this interface anyways? How does a working implementation look?Richardo
B
0

You can copy file to local first and then try open the container:

filePath = split.getPath();
final FileSystem fileSystem = filePath.getFileSystem(job);
Path localFile = new Path(filePath.getName());
fileSystem.createNewFile(localFile);
fileSystem.copyToLocalFile(filePath, localFile);
int result = container.open(filePath.getName(), IContainer.Type.READ, null);

This code works for me in the RecordReader class.

In your case you may copy the file to local first and then try to create the MediaReader

Brazier answered 24/4, 2013 at 11:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.