Android ICS and MJPEG using AsyncTask

瘦欲@ 提交于 2019-11-26 12:07:32

nice work! For your problem with onResume(), isn't it enough when you move the following code from onCreate() to onResume()?

    //sample public cam 
    String URL = "http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=800x600&amp%3bdummy=1333689998337"; 

    mv = new MjpegView(this); 
    setContentView(mv);         

    new DoRead().execute(URL); 

Then you simply recreate the View and new instance of the AsyncTask... I tried it and it works for me...

It'll be helpful for the newbies that if you want to access your ip camera having a username or password , you might want to add this to your DefaultHttpClient and the above code will work for cameras that require authentication

 CredentialsProvider provider = new BasicCredentialsProvider();
            UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("yourusername", "yourpassword");
            provider.setCredentials(AuthScope.ANY, credentials);
            DefaultHttpClient httpclient = new DefaultHttpClient();
            httpclient.setCredentialsProvider(provider);
Rusty

thanks for the code, it's very helpful

I want to suggest few optimization tips, which are already used in my code, overall performance can be easily increased by a few times.

  1. I removed memory allocations during frame reading, where possible

    private final static int HEADER_MAX_LENGTH = 100;
    private final static int FRAME_MAX_LENGTH = 200000 + HEADER_MAX_LENGTH;
    private final String CONTENT_LENGTH = "Content-Length:";
    private final String CONTENT_END = "\r\n";
    private final static byte[] gFrameData = new byte[FRAME_MAX_LENGTH];
    private final static byte[] gHeader = new byte[HEADER_MAX_LENGTH];
    BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
    
    public Bitmap readMjpegFrame() throws IOException {
    
        mark(FRAME_MAX_LENGTH);
        int headerLen = getStartOfSequence(SOI_MARKER);
    
        if(headerLen < 0)
            return false;
    
        reset();
        readFully(gHeader, 0, headerLen);
    
        int contentLen;
    
        try
        {
            contentLen = parseContentLength(gHeader, headerLen);
        } catch (NumberFormatException nfe) 
        {
            nfe.getStackTrace();
            Log.d(TAG, "catch NumberFormatException hit", nfe);
            contentLen = getEndOfSequence(EOF_MARKER);
        }
    
        readFully(gFrameData, 0, contentLen);
    
        Bitmap bm = BitmapFactory.decodeByteArray(gFrameData, 0, contentLen, bitmapOptions);
        bitmapOptions.inBitmap = bm;
    
        return bm;
    }
    
  2. Optimizing parseContentLength, removing String operations as much as possible

    byte[] CONTENT_LENGTH_BYTES;
    byte[] CONTENT_END_BYTES;
    
    public MjpegInputStream(InputStream in)
    {
        super(new BufferedInputStream(in, FRAME_MAX_LENGTH));
    
        bitmapOptions.inSampleSize = 1;
        bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        bitmapOptions.inPreferQualityOverSpeed = false;
        bitmapOptions.inPurgeable = true;
        try
        {
            CONTENT_LENGTH_BYTES = CONTENT_LENGTH.getBytes("UTF-8");
            CONTENT_END_BYTES = CONTENT_END.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) 
        {
            e.printStackTrace();
        }
    }
    
    private int findPattern(byte[] buffer, int bufferLen, byte[] pattern, int offset)
    {
        int seqIndex = 0;
        for(int i=offset; i < bufferLen; ++i)
        {
            if(buffer[i] == pattern[seqIndex])
            {
                ++seqIndex;
                if(seqIndex == pattern.length)
                {
                    return i + 1;
                }
            } else
            {
                seqIndex = 0;
            }
        }
    
        return -1;
    }
    
    
    
    private int parseContentLength(byte[] headerBytes, int length) throws IOException, NumberFormatException
    {
        int begin = findPattern(headerBytes, length, CONTENT_LENGTH_BYTES, 0);
        int end = findPattern(headerBytes, length, CONTENT_END_BYTES, begin) - CONTENT_END_BYTES.length;
    
        // converting string to int
        int number = 0;
        int radix = 1;
        for(int i = end - 1; i >= begin; --i)
        {
            if(headerBytes[i] > 47 && headerBytes[i] < 58)
            {
                number += (headerBytes[i] - 48) * radix;
                radix *= 10;
            }
        }
    
        return number;
    }
    

There could be mistakes in the code since I was rewriting it for stackoverflow, originally I'm using 2 threads, one is reading frames and another is rendering.

I hope it will help for someone.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!