Luiz Alberto Roque
Luiz Alberto Roque

Reputation: 75

Delphi - JNI Error

I'm developing an App in Delphi 10 Seattle for android that get the image from the TCameraComponent and send for another device using TIdUDPServer. I created a thread to handle the TIdUDPServer and send the images and others text commands. It works this way: The main thread takes the bitmap write inside the thread and then, the thread send.

The problem is once every 5 or 4 minutes the App's crash with Fatal Signal 6 error, I think it is related to threads accessing the same object, I've tried using TCriticalSection to protect the object, but I'm still getting the error.

Here is the code of the main thread

procedure TFormMain.CameraComponent1SampleBufferReady(Sender: TObject;
  const ATime: TMediaTime);
var
  Bitm: TBitmap;
begin
  try
    Bitm:= TBitmap.Create;
    CameraComponent1.SampleBufferToBitmap(Bitm, True);
    BabyImag.Bitmap.Assign(Bitm);
    Log.d('DBBaby', nil, 'Image on Screen');
    if SendVideo then
      FCommThread.SetGetImage(Bitm, True);
  finally
    Bitm.Free;
    Bitm:= nil;
  end;
end;

And here is the part code of the thread to send the image

type
  TComThread = class(TThread)
  private
    { Some code }
    CriticalX: TCriticalSection;
  public 
    Constructor Create(UserType: Integer);
    { Some code }
    function SetGetImage(ImageBitmap: TBitmap; SetOrGet: Boolean): TBitmap;
  protected
    procedure Execute; override;
  end;

implementation

constructor TComThread.Create(UserType: Integer);
begin
  inherited Create (True);
  FreeOnTerminate := True;
  { Some code }
  CriticalX:= TCriticalSection.Create;
  FImage:= TBitmap.Create;
end;

procedure TComThread.Execute;
var
  BitmSurface: TBitmapSurface;
  ToJPEG: TBitmapCodecManager;
  quality: TBitmapCodecSaveParams;
  CameraImg: TMemoryStream;
begin
  while SendBabyVideo do
  begin
    try
      if Assigned(FImage) then
      begin
        try
          CameraImg:= TMemoryStream.Create();
          BitmSurface:= TBitmapSurface.Create;
          ToJPEG:= TBitmapCodecManager.Create;
          quality.Quality:= 50;
          //BitmSurface.Assign(FImage);
          BitmSurface.Assign(SetGetImage(nil, False));
          Log.d('DBBaby', nil, 'SurfWidth ' + IntToStr(BitmSurface.Width));
          if (BitmSurface.Width > 0) AND (BitmSurface.Height > 0) then
          begin
            // Image stream ready
            ToJPEG.SaveToStream(CameraImg, BitmSurface, '.jpg', @quality);
            CamSize:= CameraImg.Size;
            SetLength(bffrImg, CamSize+8);
            bffrImg[0]:= $FF;
            bffrImg[1]:= $FF;
            bffrImg[2]:= $16;
            bffrImg[3]:= $09;
            bffrImg[4]:= byte(CamSize);
            bffrImg[5]:= byte(CamSize shr 8);
            bffrImg[6]:= byte(CamSize shr 16);
            bffrImg[7]:= byte(CamSize shr 24);

            CameraImg.Position:= 0;
            CameraImg.Read(bffrImg[8], CamSize);

            Log.d('DBBaby', nil, 'Imagem total: '+IntToStr(Length(bffrImg)));
          end;
        finally
          BitmSurface.Free;
          BitmSurface:= nil;
          ToJPEG.Free;
          ToJPEG:= nil;
          CameraImg.Free;
          CameraImg:= nil;
        end;
      end;
    except
      on E: Exception do
      begin
        Log.d('DBBaby', nil, '------------------------ GET STREAM');
        Log.d('DBBaby', nil, E.message);
      end;
    end;

    try
      if (PeerIP <> '') AND (PeerIP <> '255.255.255.255') then
      begin
        if (bffr <> nil) AND (bffrImg <> nil) then
        begin
          FUDPBABY.SendBuffer(PeerIP, PeerPort, TIdIPVersion.Id_IPv4, bffr);
          FUDPBABY.SendBuffer(PeerIP, PeerPort, TIdIPVersion.Id_IPv4, bffrImg);
      end;
    except
      on E: Exception do
      begin
        Log.d('DBBaby', nil, '------------------------ SEND STREAM');
        Log.d('DBBaby', nil, E.message);
      end;
    end;
  end;
end;

function TComThread.SetGetImage(ImageBitmap: TBitmap; SetOrGet: Boolean): TBitmap;
begin
  CriticalX.Enter;
  try
    if SetOrGet then
    begin
      Self.FImage.Assign(ImageBitmap);
      Result:= nil;
    end
    else
    begin
      Result:= Self.FImage;
    end;
  finally
    CriticalX.Leave;
  end;
end;

I'm using a Moto E Android 6.0, the NDK is r11b. In SDK Manager I set all the configurations to API 23.

Here is the Log.

04-05 17:00:28.743 27591-27591/com.Test2.Project2 D/skia: onFlyCompress
04-05 17:00:28.780 27591-27611/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Image on Screen
04-05 17:00:28.807 27591-27591/com.Test2.Project2 D/skia: onFlyCompress
04-05 17:00:28.818 27591-28475/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): SurfWidth 144
04-05 17:00:28.822 27591-28475/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Imagem total: 1946
04-05 17:00:28.846 27591-27611/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Image on Screen
04-05 17:00:28.876 27591-27591/com.Test2.Project2 D/skia: onFlyCompress
04-05 17:00:28.912 27591-27611/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Image on Screen
04-05 17:00:28.942 27591-27591/com.Test2.Project2 D/skia: onFlyCompress
04-05 17:00:28.978 27591-27611/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Image on Screen
04-05 17:00:29.008 27591-28475/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): SurfWidth 144
04-05 17:00:29.012 27591-27591/com.Test2.Project2 D/skia: onFlyCompress
04-05 17:00:29.015 27591-28475/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Imagem total: 1943
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0xb9f7a0b0
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]     from java.lang.Object com.embarcadero.rtl.ProxyInterface.dispatchToNative(java.lang.String, java.lang.Object[], long)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410] "main" prio=5 tid=1 Runnable
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | group="main" sCount=0 dsCount=0 obj=0x73f5af98 self=0xb70f0c60
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | sysTid=27591 nice=0 cgrp=default sched=0/0 handle=0xb6f94b34
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | state=R schedstat=( 46379176934 4119603860 17774 ) utm=4206 stm=431 core=0 HZ=100
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | stack=0xbe418000-0xbe41a000 stackSize=8MB
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | held mutexes= "mutator lock"(shared held)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #00 pc 0035c6d5  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::ArtMethod*, void*)+116)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #01 pc 0033d7cf  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+138)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #02 pc 0024f6a1  /system/lib/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+760)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #03 pc 0024fda9  /system/lib/libart.so (art::JavaVMExt::JniAbortF(char const*, char const*, ...)+68)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #04 pc 0033e32b  /system/lib/libart.so (art::Thread::DecodeJObject(_jobject*) const+174)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #05 pc 000fff55  /system/lib/libart.so (art::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::JniValueType*) (.constprop.95)+900)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #06 pc 0010e193  /system/lib/libart.so (art::CheckJNI::CallMethodA(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, jvalue*, art::Primitive::Type, art::InvokeType)+498)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #07 pc 0010ed57  /system/lib/libart.so (art::CheckJNI::CallIntMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*)+30)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #08 pc 006913e5  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (ExecJNI+884)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #09 pc 01135073  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #10 pc 01141607  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #11 pc 010b047f  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #12 pc 010ab189  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #13 pc 01135021  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #14 pc 005d9d5f  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #15 pc 005cde87  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #16 pc 005cf035  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #17 pc 005ac013  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #18 pc 006a10bf  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #19 pc 000aca1b  /data/app/com.Test2.Project2-2/oat/arm/base.odex (java.lang.Object com.embarcadero.rtl.ProxyInterface.dispatchToNative(java.lang.String, java.lang.Object[], long)+134)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #20 pc 000acadb  /data/app/com.Test2.Project2-2/oat/arm/base.odex (java.lang.Object com.embarcadero.rtl.ProxyInterface.invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])+118)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #21 pc 0029879d  /system/framework/arm/boot.oat (???)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.embarcadero.rtl.ProxyInterface.dispatchToNative(Native method)
04-05 17:00:29.163 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.embarcadero.rtl.ProxyInterface.invoke(ProxyInterface.java:21)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at java.lang.reflect.Proxy.invoke(Proxy.java:393)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.hardware.Camera$PreviewCallback.onPreviewFrame(Camera.java:-2)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1129)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.os.Handler.dispatchMessage(Handler.java:102)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.os.Looper.loop(Looper.java:148)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.app.ActivityThread.main(ActivityThread.java:5443)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at java.lang.reflect.Method.invoke!(Native method)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-05 17:00:29.165 27591-27591/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410] 

04-05 17:00:29.501 27591-27591/com.Test2.Project2 A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 27591

Any help would be appreciated.

I've tried the code, but I still get Fatal Signal 6 See the log:

04-06 08:24:12.660 18999-19023/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Image on Screen
04-06 08:24:12.712 18999-18999/com.Test2.Project2 D/skia: onFlyCompress
04-06 08:24:12.726 18999-19023/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Image on Screen
04-06 08:24:12.778 18999-18999/com.Test2.Project2 D/skia: onFlyCompress
04-06 08:24:12.779 18999-20099/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): SurfWidth 144
04-06 08:24:12.784 18999-20099/com.Test2.Project2 I/info: FMX: Project2: DBBaby (Nil): Imagem total: 2984
04-06 08:24:12.785 18999-18999/com.Test2.Project2 E/art: JNI ERROR (app bug): accessed stale global reference 0x203776 (index 3549 in a table of size 3546)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: use of deleted global reference 0x203776
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]     from java.lang.Object com.embarcadero.rtl.ProxyInterface.dispatchToNative(java.lang.String, java.lang.Object[], long)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410] "main" prio=5 tid=1 Runnable
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | group="main" sCount=0 dsCount=0 obj=0x73f5af98 self=0xb70f0c60
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | sysTid=18999 nice=0 cgrp=default sched=0/0 handle=0xb6f94b34
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | state=R schedstat=( 5347038051 485186867 2088 ) utm=480 stm=54 core=3 HZ=100
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | stack=0xbe418000-0xbe41a000 stackSize=8MB
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   | held mutexes= "mutator lock"(shared held)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #00 pc 0035c6d5  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::ArtMethod*, void*)+116)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #01 pc 0033d7cf  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+138)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #02 pc 0024f6a1  /system/lib/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+760)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #03 pc 0024fda9  /system/lib/libart.so (art::JavaVMExt::JniAbortF(char const*, char const*, ...)+68)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #04 pc 0033e52b  /system/lib/libart.so (art::Thread::DecodeJObject(_jobject*) const+686)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #05 pc 000fff55  /system/lib/libart.so (art::ScopedCheck::Check(art::ScopedObjectAccess&, bool, char const*, art::JniValueType*) (.constprop.95)+900)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #06 pc 0010e193  /system/lib/libart.so (art::CheckJNI::CallMethodA(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, jvalue*, art::Primitive::Type, art::InvokeType)+498)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #07 pc 0010ee41  /system/lib/libart.so (art::CheckJNI::CallObjectMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*)+28)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #08 pc 00691773  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (ExecJNI+1826)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #09 pc 0113503b  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #10 pc 011415d7  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #11 pc 010b0451  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #12 pc 010ab169  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #13 pc 01134fe9  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #14 pc 005d9d3f  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #15 pc 005cde67  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #16 pc 005cf015  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #17 pc 005abff3  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #18 pc 006a109f  /data/app/com.Test2.Project2-2/lib/arm/libProject2.so (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #19 pc 000aca1b  /data/app/com.Test2.Project2-2/oat/arm/base.odex (java.lang.Object com.embarcadero.rtl.ProxyInterface.dispatchToNative(java.lang.String, java.lang.Object[], long)+134)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #20 pc 000acadb  /data/app/com.Test2.Project2-2/oat/arm/base.odex (java.lang.Object com.embarcadero.rtl.ProxyInterface.invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])+118)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   native: #21 pc 0029879d  /system/framework/arm/boot.oat (???)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.embarcadero.rtl.ProxyInterface.dispatchToNative(Native method)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.embarcadero.rtl.ProxyInterface.invoke(ProxyInterface.java:21)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at java.lang.reflect.Proxy.invoke(Proxy.java:393)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.hardware.Camera$PreviewCallback.onPreviewFrame(Camera.java:-2)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.hardware.Camera$EventHandler.handleMessage(Camera.java:1129)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.os.Handler.dispatchMessage(Handler.java:102)
04-06 08:24:12.839 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.os.Looper.loop(Looper.java:148)
04-06 08:24:12.840 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at android.app.ActivityThread.main(ActivityThread.java:5443)
04-06 08:24:12.840 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at java.lang.reflect.Method.invoke!(Native method)
04-06 08:24:12.840 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
04-06 08:24:12.840 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410]   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-06 08:24:12.840 18999-18999/com.Test2.Project2 A/art: art/runtime/java_vm_ext.cc:410] 
04-06 08:24:12.840 18999-19006/com.Test2.Project2 W/art: Suspending all threads took: 38.697ms
04-06 08:24:13.103 18999-18999/com.Test2.Project2 A/art: art/runtime/runtime.cc:399] Runtime aborting...
04-06 08:24:13.103 18999-18999/com.Test2.Project2 A/art: art/runtime/runtime.cc:399] Aborting thread:

04-06 08:24:13.107 18999-18999/com.Test2.Project2 A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 18999

Upvotes: 0

Views: 555

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595711

You are not protecting your thread's FBitmap object adequately enough.

When the thread calls SetGetImage(nil, False), the TCriticalSection is locked and then unlocked before SetGetImage() exits, thus access to FBitmap is not locked when it is Assign()'ed to BitmSurface. That means the main thread can modify FBitmap while BitmSurface is still busy copying it.

Try something more like this instead:

procedure TFormMain.CameraComponent1SampleBufferReady(Sender: TObject;
  const ATime: TMediaTime);
begin
  CameraComponent1.SampleBufferToBitmap(BabyImag.Bitmap, True);
  Log.d('DBBaby', nil, 'Image on Screen');
  if SendVideo then
    FCommThread.SetImage(BabyImag.Bitmap);
end;

type
  TComThread = class(TThread)
  private
    { Some code }
    procedure GetImage(ASurface: TBitmapSurface);
  protected
    procedure Execute; override;
  public 
    Constructor Create(UserType: Integer);
    { Some code }
    function SetImage(AImage: TBitmap);
  end;

implementation

constructor TComThread.Create(UserType: Integer);
begin
  inherited Create(True);
  { Some code }
  FImage := TBitmap.Create;
end;

procedure TComThread.Execute;
var
  BitmSurface: TBitmapSurface;
  ToJPEG: TBitmapCodecManager;
  quality: TBitmapCodecSaveParams;
  CameraImg: TMemoryStream;
begin
  BitmSurface := TBitmapSurface.Create;
  ToJPEG := TBitmapCodecManager.Create;
  quality.Quality := 50;
  try
    while SendBabyVideo do
    begin
      try
        GetImage(BitmSurface);
        Log.d('DBBaby', nil, 'SurfWidth ' + IntToStr(BitmSurface.Width));
        if (BitmSurface.Width > 0) and (BitmSurface.Height > 0) then
        begin
          // Image stream ready
          CameraImg.Clear;
          try
            ToJPEG.SaveToStream(CameraImg, BitmSurface, '.jpg', @quality);
            CamSize := CameraImg.Size;
            SetLength(bffrImg, CamSize+8);
            bffrImg[0] := $FF;
            bffrImg[1] := $FF;
            bffrImg[2] := $16;
            bffrImg[3] := $09;
            bffrImg[4] := byte(CamSize);
            bffrImg[5] := byte(CamSize shr 8);
            bffrImg[6]:= byte(CamSize shr 16);
            bffrImg[7]:= byte(CamSize shr 24);

            CameraImg.Position := 0;
            CameraImg.ReadBuffer(bffrImg[8], CamSize);
          finally
            CameraImg.Clear;
          end;

          Log.d('DBBaby', nil, 'Imagem total: '+IntToStr(Length(bffrImg)));
        end;
      except
        on E: Exception do
        begin
          Log.d('DBBaby', nil, '------------------------ GET STREAM');
          Log.d('DBBaby', nil, E.Message);
        end;
      end;

      try
        if (PeerIP <> '') and (PeerIP <> '255.255.255.255') and
           (bffr <> nil) and (bffrImg <> nil) then
        begin
          FUDPBABY.SendBuffer(PeerIP, PeerPort, TIdIPVersion.Id_IPv4, bffr);
          FUDPBABY.SendBuffer(PeerIP, PeerPort, TIdIPVersion.Id_IPv4, bffrImg);
        end;
      except
        on E: Exception do
        begin
          Log.d('DBBaby', nil, '------------------------ SEND STREAM');
          Log.d('DBBaby', nil, E.Message);
        end;
      end;
    end;
  finally
    CameraImg.Free;
    ToJPEG.Free;
    BitmSurface.Free;
  end;
end;

procedure TComThread.GetImage(ASurface: TBitmapSurface);
begin
  TMonitor.Enter(FImage);
  try
    ASurface.Assign(FImage);
  finally
    TMonitor.Exit(FImage);
  end;
end;

procedure TComThread.SetImage(AImage: TBitmap);
begin
  TMonitor.Enter(FImage);
  try
    FImage.Assign(AImage);
  finally
    TMonitor.Exit(FImage);
  end;
end;

Upvotes: 2

Related Questions