bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.42k stars 1.57k forks source link

[libmp3lame @ 0x7f6ef9084d40] 4 frames left in the queue on closing #2074

Open Mhuang77 opened 11 months ago

Mhuang77 commented 11 months ago

Get the exception in javacv "[libmp3lame @ 0x7f91cd0ce3c0] 4 frames left in the queue on closing"

test file: input_case.zip

1 The ffmpeg command does not have this exception.

ffmpeg -i input.m4a tmp.mp3

2 javacv code encounter this exception

2.1 lib version:

    implementation 'org.bytedeco:openblas:0.3.23-1.5.9:linux-x86_64'
    implementation 'org.bytedeco:opencv:4.7.0-1.5.9:linux-x86_64'
    implementation 'org.bytedeco:ffmpeg:6.0-1.5.9:linux-x86_64'
    implementation 'org.bytedeco:javacpp:1.5.9:linux-x86_64'
    implementation 'org.bytedeco:javacv:1.5.9'

2.2 jdk version

openjdk version "11.0.19" 2023-04-18

2.3 os version

Ubuntu 22.04.1 LTS

2.4 reproduce code:

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;

import java.io.*;

public class TestMain {
    final static String INPUT_FILE_NAME = "/tmp/input.m4a";
    final static String OUTPUT_FILE_PATH = "/tmp/";
    public static void main(String[] args) throws IOException {
        test1();
    }

    public static void test1() throws FileNotFoundException, FFmpegFrameRecorder.Exception, FrameGrabber.Exception {
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new FileInputStream(INPUT_FILE_NAME));
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(OUTPUT_FILE_PATH + "test1.mp3", 1);
        extracted(grabber, recorder);
        grabber.stop();
        recorder.stop();
    }

    private static void extracted(FFmpegFrameGrabber grabber, FFmpegFrameRecorder recorder) throws FFmpegFrameRecorder.Exception, FrameGrabber.Exception {
        recorder.setFormat("MP3");
        recorder.start();
        grabber.start();
        Frame frame;
        while ((frame = grabber.grabFrame()) != null) {
            recorder.record(frame);
        }
    }
}

3 exception log

Output #0, mp3, to '/tmp/test1.mp3':
  Metadata:
    TSSE            : Lavf60.3.100
  Stream #0:0: Audio: mp3, 44100 Hz, mono, fltp, 64 kb/s
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'java.io.BufferedInputStream@5aa9e4eb':
  Metadata:
    major_brand     : M4A 
    minor_version   : 512
    compatible_brands: M4A isomiso2
    encoder         : Lavf60.3.100
  Duration: 00:00:14.98, start: 0.000000, bitrate: 75 kb/s
  Stream #0:0[0x1](und): Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 74 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
[libmp3lame @ 0x7f91cd0ce3c0] 4 frames left in the queue on closing   <-------------------  this exception
Mhuang77 commented 11 months ago

@saudet What can I do to help track down this issue?

saudet commented 11 months ago

It sounds like FFmpegFrameRecorder.flush() isn't working properly. Someone needs to debug that.

Mhuang77 commented 11 months ago

It sounds like FFmpegFrameRecorder.flush() isn't working properly. Someone needs to debug that.

I set the log level to debug and got log messages

......
[SWR @ 0x7ff275307140] Using s16p internally between filters
[mp3 @ 0x7ff2751fedc0] av_interleaved_write_frame FLUSH
[libmp3lame @ 0x7ff275206e80] 4 frames left in the queue on closing
[AVIOContext @ 0x7ff2752eeb80] Statistics: 119579 bytes written, 0 seeks, 1 writeouts

Based on the provided log, it can be observed that "av_interleaved_write_frame FLUSH" occurs before "4 frames left in the queue on closing". Now there is a suspicion that av_interleaved_write_frame has a problem.

How to debug the native method "org.bytedeco.ffmpeg.global.avformat#av_interleaved_write_frame"?

saudet commented 10 months ago

It sounds to me like the problem lies in libmp3lame. We need to figure out how to properly flush that specific codec.