2017-09-05 9 views
5

मैं LogCat #onPreviewFrame() कई बार लॉग कर करने की उम्मीद कर रहा हूँ, लेकिन यह केवल की तरह चयनित उपकरणों पर काम करता है:कैमरा onPreviewFrame

  • Samsung Galaxy S6 (7.0)
  • Samsung Galaxy S6 (6.0.1)
  • एलजी लियोन (5.0.1)

लेकिन निम्नलिखित उपकरणों पर नहीं करता है:

public CameraSurfaceView(Context context, AttributeSet set) { 
    super(context, set); 
    Log.d(TAG, "CameraSurfaceView(context, set)"); 

    // Get the Surface Holder 
    this.holder = this.getHolder(); 
    this.holder.addCallback(this); 
    this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    try { 
    // Turn on the Camera 
    this.camera = Camera.open(); 
    } catch (Exception ex) { 
    Log.e(TAG, "#surfaceCreated() error=" + ex.getMessage(), ex); 
    } 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    Log.d(TAG, "#surfaceChanged()"); 

    if (holder.getSurface() == null) { 
    // preview surface does not exist 
    return; 
    } 
    if (camera == null) { 
    // camera does not exist 
    return; 
    } 

    // This allows us to make our own draw calls to this canvas 
    this.setWillNotDraw(false); 
    // Initialize canvas variables 
    previewPaint = new Paint(); 
    // Initialize preview variables 
    deviceWidth = width; 
    deviceHeight = height; 
    Camera.Size previewSize = this.camera.getParameters().getPreviewSize(); 
    previewWidth = previewSize.width; 
    previewHeight = previewSize.height; 
    previewBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888); 

    // Initialize Scale Variables 
    previewScaleMatrix = new Matrix(); 
    previewScaleMatrix.setScale(deviceWidth/(float) previewWidth, 
     deviceHeight/(float) previewHeight, deviceWidth/2.0f, deviceHeight/2.0f); 

    // Initialize RenderScript variables 
    rs = RenderScript.create(getContext()); 

    // RenderScript YUV to RGB 
    yuvToRgbScript = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); 
    Type.Builder previewRgbaType = 
     new Type.Builder(rs, Element.RGBA_8888(rs)).setX(previewWidth).setY(previewHeight); 
    yuvToRgbOut = Allocation.createTyped(rs, previewRgbaType.create(), Allocation.USAGE_SCRIPT); 

    // RenderScript Invert 
    invertScript = new ScriptC_invert(rs); 
    invertOut = Allocation.createTyped(rs, yuvToRgbOut.getType(), Allocation.USAGE_SCRIPT); 

    // Set color effect to none 
    parameters.setColorEffect(Camera.Parameters.EFFECT_NONE); 
    camera.setParameters(parameters); 

    // Set the preview callback 
    Log.d(TAG, "#surfaceChanged() camera.setPreviewCallback()"); 
    camera.setPreviewCallback(new Camera.PreviewCallback() { 
    @Override 
    public void onPreviewFrame(byte[] data, Camera camera) { 
     Log.d(TAG, "#onPreviewFrame()"); 
    } 
    }); 

    // Start the camera preview 
    Log.d(TAG, "#surfaceChanged() camera.startPreview()"); 
    camera.startPreview(); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    // Surface will be destroyed when replaced with a new screen 
    // Always make sure to release the Camera instance 
    if (camera != null) { 
    camera.setPreviewCallback(null); 
    camera.stopPreview(); 
    camera.release(); 
    camera = null; 
    } 
} 

मेरे LogCat प्रदर्शित करता है इस प्रकार है::

  • एलजी जी -4 (6,0)
  • Huawei 6X (7,0)
  • Nexus 6P (7,0)

नीचे कोड स्निपेट है

D/CameraSurfaceView: #surfaceChanged() 
D/CameraSurfaceView: #surfaceChanged() camera.setPreviewCallback() 
D/CameraSurfaceView: #surfaceChanged() camera.startPreview() 

ScriptC_invert से है RenderScript नमूना https://developer.android.com/guide/topics/renderscript/compute.html#writing-an-rs-kernel

और यहां तक ​​कि अगर मैं सभी रेंडरस्क्रिप्ट सामान को हटा देता हूं, वही समस्या।

नोट::

एक ठीक मेरी surfaceChanged() विधि में एक camera.setPreviewDisplay(holder) की आवश्यकता होगी

मैं भी निम्नलिखित की कोशिश की है। लेकिन यह मेरे लिए एक और मुद्दा बनाने के बाद से मैं मुठभेड़ onPreviewFrame() में एक holder.lockCanvas() करने की ज़रूरत है और निम्न अपवाद हैं जाएगा:

E/SurfaceHolder: Exception locking surface 
       java.lang.IllegalArgumentException 
        at android.view.Surface.nativeLockCanvas(Native Method) 
        at android.view.Surface.lockCanvas(Surface.java:264) 
        at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:842) 
        at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:830) 
        at com.arcanys.ar.CameraSurfaceView.onPreviewFrame(CameraSurfaceView.java:204) 

से कुछ चीज़ों पर मैं चूक या गलत कॉन्फ़िगर किया गया है हो सकता है।

उत्तर

1

समय के लिए, मुझे इस मुद्दे के लिए कोई फिक्स नहीं मिला है, बल्कि मेरे पास एक कामकाज है।

जब से हम एक ही समय में camera.setPreviewDisplay(surfaceHolder) और camera.setPreviewCallback(previewCallback) दोनों का उपयोग नहीं कर सकते हैं कुछ उपकरणों के लिए onPreviewFrame() में surfaceHolder.lockCanvas() का उपयोग करने की उम्मीद है, मैं एक और SurfaceView करने के लिए मेरे पूर्वावलोकन स्थानांतरित कर दिया और वहां से onPreviewFrame() संभालने के लिए और अपने स्वयं के SufraceHolder का उपयोग किया है।

+2

यह एक सही कामकाज है। [setPreviewDisplay या setPreviewTexture] (https://stackoverflow.com/questions/16752454/setpreviewdisplay-vs-setpreviewtexture) एंड्रॉइड में अनिवार्य है, लेकिन कुछ डिवाइस इसे लागू नहीं करते हैं। –

+2

बीटीडब्ल्यू, ** कैमरा 2 ** एपीआई पर स्विच करने पर विचार करें जब तक कि आपके अधिकांश लक्षित डिवाइस लॉलीपॉप से ​​नीचे न हों। और यदि आप * बहिष्कृत * कैमरा एपीआई के साथ रहने का फैसला करते हैं, तो सुनिश्चित करें कि आप कैमरे को एक अलग हैंडलर थ्रेड में खोलें (ताकि कैमरा.ओपेन() और कॉलबैक यूआई थ्रेड पर भीड़ का कारण न बनें)। –

+0

@AlexCohn आपकी सलाह के लिए धन्यवाद। हां, मैं प्री-लॉलीपॉप डिवाइस को भी लक्षित कर रहा हूं इसलिए मैं अभी भी बहिष्कृत कैमरा एपीआई का उपयोग कर रहा हूं। – dhagz

संबंधित मुद्दे