MJPEG on Android anyone?

All your problems with Audio, Video and Images.

MJPEG on Android anyone?

Postby ryank » Fri Apr 25, 2008 7:39 pm

I have made significant updates to LiveVision since I submitted it for the ADC, namely retrieiving current frames asynchronously... no idea why I didn't just get that done prior to submitting. Performs much better now.

The next thing I am going to tackle is MJPEG support. I have it working in java, but as you know, there are some libraries that do not exist for android.

Has anyone attempted mjpeg on Android yet?
User avatar
ryank
Developer
Developer
 
Posts: 43
Joined: Mon Jan 28, 2008 3:23 am

Top

Postby padde » Wed Apr 08, 2009 5:50 pm

This could help i think.. i know this post is old but i read that forum quite a while now
and always want to give a little contribution in return for the help and informationen i got.
And because i came across the same problem lately and solved it my chance for contribution
arrived :D

This is a little app to simply show an MJPEG stream.. okay a few gadgets like resize and fps overlay
too but nothing too fancy.

First the Test Activity to show how to use the MjpegView
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package de.mjpegsample;
  3.  
  4.  
  5.  
  6. import android.app.Activity;
  7.  
  8. import android.os.Bundle;
  9.  
  10. import android.view.Window;
  11.  
  12. import android.view.WindowManager;
  13.  
  14. import de.mjpegsample.MjpegView.MjpegInputStream;
  15.  
  16. import de.mjpegsample.MjpegView.MjpegView;
  17.  
  18.  
  19.  
  20. public class MjpegSample extends Activity {
  21.  
  22.         private MjpegView mv;
  23.  
  24.        
  25.  
  26.         public void onCreate(Bundle icicle) {
  27.  
  28.         super.onCreate(icicle);
  29.  
  30.        
  31.  
  32.         //sample public cam
  33.  
  34.         String URL = "http://www.gfp.cz:88/axis-cgi/mjpg/video.cgi?resolution=320x240";
  35.  
  36.        
  37.  
  38.         requestWindowFeature(Window.FEATURE_NO_TITLE);
  39.  
  40.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  41.  
  42.                              WindowManager.LayoutParams.FLAG_FULLSCREEN);
  43.  
  44.        
  45.  
  46.         mv = new MjpegView(this);
  47.  
  48.         setContentView(mv);        
  49.  
  50.        
  51.  
  52.         mv.setSource(MjpegInputStream.read(URL));
  53.  
  54.         mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);
  55.  
  56.         mv.showFps(true);
  57.  
  58.         }
  59.  
  60.        
  61.  
  62.         public void onPause() {
  63.  
  64.                 super.onPause();
  65.  
  66.                 mv.stopPlayback();
  67.  
  68.         }
  69.  
  70. }
  71.  
  72.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


In the MjpegInputStream Class the "real magic" happens
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package de.mjpegsample.MjpegView;
  3.  
  4.  
  5.  
  6. import java.io.BufferedInputStream;
  7.  
  8. import java.io.ByteArrayInputStream;
  9.  
  10. import java.io.DataInputStream;
  11.  
  12. import java.io.IOException;
  13.  
  14. import java.io.InputStream;
  15.  
  16. import java.net.URI;
  17.  
  18. import java.util.Properties;
  19.  
  20.  
  21.  
  22. import org.apache.http.HttpResponse;
  23.  
  24. import org.apache.http.client.ClientProtocolException;
  25.  
  26. import org.apache.http.client.methods.HttpGet;
  27.  
  28. import org.apache.http.impl.client.DefaultHttpClient;
  29.  
  30.  
  31.  
  32. import android.graphics.Bitmap;
  33.  
  34. import android.graphics.BitmapFactory;
  35.  
  36.  
  37.  
  38. public class MjpegInputStream extends DataInputStream {
  39.  
  40.     private final byte[] SOI_MARKER = { (byte) 0xFF, (byte) 0xD8 };
  41.  
  42.     private final byte[] EOF_MARKER = { (byte) 0xFF, (byte) 0xD9 };
  43.  
  44.     private final String CONTENT_LENGTH = "Content-Length";
  45.  
  46.     private final static int HEADER_MAX_LENGTH = 100;
  47.  
  48.     private final static int FRAME_MAX_LENGTH = 40000 + HEADER_MAX_LENGTH;
  49.  
  50.     private int mContentLength = -1;
  51.  
  52.        
  53.  
  54.     public static MjpegInputStream read(String url) {
  55.  
  56.         HttpResponse res;
  57.  
  58.         DefaultHttpClient httpclient = new DefaultHttpClient();        
  59.  
  60.         try {
  61.  
  62.             res = httpclient.execute(new HttpGet(URI.create(url)));
  63.  
  64.             return new MjpegInputStream(res.getEntity().getContent());                         
  65.  
  66.         } catch (ClientProtocolException e) {
  67.  
  68.         } catch (IOException e) {}
  69.  
  70.         return null;
  71.  
  72.     }
  73.  
  74.        
  75.  
  76.     public MjpegInputStream(InputStream in) {
  77.  
  78.         super(new BufferedInputStream(in, FRAME_MAX_LENGTH));
  79.  
  80.     }
  81.  
  82.        
  83.  
  84.     private int getEndOfSeqeunce(DataInputStream in, byte[] sequence)
  85.  
  86.         throws IOException
  87.  
  88.     {
  89.  
  90.         int seqIndex = 0;
  91.  
  92.         byte c;
  93.  
  94.         for(int i=0; i < FRAME_MAX_LENGTH; i++) {
  95.  
  96.             c = (byte) in.readUnsignedByte();
  97.  
  98.             if(c == sequence[seqIndex]) {
  99.  
  100.                 seqIndex++;
  101.  
  102.                 if(seqIndex == sequence.length) return i + 1;
  103.  
  104.             } else seqIndex = 0;
  105.  
  106.         }
  107.  
  108.         return -1;
  109.  
  110.     }
  111.  
  112.        
  113.  
  114.     private int getStartOfSequence(DataInputStream in, byte[] sequence)
  115.  
  116.         throws IOException
  117.  
  118.     {
  119.  
  120.         int end = getEndOfSeqeunce(in, sequence);
  121.  
  122.         return (end < 0) ? (-1) : (end - sequence.length);
  123.  
  124.     }
  125.  
  126.  
  127.  
  128.     private int parseContentLength(byte[] headerBytes)
  129.  
  130.         throws IOException, NumberFormatException
  131.  
  132.     {
  133.  
  134.         ByteArrayInputStream headerIn = new ByteArrayInputStream(headerBytes);
  135.  
  136.         Properties props = new Properties();
  137.  
  138.         props.load(headerIn);
  139.  
  140.         return Integer.parseInt(props.getProperty(CONTENT_LENGTH));
  141.  
  142.     }  
  143.  
  144.  
  145.  
  146.     public Bitmap readMjpegFrame() throws IOException {
  147.  
  148.         mark(FRAME_MAX_LENGTH);
  149.  
  150.         int headerLen = getStartOfSequence(this, SOI_MARKER);
  151.  
  152.         reset();
  153.  
  154.         byte[] header = new byte[headerLen];
  155.  
  156.         readFully(header);
  157.  
  158.         try {
  159.  
  160.             mContentLength = parseContentLength(header);
  161.  
  162.         } catch (NumberFormatException nfe) {
  163.  
  164.             mContentLength = getEndOfSeqeunce(this, EOF_MARKER);
  165.  
  166.         }
  167.  
  168.         reset();
  169.  
  170.         byte[] frameData = new byte[mContentLength];
  171.  
  172.         skipBytes(headerLen);
  173.  
  174.         readFully(frameData);
  175.  
  176.         return BitmapFactory.decodeStream(new ByteArrayInputStream(frameData));
  177.  
  178.     }
  179.  
  180. }
  181.  
  182.  
Parsed in 0.044 seconds, using GeSHi 1.0.8.4



And last but not least the MjpegView to put MjpegInputStreams to the Display :wink:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package de.mjpegsample.MjpegView;
  3.  
  4.  
  5.  
  6. import java.io.IOException;
  7.  
  8.  
  9.  
  10. import android.content.Context;
  11.  
  12. import android.graphics.Bitmap;
  13.  
  14. import android.graphics.Canvas;
  15.  
  16. import android.graphics.Color;
  17.  
  18. import android.graphics.Paint;
  19.  
  20. import android.graphics.PorterDuff;
  21.  
  22. import android.graphics.PorterDuffXfermode;
  23.  
  24. import android.graphics.Rect;
  25.  
  26. import android.graphics.Typeface;
  27.  
  28. import android.util.AttributeSet;
  29.  
  30. import android.view.SurfaceHolder;
  31.  
  32. import android.view.SurfaceView;
  33.  
  34.  
  35.  
  36. public class MjpegView extends SurfaceView implements SurfaceHolder.Callback {
  37.  
  38.     public final static int POSITION_UPPER_LEFT  = 9;
  39.  
  40.     public final static int POSITION_UPPER_RIGHT = 3;
  41.  
  42.     public final static int POSITION_LOWER_LEFT  = 12;
  43.  
  44.     public final static int POSITION_LOWER_RIGHT = 6;
  45.  
  46.  
  47.  
  48.     public final static int SIZE_STANDARD   = 1;
  49.  
  50.     public final static int SIZE_BEST_FIT   = 4;
  51.  
  52.     public final static int SIZE_FULLSCREEN = 8;
  53.  
  54.    
  55.  
  56.     private MjpegViewThread thread;
  57.  
  58.     private MjpegInputStream mIn = null;    
  59.  
  60.     private boolean showFps = false;
  61.  
  62.     private boolean mRun = false;
  63.  
  64.     private boolean surfaceDone = false;    
  65.  
  66.     private Paint overlayPaint;
  67.  
  68.     private int overlayTextColor;
  69.  
  70.     private int overlayBackgroundColor;
  71.  
  72.     private int ovlPos;
  73.  
  74.     private int dispWidth;
  75.  
  76.     private int dispHeight;
  77.  
  78.     private int displayMode;
  79.  
  80.  
  81.  
  82.     public class MjpegViewThread extends Thread {
  83.  
  84.         private SurfaceHolder mSurfaceHolder;
  85.  
  86.         private int frameCounter = 0;
  87.  
  88.         private long start;
  89.  
  90.         private String fps = "";
  91.  
  92.         private Bitmap ovl;
  93.  
  94.          
  95.  
  96.         public MjpegViewThread(SurfaceHolder surfaceHolder, Context context) {
  97.  
  98.             mSurfaceHolder = surfaceHolder;
  99.  
  100.         }
  101.  
  102.  
  103.  
  104.         private Rect destRect(int bmw, int bmh) {
  105.  
  106.             int tempx;
  107.  
  108.             int tempy;
  109.  
  110.             if (displayMode == MjpegView.SIZE_STANDARD) {
  111.  
  112.                 tempx = (dispWidth / 2) - (bmw / 2);
  113.  
  114.                 tempy = (dispHeight / 2) - (bmh / 2);
  115.  
  116.                 return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
  117.  
  118.             }
  119.  
  120.             if (displayMode == MjpegView.SIZE_BEST_FIT) {
  121.  
  122.                 float bmasp = (float) bmw / (float) bmh;
  123.  
  124.                 bmw = dispWidth;
  125.  
  126.                 bmh = (int) (dispWidth / bmasp);
  127.  
  128.                 if (bmh > dispHeight) {
  129.  
  130.                     bmh = dispHeight;
  131.  
  132.                     bmw = (int) (dispHeight * bmasp);
  133.  
  134.                 }
  135.  
  136.                 tempx = (dispWidth / 2) - (bmw / 2);
  137.  
  138.                 tempy = (dispHeight / 2) - (bmh / 2);
  139.  
  140.                 return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
  141.  
  142.             }
  143.  
  144.             if (displayMode == MjpegView.SIZE_FULLSCREEN)
  145.  
  146.                 return new Rect(0, 0, dispWidth, dispHeight);
  147.  
  148.             return null;
  149.  
  150.         }
  151.  
  152.          
  153.  
  154.         public void setSurfaceSize(int width, int height) {
  155.  
  156.             synchronized(mSurfaceHolder) {
  157.  
  158.                 dispWidth = width;
  159.  
  160.                 dispHeight = height;
  161.  
  162.             }
  163.  
  164.         }
  165.  
  166.          
  167.  
  168.         private Bitmap makeFpsOverlay(Paint p) {
  169.  
  170.             Rect b = new Rect();
  171.  
  172.             p.getTextBounds(fps, 0, fps.length(), b);
  173.  
  174.  
  175.  
  176. // false indentation to fix forum layout            
  177.  
  178. Bitmap bm = Bitmap.createBitmap(b.width(), b.height(), Bitmap.Config.ARGB_8888);
  179.  
  180.  
  181.  
  182.             Canvas c = new Canvas(bm);
  183.  
  184.             p.setColor(overlayBackgroundColor);
  185.  
  186.             c.drawRect(0, 0, b.width(), b.height(), p);
  187.  
  188.             p.setColor(overlayTextColor);
  189.  
  190.             c.drawText(fps, -b.left, b.bottom-b.top-p.descent(), p);
  191.  
  192.             return bm;           
  193.  
  194.         }
  195.  
  196.  
  197.  
  198.         public void run() {
  199.  
  200.             start = System.currentTimeMillis();
  201.  
  202.             PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
  203.  
  204.             Bitmap bm;
  205.  
  206.             int width;
  207.  
  208.             int height;
  209.  
  210.             Rect destRect;
  211.  
  212.             Canvas c = null;
  213.  
  214.             Paint p = new Paint();
  215.  
  216.             while (mRun) {
  217.  
  218.                 if(surfaceDone) {
  219.  
  220.                     try {
  221.  
  222.                         c = mSurfaceHolder.lockCanvas();
  223.  
  224.                         synchronized (mSurfaceHolder) {
  225.  
  226.                             try {
  227.  
  228.                                 bm = mIn.readMjpegFrame();
  229.  
  230.                                 destRect = destRect(bm.getWidth(),bm.getHeight());
  231.  
  232.                                 c.drawColor(Color.BLACK);
  233.  
  234.                                 c.drawBitmap(bm, null, destRect, p);
  235.  
  236.                                 if(showFps) {
  237.  
  238.                                     p.setXfermode(mode);
  239.  
  240.                                     if(ovl != null) {
  241.  
  242.  
  243.  
  244. // false indentation to fix forum layout                                                 
  245.  
  246. height = ((ovlPos & 1) == 1) ? destRect.top : destRect.bottom-ovl.getHeight();
  247.  
  248. width  = ((ovlPos & <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" /> == <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" /> ? destRect.left : destRect.right -ovl.getWidth();
  249.  
  250.  
  251.  
  252.                                         c.drawBitmap(ovl, width, height, null);
  253.  
  254.                                     }
  255.  
  256.                                     p.setXfermode(null);
  257.  
  258.                                     frameCounter++;
  259.  
  260.                                     if((System.currentTimeMillis() - start) >= 1000) {
  261.  
  262.                                         fps = String.valueOf(frameCounter)+"fps";
  263.  
  264.                                         frameCounter = 0;
  265.  
  266.                                         start = System.currentTimeMillis();
  267.  
  268.                                         ovl = makeFpsOverlay(overlayPaint);
  269.  
  270.                                     }
  271.  
  272.                                 }
  273.  
  274.                             } catch (IOException e) {}
  275.  
  276.                         }
  277.  
  278.                     } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); }
  279.  
  280.                 }
  281.  
  282.             }
  283.  
  284.         }
  285.  
  286.     }
  287.  
  288.  
  289.  
  290.     private void init(Context context) {
  291.  
  292.         SurfaceHolder holder = getHolder();
  293.  
  294.         holder.addCallback(this);
  295.  
  296.         thread = new MjpegViewThread(holder, context);
  297.  
  298.         setFocusable(true);
  299.  
  300.         overlayPaint = new Paint();
  301.  
  302.         overlayPaint.setTextAlign(Paint.Align.LEFT);
  303.  
  304.         overlayPaint.setTextSize(12);
  305.  
  306.         overlayPaint.setTypeface(Typeface.DEFAULT);
  307.  
  308.         overlayTextColor = Color.WHITE;
  309.  
  310.         overlayBackgroundColor = Color.BLACK;
  311.  
  312.         ovlPos = MjpegView.POSITION_LOWER_RIGHT;
  313.  
  314.         displayMode = MjpegView.SIZE_STANDARD;
  315.  
  316.         dispWidth = getWidth();
  317.  
  318.         dispHeight = getHeight();
  319.  
  320.     }
  321.  
  322.    
  323.  
  324.     public void startPlayback() {
  325.  
  326.         if(mIn != null) {
  327.  
  328.             mRun = true;
  329.  
  330.             thread.start();            
  331.  
  332.         }
  333.  
  334.     }
  335.  
  336.    
  337.  
  338.     public void stopPlayback() {
  339.  
  340.         mRun = false;
  341.  
  342.         boolean retry = true;
  343.  
  344.         while(retry) {
  345.  
  346.             try {
  347.  
  348.                 thread.join();
  349.  
  350.                 retry = false;
  351.  
  352.             } catch (InterruptedException e) {}
  353.  
  354.         }
  355.  
  356.     }
  357.  
  358.  
  359.  
  360.     public MjpegView(Context context, AttributeSet attrs) {
  361.  
  362.         super(context, attrs); init(context);
  363.  
  364.     }
  365.  
  366.  
  367.  
  368.     public void surfaceChanged(SurfaceHolder holder, int f, int w, int h) {
  369.  
  370.         thread.setSurfaceSize(w, h);
  371.  
  372.     }
  373.  
  374.  
  375.  
  376.     public void surfaceDestroyed(SurfaceHolder holder) {
  377.  
  378.         surfaceDone = false;
  379.  
  380.         stopPlayback();
  381.  
  382.     }
  383.  
  384.    
  385.  
  386.     public MjpegView(Context context) { super(context); init(context); }    
  387.  
  388.     public void surfaceCreated(SurfaceHolder holder) { surfaceDone = true; }
  389.  
  390.     public void showFps(boolean b) { showFps = b; }
  391.  
  392.     public void setSource(MjpegInputStream source) { mIn = source; startPlayback();}
  393.  
  394.     public void setOverlayPaint(Paint p) { overlayPaint = p; }
  395.  
  396.     public void setOverlayTextColor(int c) { overlayTextColor = c; }
  397.  
  398.     public void setOverlayBackgroundColor(int c) { overlayBackgroundColor = c; }
  399.  
  400.     public void setOverlayPosition(int p) { ovlPos = p; }
  401.  
  402.     public void setDisplayMode(int s) { displayMode = s; }
  403.  
  404. }
  405.  
  406.  
Parsed in 0.067 seconds, using GeSHi 1.0.8.4


Runs on newest SDK build Android SDK 1.1_r1 (at time of writing this)


Greets
Padde



--- Edited 09.04.2009 - 19:36 ---
Reason: less and more efficient Code + load speed improvements
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby rober-mpp » Sat Sep 26, 2009 3:42 am

Runs great on sdk-linux_x86-1.5_r1.

I'm being able to stream to the emulator using vlc 1.0.2 locally with the following command:

$ vlc -vvv v4l2:///dev/video0 --sout '#transcode{vcodec=MJPG,vb=800,scale=1,width=480,height=320,acodec=none}:duplicate{dst=standard{access=http,mux=mpjpeg,dst=localhost:1234},dst=display}'

Thanks!!
rober-mpp
Freshman
Freshman
 
Posts: 2
Joined: Sat Sep 26, 2009 3:12 am

Fail to run on 1.5 or 1.6

Postby yaozr » Tue Oct 27, 2009 4:36 pm

Hi a new android fan:

I crated a new empty Android project under 1.6, create 2 new package according to the 3 java class,
package de.mjpegsample contains MjpegSample.java
package de.mjpegsample.MjpegView contains MjpegInputStream.java and MjpegView.java

it seems fine but when it run it always give only a black screen both on emulator or ADP phone, I tred on 1.5 and it was the same...

Any tip would be greatly appreciated!

yaozr
yaozr
Freshman
Freshman
 
Posts: 2
Joined: Tue Oct 27, 2009 4:25 pm

Postby padde » Tue Oct 27, 2009 5:36 pm

Have you added the internet permission to your manifest?

--- Edit ---
Added the hole eclipse project.. new cam url.. more to see 24/7 :)
Attachments
MjpegDemo.rar
(9.42 KiB) Downloaded 2965 times
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby rober-mpp » Tue Oct 27, 2009 6:20 pm

Some things that went wrong while i was implementing this code:

- Blocked ports within the network.
- Try to connect to the streaming server with another client to see that is actually streaming. ( should work with two vlc, as server with the posted command and another one as client )
- As padde said, the permissions in the manifest.

Cheers
rober-mpp
Freshman
Freshman
 
Posts: 2
Joined: Sat Sep 26, 2009 3:12 am

Top

Postby yaozr » Tue Oct 27, 2009 8:40 pm

Many thanks! yes after add the permission it works like charm! Great job and thx again!
yaozr
Freshman
Freshman
 
Posts: 2
Joined: Tue Oct 27, 2009 4:25 pm

Postby wirblix » Mon Nov 09, 2009 4:39 pm

Thanks so much for this code. I'm getting mixed results from different camera types though, and I'm wondering if you could help me to understand why, and possibly suggest a solution. On some IP cameras, the mjpeg stream viewed from this code is anywhere from 5-10 seconds behind actual reality. (ie, I wave my hand in front of the camera, count to 10, then I see it on the android device). I'm getting great framerates, just from 10 seconds ago. :) On other cameras though, it's almost real-time. I'm not familiar enough with the inner workings of the mjpeg format to make sense of this problem. Any ideas?
wirblix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Wed Apr 29, 2009 12:10 am

Postby padde » Mon Nov 09, 2009 8:49 pm

Hmm.. there are to many variables that might cause this.

1. Internet connection
2. Camera settings
3. Device memory load

Just the first 3 that came to my mind.
It depends on your test setup to tell which one is the culprit.
When i was developing the app wherefore i coded this MJPEG stuff
i had the chance to test several IP-Cams locally with various settings
from 2 major professional manufacturers. In my tests the framerate
was almost always limited by the Cam settings. If i remember right
the highest fps i was able to achieve was 30fps but that was also the
limit of the cam. But this are scenarios far beyond real world usage.
Common max. fps settings are in the 5 to 15 frames per second ballpark
for remote access of IP-Cams.

You could log some debug infos to check if at some point the garbage collection
freaks out and slows down the hole thing.

Tip:
If you do some debug logs think about logging the image sizes too and add them up.
Afterwards limiting framerates via settings actually makes sense. :lol:
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby wirblix » Tue Nov 10, 2009 3:33 pm

Thanks for the response. I'm testing on a local LAN (wifi on camera, wifi on android device), so the internet connection is a non-issue. As for the camera, it's an Axis 207W. You were right about limiting the framerate - I set it to 5 on the camera and at first it was much closer to real-time. However over time, it seems to fall behind. If I stop and restart your mjpegdemo app, it's good again for awhile. Maybe the android device is taking little time-outs to do something else (cleanup, mail-sync, etc.) and causing the frame viewer to fall behind real-time. Is there a clean way to force the code to drop frames occasionally to maintain sync? (Or am I way off?)
wirblix
Junior Developer
Junior Developer
 
Posts: 13
Joined: Wed Apr 29, 2009 12:10 am

Postby padde » Tue Nov 10, 2009 9:24 pm

Hmm so point 3 from my list of suspects is the culprit here.
When its fixed by restarting the app.. then i guess i fill up
some memory the GC cant clean up. I have to little knowledge
of Java VMs or the Dalvik in this case to narrow it down to
specific parts in the code that might cause this problem.
These days i am really busy and cant realy look into it.. maybe
about the holiday season.
If you start some investigation by yourself keep me informed :)

About the drop frame to stay in sync thingy... MJPEG isnt really
a video codec like others. Its a simple chain of JPEGs seperated
by a delimiter string. There is no information about sync or speed
at all in the stream itself.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Mjpeg files?

Postby wally1944 » Mon Nov 16, 2009 6:12 pm

Has anyone modified this code to handle local mjpeg avi files? I assume this would be trivial?
wally1944
Freshman
Freshman
 
Posts: 3
Joined: Mon Nov 16, 2009 6:03 pm

Postby padde » Mon Nov 16, 2009 6:43 pm

If you could provide a small test file i will add this functionality :)
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Mjpeg files?

Postby wally1944 » Mon Nov 16, 2009 7:26 pm

Here is a short sample avi file with mjpeg.
Attachments
A650 IS-MVI_5623.zip
Sample mjpeg file in an avi container generated by a Canon A650 IS.
(4.38 MiB) Downloaded 1072 times
wally1944
Freshman
Freshman
 
Posts: 3
Joined: Mon Nov 16, 2009 6:03 pm

Postby padde » Mon Nov 16, 2009 8:44 pm

I tested the obvious solution ideas but it doesnt work.
I would have to write a complete avi container parser i think to get those
pictures.. and because its packed within the avi container its synced to a
timescale so i would have to implement something to take care about fps
and syncing too.

You could try one of the mediaplayers from the market.. or ask their
developers for mjpeg support in case it isnt supported out of the box.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Top
Next

Return to Multimedia Problems

Who is online

Users browsing this forum: Exabot [Bot] and 18 guests