Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

video take strang line on android api >= 21 #190

Closed
nguyenvancuongit opened this issue Jul 30, 2015 · 25 comments
Closed

video take strang line on android api >= 21 #190

nguyenvancuongit opened this issue Jul 30, 2015 · 25 comments
Labels

Comments

@nguyenvancuongit
Copy link

Hi,
Sorry when open this issue, but did @saudet check on android api >= 21?
My result is strange, pls take a look here
unnamed
There's a video area on the left.
Thanks you for your support.

@tomerhatav
Copy link

Have this issue too, only in android api>=21
The area on the left is 5 pixels of video from the right side.

@hieunt142
Copy link

I face with issue too.
Anyone know solution for this ?

@saudet
Copy link
Member

saudet commented Jul 31, 2015

Doesn't sound like a problem with FFmpegFrameRecorder. Sounds like a problem with the Android API and the way it's used in the sample. Let's make sure it works properly with the new samples developed at #163. Thanks!

@saudet saudet closed this as completed Jul 31, 2015
@nguyenvancuongit
Copy link
Author

@tomerhatav how about on your side
At I debug here, the frame image data is correct (without the video area)
But the video after encode is same result? How about you?

@tomerhatav
Copy link

@nguyenvancuongit same result as yours, image is fine, video encode is making the strange 5 pixels line

@nguyenvancuongit
Copy link
Author

@tomerhatav any solution on your side? my bad currently solution is crop video ...

@DTHeaven
Copy link

DTHeaven commented Sep 1, 2015

I found the bug.
It's because the allocateDirect() of ByteBuffer has changed from android 5.0.
Look at this:
Before 5.0:

/**
      * Creates a direct byte buffer based on a newly allocated memory block.
      *
      * @param capacity
      *            the capacity of the new buffer
      * @return the created byte buffer.
      * @throws IllegalArgumentException
      *             if {@code capacity < 0}.
      */
     public static ByteBuffer allocateDirect(int capacity) {
         if (capacity < 0) {
            throw new IllegalArgumentException("capacity < 0: " + capacity);
         }
         return new DirectByteBuffer(MemoryBlock.allocate(capacity), capacity, 0, false, null);
     }

After 5.0:

/**
      * Creates a direct byte buffer based on a newly allocated memory block.
      *
      * @param capacity
      *            the capacity of the new buffer
      * @return the created byte buffer.
      * @throws IllegalArgumentException
      *             if {@code capacity < 0}.
      */
     public static ByteBuffer allocateDirect(int capacity) {
         if (capacity < 0) {
             throw new IllegalArgumentException("capacity < 0: " + capacity);
         }
         // Ensure alignment by 8.
         MemoryBlock memoryBlock = MemoryBlock.allocate(capacity + 7);
         long address = memoryBlock.toLong();
         long alignedAddress = (address + 7) & ~(long)7;
         return new DirectByteBuffer(memoryBlock, capacity, (int)(alignedAddress - address), false, null);
     }

The buffer's arrayOffset is always 0 before android 5.0, but not after 5.0.
There's another discuss.
https://code.google.com/p/android/issues/detail?id=80064

So I changed FFmpegFrameRecorder.recordImage(int width, int height, int depth, int channels, int stride, int pixelFormat, Buffer ... image)

Before:

int step = stride * Math.abs(depth) / 8;
BytePointer data = image[0] instanceof ByteBuffer
         ? new BytePointer((ByteBuffer)image[0].position(0))
          : new BytePointer(new Pointer(image[0].position(0)));

After:

int step = stride * Math.abs(depth) / 8;
BytePointer data = image[0] instanceof ByteBuffer
         ? new BytePointer((ByteBuffer)image[0].position(image[0].arrayOffset()))
          : new BytePointer(new Pointer(image[0].position(image[0].arrayOffset())));

Now it works well both on Android 4.x and 5.x.

@saudet saudet removed the duplicate label Sep 1, 2015
saudet added a commit to bytedeco/javacpp that referenced this issue Sep 1, 2015
@saudet
Copy link
Member

saudet commented Sep 1, 2015

Nice catch @DTHeaven! I've fixed the root cause of this bug in the latest commit for JavaCPP above. Thanks!

@nguyenvancuongit
Copy link
Author

@DTHeaven you're awesome !!

@aka-awasthi
Copy link

@saudet is there any example of recoder.recordeImage().... so i can overcome this issue .
i am not familiar with this method and never used before

@saudet
Copy link
Member

saudet commented Sep 15, 2015

@justflyhard No need to do that. Instead of javacpp.jar from version 1.0, simple use the latest javacpp-1.0.1-[...].jar file from here:
https://oss.sonatype.org/content/repositories/snapshots/org/bytedeco/javacpp/1.0.1-SNAPSHOT/

@aka-awasthi
Copy link

@saudet i import that jar and avutil avcodec avformat all are missing ,using javacv.jar from http://bytedeco.org/download/

@aka-awasthi
Copy link

@saudet before i were using gradle build javacv 1.0 and javacpp 1.0

@saudet
Copy link
Member

saudet commented Sep 20, 2015

Reopening this just to try to get people to stop creating duplicates...

@saudet saudet reopened this Sep 20, 2015
@aka-awasthi
Copy link

@saudet help... your javacpp.jar 1.0.1 not working ...avutil avcodec avformat all are missing

@saudet
Copy link
Member

saudet commented Sep 22, 2015

@justflyhard Just use the ones you used before. Those don't need to be changed.

@aka-awasthi
Copy link

@saudet i tried everything you said about 5 times but these are errors ....

first what i did
steps

  1. i remove my javacv and javacpp from gradle builde .
    2.put javacv.jar in libs folder from downlading javacv. 1.0 from your link in github .
    3.i download your javacpp 1.0.1 as above link and put it into libs folder.
    4.ffmpeg-android.arm.jar also in libs folder .

now my previous code showing these errors
these imports not found.
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacpp.swresample;

here is my code

 private void initRecorder() {
        Log.w(LOG_TAG, "init recorder");

        if (RECORD_LENGTH > 0) {
            imagesIndex = 0;
            images = new Frame[RECORD_LENGTH * frameRate];
            timestamps = new long[images.length];
            for (int i = 0; i < images.length; i++) {
                images[i] = new Frame(imageHeight, imageHeight, Frame.DEPTH_UBYTE, 2);
                timestamps[i] = -1;
            }
        } else if (yuvImage == null) {
            yuvImage = new Frame(imageHeight, imageHeight, Frame.DEPTH_UBYTE, 2);
            Log.i(LOG_TAG, "create yuvImage");
        }
//        filter = new FFmpegFrameFilter("transpose=cclock_flip", imageWidth, imageHeight);
//        filter.setPixelFormat(org.bytedeco.javacpp.avutil.AV_PIX_FMT_NV21); // default camera format on Android
//        filter.start();

        captureFile=new File(getActivity().getExternalFilesDir(null),function.randomString(12)+".mp4");
        recorder = new FFmpegFrameRecorder(captureFile, imageHeight, imageHeight, 1);
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);  error here
        recorder.setFormat("mp4");
        recorder.setSampleRate(sampleAudioRateInHz);
        recorder.setAudioBitrate(93);
        //recorder.setVideoBitrate(2048);
        recorder.setAudioChannels(2);


        // Set in the surface changed method
        recorder.setFrameRate(frameRate);
       //recorder.setAspectRatio(1);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);  error here -----
        Log.i(LOG_TAG, "recorder initialize success");
        audioRecordRunnable = new AudioRecordRunnable();
        audioThread = new Thread(audioRecordRunnable);
        runAudioThread = true;
    }

@saudet
Copy link
Member

saudet commented Sep 25, 2015

@justflyhard You forgot to add ffmpeg.jar.

@aka-awasthi
Copy link

@saudet thanks but after doing all this that strange line still there ....your javacpp 1.0.1 didnt help ...are you sure about this jar that by adding this jar strange line will dissappear

@saudet
Copy link
Member

saudet commented Sep 25, 2015

@justflyhard No one else has noted that yet, you would be the first. You could try the patch from @DTHeaven as well see if that does anything more.

@aka-awasthi
Copy link

@saudet i dont know how to use that function ...never experienced it before ..
@DTHeaven help. any code sample how to use that function

@aka-awasthi
Copy link

by adding this line in onPreviewFrame(byte[] data )
((ByteBuffer)yuvImage.image[0].position(yuvImage.image[0].arrayOffset())).put(data);

problem not solved @saudet @DTHeaven
please tell me a way to solve this.

@nguyenvancuongit
Copy link
Author

@justflyhard pls try to override FFmpegFrameRecorder.java with edited from #190 (comment)

@aka-awasthi
Copy link

thankyou @nguyenvancuongit @saudet problem fixed .thanks a lot 👍

@saudet
Copy link
Member

saudet commented Oct 31, 2015

Fix included in version 1.1. Thanks for reporting and thanks to @DTHeaven for finding the bug!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants