Exoplayer scrubbing has huge delay on local video files - java

I'm working on an app that plays video files that are stored on the device rather than streamed. I want the user to be able to analyze it, which involves features like playback speed, accurate scrubbing, frame export, all that jazz. The functionality works great except when I try to move the scrubber it takes a second or two to display the video frame. It feels really bad manually scrubbing slowly only to not see the frame you're currently on. The videos I expect to be used in the app aren't going to be ten minute videos or anything like that; more like a minute or two at most.
I've tried setting the seek parameter to closest sync when scrubbing but that has too much imprecision. I've also tried changing the buffer durations like so:
DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder(); builder.setBufferDurationsMs(1500, DefaultLoadControl.DEFAULT_MAX_BUFFER_MS, 1500, 1500); TrackSelector trackSelector = new DefaultTrackSelector(this);
But this had no visible change. Then I tried increasing the individual allocation size to 4mb, but that didn't work either. All the suggestions I've seen online relate the streaming, but my files are local.
If anyone could point me in the right direction I would greatly appreciate it.

Related

Real time logo detection in live camera preview with OpenCV on Android

I am new to computer vision but I am trying to code an android app which does the following:
Get the live camera preview and try to detect one logo in that (i have the logo in my resources). In real-time. Draw a rect around the logo if found. If there is no match, dont draw the rectangle.
I already tried a couple of things including template-matching and feature detection using ORB.
Why that didnt work:
Template-matching:
Issues with scaling and rotation. I tried a multi scale variant of it but a) the performance was really bad and b) the rectangle was of course always shown trying to search for the image. There was no way to actually confirm in the code if the logo was found or not.
ORB feature detection:
Also pretty slow (5-6 fps) but it worked ok-ish. The other problem was that also i never could be sure if the logo was in the picture or not. ORB found random matches even if the logo was not in the picture.
Like I said, I am very new to this. I would appreciate the help on what would be the best way to achieve:
Confirm if a picture A (around 200x200 pixels) is in ROI of camera picture (around 600x600 pixels).
This shouldnt take longer than 50ms per frame. I dont know if thats even possible though. So if a correct way to do this would take a bit longer than that, I would just do the work in a seperate thread and only analyze like every fifth camera frame or so.
Would appreciate any hints or code examples on how to achieve that. Thank you!
With logo detection, I would highly recommend using OpenCV HaarClassifier. It is easy to generate training samples from a collection of images of the logo, or one logo image with many distortions.
If you can use a few rules like the minimum and maximum size of the logo to be detected, and possible regions on the image where it can appear, you can run the detector at a speed better than you mention with ORB.

Using JMF to get a frame from a video

I have to take in a video file (.mpg or .avi or .mov ect...) using JMF and where the user stops the video (or pauses) I need to get that frame. If I can get it into a frame buffer then I'm golden (or even save the frame as a image file like jpg). As once I have the frame I just need to get RGB values from the pixels in the frame.(which I already have made a method for)
My issue here is I have not got any experience in JMF, but I have a source file that opens a window and then I can browse for a video file which seems to only work half the time.
I gather this is a bit of a tall order as I am pretty much in the dark on how to do this, and everything I try looking up is not of any real help, if someone knows a link that has some example code that would be wonderful.
Thanks.

Why doesn't MediaPlayer.seekTo(t) go to the exact specified instant "t"?

I'm trying to get the media player to play a specific range in a locally stored video. It doesn't seem to start at the specified time I tell it to.
Example: when I seek to 1000, it works. But when I seek to 1500, it goes to 2000 instead.
I also tried pausing seeking then starting on seek completion, it doesn't make any difference.
This is the code:
mediaPlayer.start();
mediaPlayer.seekTo(time);
Is this normal? Or am I using the media player the wrong way?
This is an encoding issue. Videos have keyframes (i-frames) that store more information than other frames. A non keyframe can be built only given the previous keyframe. Trying to display a non keyframe will show green spots and pixelated jittery screen.
Now, on some android devices there's no workaround implemented for this so you get this weird behavior. On a Nexus S for example seekTo() doesn't necessarily go to the specified frame. I tried other devices with the same android version and they seek just fine.

Screen recorder, issue when converting

I'm using BufferedImage to capture the screen images and then JpegImagesToMovie class to convert it to .mov, which I found online.
When I run the output file, it's at a super speed and not the original speed I recorded at. Can someone tell me what need to do in order to get a real-time speed video?
You probably need to put in Thread.sleep(1 / fps). Try to see if that works.
You are possibly using the Oracle's example to convert images to .mov. The problem is that the size of the file generated is very very large. You need to move to something more efficient and something with a little bit more abstraction. How about using Xuggler for making screen recorder ?
Now, to the question of making the movie slower. You need to reduce the frame rate. If you have need 60 fps, your 1 second will need to be shared by 60 frames. So for n fps, you need to have (1/n) sleep duration for your thread.

Bitmap size exceeds VM budget when game development

I am developing a game on android.Like tower defense.
I am using surface view.I am using some image as bitmap.(Spritesheets, tilesets, buttons, backgrounds,efects vs.)
Now images are nearly 5-6 mb.And i get this error when i run my game:
Bitmap size exceeds VM budget
19464192-byte external allocation too large for this process.
I call images like that
BitmapFactory.decodeResource(res, id)
and i put it to array.
I can't scale images.I am using all of them.
I tried that
options.inPurgeable=true;
and it work but the image is loading very slowly.I load a spritesheet with that and when it is loading, i get very very low fps.
What can I do?
I've had this problem too; there's really no solution other than to reduce the number/size of bitmaps that you have loaded at once. Some older Android devices only allocate 16MB to the heap for your whole application, and bitmaps are stored in memory uncompressed once you load them, so it's not hard to exceed 16MB with large backgrounds, etc. (An 854x480, 32-bit bitmap is about 1.6MB uncompressed.)
In my game I was able to get around it by only loading bitmaps that I was going to use in the current level (e.g. I have a single Bitmap object for the background that gets reloaded from resources each time it changes, rather than maintaining multiple Bitmaps in memory. I just maintain an int that tracks which resource I have loaded currently.)
Your sprite sheet is huge, so I think you're right that you'll need to reduce the size of your animations. Alternatively, loading from resources is decently fast, so you might be able to get away with doing something like only loading the animation strip for the character's current direction, and have him pause slightly when he turns while you replace it with the new animation strip. That might get complicated though.
Also, I highly recommend testing your app on the emulator with a VM heap set to 16mb, to make sure you've fixed the problem for all devices. (The emulator usually defaults to 24mb, so it's easy for that to go untested and generate some 1-star reviews after release.)
I am not a game dev however I would like to think I know Android enough.
Loading images of the size is almost certain to throw errors. Why are the images that file size?
There is an example at http://p-xr.com/android-tutorial-how-to-paint-animate-loop-and-remove-a-sprite/. If you notice he has an explosion sprite of only ~200Kb. Even a more detailed image would not take much more file space.
OK some suggestions:
Are you loading all your spritesheets onto a single sheet or is
each spritesheet in a seperate file? If they are all on one I would
split them up.
Lower the resolution of the images, an Android device is portable
and some only have a low resolution screen. For example the HTC
Wildfire has a resolution of 240x320 (LDPI device) and is quite a
common device. You have not stated the image dimensions so we can't be sure if this is practical.
Finally; I am not a game programmer but I found this tutorial (part of the same series) quite enlightening - http://p-xr.com/android-tutorial-2d-canvas-graphics/. I wonder if you are applying a pattern that is not appropriate for Android, however without code I cannot say.
Right something a little off topic but worth noting...
People under estimate the power of the View. While there is a certain amount of logic to using a SurfaceView, the standard View will do quite a lot on its own. A SurfaceView more often than not requires an underlying thread to run (that you will have to setup yourself) in order to make it work. A View however calls onDraw(), which can be utilized in a variety of ways including the postinvalidate() method (see What does postInvalidate() do?).
In any case it might be worth checking out this tutorial http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/. Personally, it was an excellent example of a custom View and what you can do with them. I rewrote a few sections and made a pocket watch app.

Categories