3

I am following this code on stack Android ICS and MJPEG using AsyncTask

which is to stream mjpeg for java (code below as well). what seems to be happening is the mjpegview class is creating the mjpeg object and forcing the main activity to set it as its content view. is there a way i can throw the surfaceholder in the mjpegviewer class into a surface view defined in my xml so i can do other things? i tried to create a surface view and replace it in the mjpeg viewer class but it crashes.. does anyone have an idea of how I can just put it into my own surface view?

main act package com.example.mjpeg;

 import java.io.IOException;
 import java.net.URI;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.DefaultHttpClient;
 import com.example.mjpeg.mjpegstream;
 import com.example.mjpeg.mjpegview;
 import android.app.Activity;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.SurfaceView;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.Toast;

public class MainActivity extends Activity {
private static final String TAG = "MainActivity";

private mjpegview mv;

   public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //sample public cam
    String URL = "http://tfdsfdfdsfd.cgi";
    //   mv = new mjpegview(this);

 setContentView(R.layout.activity_main);
 setContentView(mv); //set preview as activity content 

 //    setContentView(mv);        

new DoRead().execute(URL);
}
public void onPause()
{
    super.onPause();
    mv.stopPlayback();
}

public class DoRead extends AsyncTask<String, Void, mjpegstream> {
    protected mjpegstream doInBackground(String... url) {
        //TODO: if camera has authentication deal with it and don't just not work
        HttpResponse res = null;
        DefaultHttpClient httpclient = new DefaultHttpClient();     
        Log.d(TAG, "1. Sending http request");
        try {
            res = httpclient.execute(new HttpGet(URI.create(url[0])));
            Log.d(TAG, "2. Request finished, status = " + res.getStatusLine().getStatusCode());
            if(res.getStatusLine().getStatusCode()==401){
                //You must turn off camera User Access Control before this will work
                return null;
            }
            return new mjpegstream(res.getEntity().getContent());  
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            Log.d(TAG, "Request failed-ClientProtocolException", e);
            //Error connecting to camera
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "Request failed-IOException", e);
            //Error connecting to camera
        }

        return null;
    }

    protected void onPostExecute(mjpegstream result) {
        mv.setSource(result);
        mv.setDisplayMode(mjpegview.SIZE_BEST_FIT);
        mv.showFps(true);
    }
}
}

mjpegviewer class

    package com.example.mjpeg;


    import java.io.IOException;

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.PixelFormat;
    import android.graphics.PorterDuff;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.graphics.Typeface;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;

    public class mjpegview extends SurfaceView implements SurfaceHolder.Callback {
        private static final String TAG = "mjpegview";

        public final static int POSITION_UPPER_LEFT  = 9;
        public final static int POSITION_UPPER_RIGHT = 3;
        public final static int POSITION_LOWER_LEFT  = 12;
        public final static int POSITION_LOWER_RIGHT = 6;

        public final static int SIZE_STANDARD   = 1; 
        public final static int SIZE_BEST_FIT   = 4;
        public final static int SIZE_FULLSCREEN = 8;

        private MjpegViewThread thread;
        private mjpegstream mIn = null;    
        private boolean showFps = false;
        private boolean mRun = false;
        private boolean surfaceDone = false;    
        private Paint overlayPaint;
        private int overlayTextColor;
        private int overlayBackgroundColor;
        private int ovlPos;
        private int dispWidth;
        private int dispHeight;
        private int displayMode;

        public class MjpegViewThread extends Thread {
            private SurfaceHolder mSurfaceHolder;
            private int frameCounter = 0;
            private long start;
            private Bitmap ovl;

            public MjpegViewThread(SurfaceHolder surfaceHolder, Context context) {
            SurfaceView camSurface = (SurfaceView) findViewById(R.id.camSurface); 
                 SurfaceHolder mSurfaceholder = camSurface.getHolder();
              mSurfaceHolder = surfaceHolder;

            }

            private Rect destRect(int bmw, int bmh) {
                int tempx;
                int tempy;
                if (displayMode == mjpegview.SIZE_STANDARD) {
                    tempx = (dispWidth / 2) - (bmw / 2);
                    tempy = (dispHeight / 2) - (bmh / 2);
                    return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
                }
                if (displayMode == mjpegview.SIZE_BEST_FIT) {
                    float bmasp = (float) bmw / (float) bmh;
                    bmw = dispWidth;
                    bmh = (int) (dispWidth / bmasp);
                    if (bmh > dispHeight) {
                        bmh = dispHeight;
                        bmw = (int) (dispHeight * bmasp);
                    }

                     tempx = (dispWidth / 2) - (bmw / 2);
                  //  tempy = (dispHeight / 4) - (bmh / 2);
                     tempy = 0;
                    return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
                }
                if (displayMode == mjpegview.SIZE_FULLSCREEN){
                    return new Rect(0, 0, dispWidth, dispHeight);
                }
                return null;
            }

            public void setSurfaceSize(int width, int height) {
                synchronized(mSurfaceHolder) {
                   dispWidth = width;
                  dispHeight = height;
             }
        }

            private Bitmap makeFpsOverlay(Paint p, String text) {
                Rect b = new Rect();
                p.getTextBounds(text, 0, text.length(), b);
                int bwidth  = b.width()+2;
                int bheight = b.height()+2;
                Bitmap bm = Bitmap.createBitmap(bwidth, bheight, Bitmap.Config.ARGB_8888);
                Canvas c = new Canvas(bm);
      //          p.setColor(overlayBackgroundColor);
                c.drawRect(0, 0, bwidth, bheight, p);
             //   p.setColor(overlayTextColor);
         //       c.drawText(text, -b.left+1, (bheight/2)-((p.ascent()+p.descent())/2)+1, p);
                return bm;           
            }

            public void run() {
                start = System.currentTimeMillis();
                PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);
                Bitmap bm;
                int width;
                int height;
                Rect destRect;
                Canvas c = null;
                Paint p = new Paint();
                String fps;
                while (mRun) {
                    if(surfaceDone) {
                        try {

                            c = mSurfaceHolder.lockCanvas();
                            synchronized (mSurfaceHolder) {
                                try {
                                    bm = mIn.readMjpegFrame();
                                    destRect = destRect(bm.getWidth(),bm.getHeight());
                           //  c.drawColor(Color.BLACK);
                                    c.drawBitmap(bm, null, destRect, p);
                                    if(showFps) {
                                        p.setXfermode(mode);
                                        if(ovl != null) {
                                        height = ((ovlPos & 1) == 1) ? destRect.top : destRect.bottom-ovl.getHeight();
                                        width  = ((ovlPos & 8) == 8) ? destRect.left : destRect.right -ovl.getWidth();
                                            c.drawBitmap(ovl, width, height, null);
                                        }
                                        p.setXfermode(null);
                                        frameCounter++;
                                        if((System.currentTimeMillis() - start) >= 1000) {
                                            fps = String.valueOf(frameCounter)+" fps";
                                            frameCounter = 0; 
                                            start = System.currentTimeMillis();
                                            ovl = makeFpsOverlay(overlayPaint, fps);
                                        }
                                    }
                                } catch (IOException e) {
                                    e.getStackTrace();
                                    Log.d(TAG, "catch IOException hit in run", e);
                                }
                            }
                        } finally { 
                            if (c != null) {
                                mSurfaceHolder.unlockCanvasAndPost(c); 
                            }
                        }
                    }
                }
            }
        }

        private void init(Context context) {
            SurfaceHolder holder = getHolder();
            getHolder().setFormat(PixelFormat.TRANSLUCENT);
            holder.addCallback(this);
            thread = new MjpegViewThread(holder, context);
           // setFocusable(true);
            overlayPaint = new Paint();
            overlayPaint.setTextAlign(Paint.Align.LEFT);
            overlayPaint.setTextSize(12);
            overlayPaint.setTypeface(Typeface.DEFAULT);
            overlayTextColor = Color.WHITE;
           // overlayBackgroundColor = Color.BLACK;
            ovlPos = mjpegview.POSITION_LOWER_RIGHT;
            displayMode = mjpegview.SIZE_STANDARD;
            dispWidth = getWidth();
            dispHeight = getHeight();
        }

        public void startPlayback() { 
            if(mIn != null) {
                mRun = true;
                thread.start();         
            }
        }

        public void stopPlayback() { 
            mRun = false;
            boolean retry = true;
            while(retry) {
                try {
                    thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                    e.getStackTrace();
                    Log.d(TAG, "catch IOException hit in stopPlayback", e);
                }
            }
        }

        public mjpegview(Context context, AttributeSet attrs) { 
            super(context, attrs); init(context); 
        }

        public void surfaceChanged(SurfaceHolder holder, int f, int w, int h) { 
            thread.setSurfaceSize(w, h); 
        }

        public void surfaceDestroyed(SurfaceHolder holder) { 
            surfaceDone = false; 
            stopPlayback(); 
        }

        public mjpegview(Context context) { 
            super(context);
            init(context); 
        }

        public void surfaceCreated(SurfaceHolder holder) { 
            surfaceDone = true; 
        }

        public void showFps(boolean b) { 
            showFps = b; 
        }

        public void setSource(mjpegstream source) { 
            mIn = source;
            startPlayback();
        }

        public void setOverlayPaint(Paint p) { 
            overlayPaint = p; 
        }

        public void setOverlayTextColor(int c) { 
            overlayTextColor = c; 
        }

        public void setOverlayBackgroundColor(int c) { 
            overlayBackgroundColor = c; 
        }

        public void setOverlayPosition(int p) { 
          ovlPos = p; 
        }

        public void setDisplayMode(int s) { 
            displayMode = s; 
        }
    }

mjpeg stream class

    package com.example.mjpeg;

    import java.io.BufferedInputStream;
    import java.io.ByteArrayInputStream;
    import java.io.DataInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;

    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.util.Log;

    public class mjpegstream extends DataInputStream {
        private static final String TAG = "mjpegstream";

        private final byte[] SOI_MARKER = { (byte) 0xFF, (byte) 0xD8 };
        private final byte[] EOF_MARKER = { (byte) 0xFF, (byte) 0xD9 };
        private final String CONTENT_LENGTH = "Content-Length";
        private final static int HEADER_MAX_LENGTH = 100;
        private final static int FRAME_MAX_LENGTH = 40000 + HEADER_MAX_LENGTH;
        private int mContentLength = -1;

        public mjpegstream(InputStream in) {
            super(new BufferedInputStream(in, FRAME_MAX_LENGTH));
        }

        private int getEndOfSeqeunce(DataInputStream in, byte[] sequence) throws IOException {
            int seqIndex = 0;
            byte c;
            for(int i=0; i < FRAME_MAX_LENGTH; i++) {
                c = (byte) in.readUnsignedByte();
                if(c == sequence[seqIndex]) {
                    seqIndex++;
                    if(seqIndex == sequence.length) {
                        return i + 1;
                    }
                } else {
                    seqIndex = 0;
                }
            }
            return -1;
        }

        private int getStartOfSequence(DataInputStream in, byte[] sequence) throws IOException {
            int end = getEndOfSeqeunce(in, sequence);
            return (end < 0) ? (-1) : (end - sequence.length);
        }

        private int parseContentLength(byte[] headerBytes) throws IOException, NumberFormatException {
            ByteArrayInputStream headerIn = new ByteArrayInputStream(headerBytes);
            Properties props = new Properties();
            props.load(headerIn);
            return Integer.parseInt(props.getProperty(CONTENT_LENGTH));
        }   

        public Bitmap readMjpegFrame() throws IOException {
            mark(FRAME_MAX_LENGTH);
            int headerLen = getStartOfSequence(this, SOI_MARKER);
            reset();
            byte[] header = new byte[headerLen];
            readFully(header);
            try {
                mContentLength = parseContentLength(header);
            } catch (NumberFormatException nfe) { 
                nfe.getStackTrace();
                Log.d(TAG, "catch NumberFormatException hit", nfe);
                mContentLength = getEndOfSeqeunce(this, EOF_MARKER); 
            }
            reset();
            byte[] frameData = new byte[mContentLength];
            skipBytes(headerLen);
            readFully(frameData);
            return BitmapFactory.decodeStream(new ByteArrayInputStream(frameData));
        }
    }

any help would be greatly appreciated thank you

     mv = new mjpegview(this);

// setContentView(R.layout.activity_main); setContentView(mv); //set preview as activity content

   View stolenView = mv;

   // set your own view
   setContentView(R.layout.activity_main);

View view =(findViewById(R.id.vids));

((ViewGroup) view).addView(stolenView);
Community
  • 1
  • 1
Dnaso
  • 1,335
  • 4
  • 22
  • 48

1 Answers1

1

There is some nasty trick that you can try. I didn't try it by my self but I give you the idea.

Steal the view from mjpegview. First thing let him set the content view, then take it like this:

// obtain mjpegview reference
View stolenView = getWindow().getDecorView().findViewById(android.R.id.content);

// set your own view
setContentView(R.layout.activity_main);

and now just add it to your view.

  (ParentView)(findViewById(R.id.mjpegviewContainer)).addView(stolenView);
Ilya Gazman
  • 31,250
  • 24
  • 137
  • 216
  • mv = new mjpegview(this); // setContentView(R.layout.activity_main); setContentView(mv); //set preview as activity content View stolenView = mv; // set your own view setContentView(R.layout.activity_main); View view =(findViewById(R.id.vids)); ((ViewGroup) view).addView(stolenView); – Dnaso May 12 '13 at 21:48