TangoService_connectOnFrameAvailable() зависает или аварийно завершает работу при использовании Google Tango Leibniz Release 1.10

Кажется, есть проблема, связанная с приемом цветных кадров в Leibniz Release 1.10: при регистрации обратного вызова с использованием TangoService_connectOnFrameAvailable(TANGO_CAMERA_COLOR,NULL,onFrameAvailable) обратный вызов onFrameAvailable() либо никогда не будет вызван, либо TangoService_connectOnFrameAvailable() вылетает со следующей ошибкой:

04-20 13:29:44.384: E/tango_client_api(4712): TangoErrorType TangoService_connectOnFrameAvailable(TangoCameraId, void*, void ()(void, TangoCameraId, const TangoImageBuffer*)): Внутренняя ошибка: connectSurface( ), идентификатор камеры 0, внутренний сбой.

В примечаниях к выпуску говорится

[...] config_enable_color_camera был добавлен к флагам конфигурации. Мы рекомендуем всегда явно устанавливать для этого флага значение true при доступе к цветной камере. Вы должны установить флаг true для TangoService_connectOnFrameAvailable() или TangoService_connectTextureId() для успешного выполнения после вызова TangoService_connect(). [...]

Таким образом, если я установлю этот флаг в значение true между вызовами TangoService_connect() и TangoService_connectOnFrameAvailable(), обратный вызов onFrameAvailable() никогда не будет вызван, если я установлю этот флаг в значение true до TangoService_connect(), TangoService_connectOnFrameAvailable() всегда будет падать.

Таким образом, что я делаю неправильно? Есть ли фрагмент кода или что-то в этом роде? Это было бы действительно полезно... К сожалению, ни в одном из примеров не используются цветные рамки...

Чувак, после подобных проблем с Kalman Release 1.9 я начинаю задаваться вопросом, тщательно ли тестируются SDK перед их выпуском...


person Günter Westphal    schedule 20.04.2015    source источник
comment
Хорошо, этот релиз начинает пахнуть вчерашней рыбой - все люди, которые держали голову опущенной, выскакивают с проблемами :=( Мне еще предстоит интегрировать эти изменения, но я читал то же самое, что и вы, и я могу только (слабо) предложить вам очень внимательно посмотреть на привязку обратного вызова, просто чтобы быть очень-очень уверенным. Вы точны в отношении примеров, простой поиск на GitHub доказывает это. Что касается вашего последнего пункта, я уволил людей именно за такое поведение.   -  person Mark Mullin    schedule 21.04.2015
comment
Извините, что у вас возникли проблемы. Это все еще происходит? Я спрашиваю об этом, потому что между обновлением TangoCore в PlayStore и выходом OTA был небольшой разрыв во времени (что потенциально может вызвать эту проблему, если OTA и TangoCore не совпадают). Я просто хочу убедиться, что вы в курсе как TangoCore, так и OTA, прежде чем диагностировать его. Кроме того, убедитесь, что у вас есть разрешения для камеры в манифесте Android.   -  person r4ravi2008    schedule 21.04.2015
comment
Что ж, на моем планшете Tango на самом деле было то несоответствие между OTA и TangoCore, о котором вы говорите ... После того, как все тщательно обновилось еще раз, я наконец смог привязать обратный вызов ... Большое спасибо ... Для тех из вас кому интересно, как преобразовать NV21 в рамку RGB, я прикрепляю свой код ниже...   -  person Günter Westphal    schedule 22.04.2015


Ответы (2)


Хорошо, если предположить, что проблема не в том, что я упомянул в разделе комментариев. Вот фрагмент кода, тестирующий обратный вызов onFrameAvailable.

Примечание. Я изменил Пример HelloTangoJni из репозитория Tango-examples-c.

В TangoHandler.h добавляем

 TangoErrorType ConnectYUVFrameCallback();

Изменить TangoHandler.cc

TangoErrorType TangoHandler::SetupConfig() {
  // TANGO_CONFIG_DEFAULT is enabling Motion Tracking and disabling Depth
  // Perception.
  tango_config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
  if (tango_config_ == nullptr) {
  return TANGO_ERROR;
  }
  TangoConfig_setBool(tango_config_,"config_enable_color_camera",true);
  return TANGO_SUCCESS;
}


TangoErrorType TangoHandler::ConnectYUVFrameCallback() {
    TangoErrorType onFrameErrorType=TangoService_connectOnFrameAvailable( TANGO_CAMERA_COLOR, NULL, onFrameAvailable);
    if( onFrameErrorType!= TANGO_SUCCESS)
    {
         LOGI("GOOGLE TANGO ONFRAMEAVAILABLE FAILED!");
    }
    LOGI("GOOGLE TANGO ONFRAMEAVAILABLE SUCCESS!");
    return onFrameErrorType;
}

static void onFrameAvailable( void* context, const TangoCameraId id, const TangoImageBuffer* buffer )
{
  int width = buffer->width;
  int height = buffer->height;
  LOGI("width and height is: %d,%d",width,height);
}

В TangoNative.cc добавить

JNIEXPORT jint JNICALLJava_com_projecttango_experiments_nativehellotango_TangoJNINative_connectOnFrameAvailableCallback(
JNIEnv*, jobject) 
{
    return static_cast<int>(tango_handler.ConnectYUVFrameCallback());
}

В TangoJNINative.java добавить

// Connect the onFrameAvailable callback.
public static native int connectOnFrameAvailableCallback();

В HelloTangoActivity.java измените onResume()

protected void onResume() {
   super.onResume();
   // Setup Tango configuraturation.
   TangoJNINative.setupConfig();
   int status = 0;
   TangoJNINative.connect();
   status = TangoJNINative.connectOnFrameAvailableCallback();
   mIsTangoServiceConnected = true;
}
person r4ravi2008    schedule 22.04.2015

Вот мой код для преобразования NV21 в кадр RGB. Может и пригодится...

static void
  cb_onFrameAvailable
  (
    void*                     contextA,
    TangoCameraId             idA,
    const TangoImageBuffer*  imageBufferA
  )
{
  // --- local constants ------------------------------

  // image width and height
  const int W               = imageBufferA->width;
  const int H               = imageBufferA->height;

  // sizes of Y, U, and V pixel arrays.
  const int sizeOfYDataL   = W * H;

  // indices, marking the begin of the y, u, and v data in the pixel buffer.
  const int beginOfYDataL  = 0;
  const int beginOfUVDataL  = sizeOfYDataL;

  // YUV, Y, and UV pixel sub arrays.
  const byte*  yuvArrL     = imageBufferA->data;
  const byte*  yArrL       = &yuvArrL[ beginOfYDataL  ];
  const byte*  uvArrL      = &yuvArrL[ beginOfUVDataL ];

  // --- local variables ------------------------------

  // image pixel coordinates.
  int xL,yL;

  // halved image pixel coordinates.
  int hxL,hyL;

  // ARGB value.
  int argbL;

  // --------------------------------------------------

  // translate YUV NV21 -> ARGB, using
  //
  //      / R \   / 1.000   0.000   1.596 \   /   Y   \
  //      | G | = | 1.000  -0.391  -0.813 | * | U-128 |
  //      \ B /   \ 1.000   2.018   0.000 /   \ V-128 /
  //

  // Note: start value yL=1 as the first scan line of the color image is ..
  //       .. reserved for metadata instead of image pixels.

  for( yL=1,hyL=0; yL<H; yL++,hyL=yL>>1 )
  {
    for( xL=0,hxL=0; xL<W; xL++,hxL=xL>>1 )
    {
      const int y = static_cast<int>( yArrL [  yL*W +    xL   ] )      ;
      const int v = static_cast<int>( uvArrL[ hyL*W + 2*hxL   ] ) - 128;
      const int u = static_cast<int>( uvArrL[ hyL*W + 2*hxL+1 ] ) - 128;

      int R = static_cast<int>( y               + ( 1.596f*v) );
      int G = static_cast<int>( y + (-0.391f*u) + (-0.813f*v) );
      int B = static_cast<int>( y + ( 2.018f*u)               );

      // clip RGB values to [0..255].
      R = R < 0 ? 0 : (R > 255 ? 255 : R);
      G = G < 0 ? 0 : (G > 255 ? 255 : G);
      B = B < 0 ? 0 : (B > 255 ? 255 : B);

      // combine to ARGB value.
      argbL = 0xff000000 | (R << 16) | (G << 8) | B;
    } // for
  } // for
} // function
person Günter Westphal    schedule 22.04.2015