2015-01-28 11 views
6

के लिए प्रोसेसिंग और मेडियाकोडेक के लिए रेंडरस्क्रिप्ट का उपयोग करके मैं एक कैमरा ऐप विकसित करने की कोशिश कर रहा हूं जो वीडियो रिकॉर्ड करने से पहले कुछ वीडियो प्रोसेसिंग करता है। मैंने प्रसंस्करण के लिए रेंडरस्क्रिप्ट का उपयोग करने का निर्णय लिया है क्योंकि यह उन कई संचालन प्रदान करता है जिन्हें मैं उपयोग करना चाहता हूं। और मैं एन्कोडिंग के लिए मीडियाकोडेक का उपयोग करना चाहता हूं। मुझे कुछ नमूने मिले हैं (Grafika सहित) जो दिखाता है कि प्रसंस्करण के लिए जीएलएस का उपयोग कैसे करें, लेकिन मुझे एक नमूना नहीं मिला है जो दिखाता है कि इसे रेंडरस्क्रिप्ट के साथ कैसे किया जाए। Renderscript साथ GLES को बदलने के लिए कोशिश कर रहा है मैं निम्नलिखित प्रश्न हैं:एन्कोडिंग

  1. मैं एनकोडर इनपुट सतह से RenderScript उत्पादन आवंटन पैदा करते हैं। ग्राफिका नमूना में ईजीएल स्वैपबफर() एन्कोडर को बफर भेजने के लिए उपयोग किया जाता है। आवंटन .ioSend() वही काम करते हैं?
  2. ईजीएल सेट प्रस्तुति समय() टाइम-स्टाम्प सेट करने के लिए उपयोग किया जाता है। मैं रेंडरस्क्रिप्ट के आवंटन में टाइम-स्टाम्प कैसे सेट करूं?
  3. क्या मुझे इनपुट बफर और टाइम-स्टैंप सबमिट करने के बजाय MediaCodec.queueInputBuffer() का उपयोग करना चाहिए? उस मामले में मुझे अभी भी Allocation.ioSend() queueInputBuffer को कॉल करने से पहले कॉल करना चाहिए?

उत्तर

1

मैं इसी मुद्दे पर आया और मैं जिस समाधान का उपयोग करता हूं वह ईजीएल के माध्यम से टाइमस्टैम्प सेट करना है, RecordFBOActivity#doFrame के समान। ऐसा करने के लिए एक मध्यवर्ती आवंटन का उपयोग रेंडरस्क्रिप्ट और ओपनजीएल/ईजीएल के बीच के अंतर को पुल करने के लिए किया जाता है।

चलिए डेटा प्रवाह को चरणों के साथ प्रसंस्करण पाइपलाइन के रूप में देखते हैं।

मूल पाइपलाइन

[Camera] 
    --> [ImageAllocation] 
     --> [RenderScript] 
      --> [MediaCodecSurfaceAllocationForEncoder] 
       --> [MediaCodec] 

मूल पाइपलाइन में सभी बफ़र्स रुपये आवंटन कर रहे हैं।

MediaCodecSurfaceAllocation एन्कोडर से लौटाई गई सतह पर आधारित है, यानी MediaCodec#getSurface()

नई पाइपलाइन

[Camera] 
    --> [ImageAllocation] 
     --> [RenderScript] 
      --> [IntermediateAllocation] 
       --> [EglWindowSurfaceForEncoder] 
        --> [MediaCodec] 

नई पाइपलाइन में दो बड़े बदलाव, IntermediateAllocation और EglWindowSurfaceForEncoder

IntermediateAllocation है एक SurfaceTexture आधारित आवंटन, ful स्क्रीन बनावट CameraCaptureActivity में इस्तेमाल blitter के समान नहीं है।

EglWindowSurfaceForEncoderRecordFBOActivity#startEncoder

को एनकोडर के इनपुट सतह, समान लपेटता कुंजी यहाँ अपने खुद के OnFrameAvailableListener स्थापित करने के लिए है।

सेटअप कोड

void setup() { 
    mEglWindowSurfaceForEncoder= new WindowSurface(mEglCore, encoderCore.getInputSurface(), true); 

    mFullScreen = new FullFrameRect(
      new Texture2dProgram(Texture2dProgram.ProgramType.TEXTURE_EXT)); 
    mTextureId = mFullScreen.createTextureObject(); 
    mSurfaceTexture = new SurfaceTexture(mTextureId);  

    Type renderType = new Type.Builder(renderScript, Element.RGBA_8888(renderScript)) 
     .setX(width) 
     .setY(height) 
     .create(); 

    mIntermediateAllocation = Allocation.createTyped(
     renderScript, 
     renderType, 
                   Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT); 

    mIntermediateAllocation .setSurface(surface); 

    mAllocationFromCamera = ... 
} 

OnNewCameraImage

mIntermediateAllocation.copyFrom(mAllocationFromCamera); 

OnFrameAvailableListener

mSurfaceTexture.setOnFrameAvailableListener(
    new SurfaceTexture.OnFrameAvailableListener() { 
     public void onFrameAvailableListener(SurfaceTexture) { 

      //latch the image data from camera 
      mSurfaceTexture.updateTexImage(); 

      // Draw the frame. 
      mSurfaceTexture.getTransformMatrix(mSTMatrix); 
      mFullScreen.drawFrame(mTextureId, mSTMatrix); 

      // latch frame to encoder input 
      mEglWindowSurfaceForEncoder.setPresentationTimes(timestampNanos); 
      mEglWindowSurfaceForEncoder.swapBuffers(); 

     }   
    } 
} 

उपर्युक्त कोड ईजीएल संदर्भ में चलाना चाहिए (यानी ओपनजीएल प्रतिपादन धागे पर)।

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