bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.52k stars 1.58k forks source link

avformat_write_header error() error -22: Could not write header to 'null' #1501

Open hytgit018 opened 4 years ago

hytgit018 commented 4 years ago

hello: When I deploy the service to a Linux system, the following error occurs: org.bytedeco.javacv.FrameRecorder$Exception: avformat_write_header error() error -22: Could not write header to 'null' at com.junction.entity.FFmpegFrameRecorder.startUnsafe(FFmpegFrameRecorder.java:946) at com.junction.entity.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:425) at com.junction.entity.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:420) at com.junction.entity.RtmpPush.push(RtmpPush.java:191) at com.junction.entity.RtmpPush.push(RtmpPush.java:304) at com.junction.entity.RealPlay.run(RealPlay.java:225)

saudet commented 4 years ago

What is the error message that gets display on the console?

hytgit018 commented 4 years ago

This is the print log:

Error: [NULL @ 0x7fa750586e40] non-existing PPS 0 referenced

Debug: [AVBSFContext @ 0x7fa7500e11c0] nal_unit_type: 1(Coded slice of a non-IDR picture), nal_ref_idc: 3

Debug: [h264 @ 0x7fa750586e40] nal_unit_type: 1(Coded slice of a non-IDR picture), nal_ref_idc: 3

Error: [h264 @ 0x7fa750586e40] non-existing PPS 0 referenced

Error: [h264 @ 0x7fa750586e40] decode_slice_header error

Error: [h264 @ 0x7fa750586e40] no frame!

Debug: [mpeg @ 0x7fa7500def00] Probe buffer size limit of 4096 bytes reached

Warning: [mpeg @ 0x7fa7500def00] Stream #1: not enough frames to estimate rate; consider increasing probesize

Info: [mpeg @ 0x7fa7500def00] decoding for stream 1 failed

Warning: [mpeg @ 0x7fa7500def00] Could not find codec parameters for stream 0 (Audio: mp2, 0 channels): unspecified frame size
Consider increasing the value for the 'analyzeduration' and 'probesize' options

Warning: [mpeg @ 0x7fa7500def00] Could not find codec parameters for stream 1 (Video: h264, 1 reference frame, none(left)): unspecified size
Consider increasing the value for the 'analyzeduration' and 'probesize' options

Debug: [mpeg @ 0x7fa7500def00] After avformat_find_stream_info() pos: 558116 bytes read:559104 seeks:0 frames:1

Info: Input #0, mpeg, from 'java.io.BufferedInputStream@24f4f82d':

Info:   Duration: 
Info: N/A
Info: , start: 
Info: 10.183000
Info: , bitrate: 
Info: N/A
Info: 

Info:     Stream #0:0
Info: [0x1c0]
Debug: , 0, 1/90000
Info: : Audio: mp2, 0 channels
Info: 

Info:     Stream #0:1
Info: [0x1e0]
Debug: , 1, 1/90000
Info: : Video: h264, 1 reference frame, none(left)
Info: , 
Info: 90k tbr, 
Info: 90k tbn
Info: 

Error: [IMGUTILS @ 0x7fa7dc1a8520] Picture size 0x0 is invalid

Error: [IMGUTILS @ 0x7fa7dc1a8500] Picture size 0x0 is invalid

Debug: [rtmp @ 0x7fa750021f00] No default whitelist set

Debug: [tcp @ 0x7fa75001ff00] No default whitelist set

Debug: [tcp @ 0x7fa75001ff00] Original list of addresses:

Debug: [tcp @ 0x7fa75001ff00] Address 192.168.254.154 port 1935

Debug: [tcp @ 0x7fa75001ff00] Interleaved list of addresses:

Debug: [tcp @ 0x7fa75001ff00] Address 192.168.254.154 port 1935

Debug: [tcp @ 0x7fa75001ff00] Starting connection attempt to 192.168.254.154 port 1935

Debug: [tcp @ 0x7fa75001ff00] Successfully connected to 192.168.254.154 port 1935

Debug: [rtmp @ 0x7fa750021f00] Handshaking...

Debug: [rtmp @ 0x7fa750021f00] Type answer 3

Debug: [rtmp @ 0x7fa750021f00] Server version 1.0.5.4

Debug: [rtmp @ 0x7fa750021f00] Proto = rtmp, path = /live/37a2cf9d-eeea-4b3c-b45b-7166435df75e, app = live, fname = 37a2cf9d-eeea-4b3c-b45b-7166435df75e

Debug: [rtmp @ 0x7fa750021f00] Window acknowledgement size = 2500000

Debug: [rtmp @ 0x7fa750021f00] Max sent, unacked = 2500000

Debug: [rtmp @ 0x7fa750021f00] New incoming chunk size = 60000

Debug: [rtmp @ 0x7fa750021f00] Releasing stream...

Debug: [rtmp @ 0x7fa750021f00] FCPublish stream...

Debug: [rtmp @ 0x7fa750021f00] Creating stream...

Debug: [rtmp @ 0x7fa750021f00] Sending publish command for '37a2cf9d-eeea-4b3c-b45b-7166435df75e'

Error: [flv @ 0x7fa750343340] No streams to mux were specified

Debug: [AVIOContext @ 0x7fa750089780] Statistics: 0 seeks, 0 writeouts

Debug: [rtmp @ 0x7fa750021f00] UnPublishing stream...

Debug: [rtmp @ 0x7fa750021f00] Deleting stream...

org.bytedeco.javacv.FrameRecorder$Exception: avformat_write_header error() error -22: Could not write header to 'null'
    at com.junction.entity.FFmpegFrameRecorder.startUnsafe(FFmpegFrameRecorder.java:946)
    at com.junction.entity.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:425)
    at com.junction.entity.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:420)
    at com.junction.entity.RtmpPush.push(RtmpPush.java:191)
    at com.junction.entity.RtmpPush.push(RtmpPush.java:304)
    at com.junction.entity.RealPlay.run(RealPlay.java:225)

This is my code:

    grabber = new FFmpegFrameGrabber(inputStream, 0);
            grabber.setVideoOption("vcodec", "copy");
            grabber.setFormat("mpeg");
            grabber.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
            grabber.setVideoCodec(avcodec.AV_CODEC_ID_HEVC);
            grabber.start();
            this.recorder = new FFmpegFrameRecorder(cameraPojo.getRtmp(), grabber.getImageWidth(), grabber.getImageHeight(),
                    0);
            this.recorder.setInterleaved(true);
            this.recorder.setVideoOptions(this.videoOption);
            this.recorder.setVideoBitrate(bitrate);
            this.recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            this.recorder.setFormat("flv");
            this.recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
            this.recorder.setFrameRate(framerate);
            this.recorder.setGopSize((int) framerate * 2);
            AVFormatContext fc = null;
            fc = grabber.getFormatContext();
            this.recorder.start(fc);    
            grabber.flush();
            AVPacket pkt = null;
            long dts = 0;
            long pts = 0;
            long startTime = 0;
            for (int no_frame_index = 0; no_frame_index < 5 && err_index < 5;) {    
                nowThread.sleep(1);
                if (exitcode == 1) {
                    break;
                }
                pkt = grabber.grabPacket();
                if (pkt == null || pkt.size() <= 0 || pkt.data() == null) {
                    no_frame_index++;
                    exitcode = 2;
                    continue;
                }
                if (pkt.dts() == avutil.AV_NOPTS_VALUE && pkt.pts() == avutil.AV_NOPTS_VALUE || pkt.pts() < dts) {
                    err_index++;
                    exitcode = 2;
                    av_packet_unref(pkt);
                    continue;
                }

                if (pkt.stream_index() == 1) {
                    continue;
                }else {

                    pkt.pts(pts);
                    pkt.dts(dts);
                    err_index += (recorder.recordPacket(pkt) ? 0 : 1);
                }
                timebase = grabber.getFormatContext().streams(pkt.stream_index()).time_base().den();
                pts += timebase / (int) framerate;
                dts += timebase / (int) framerate;
                av_packet_unref(pkt);
            }
saudet commented 4 years ago

It looks like you're trying to encode an empty image, that's not going to work. Make sure all your video frames are valid images.

hytgit018 commented 4 years ago

Thanks!

saudet commented 4 years ago

Actually, it looks like you're trying to create an interleaved stream, but you're specifying no audio channels. You'll either need to not do interleaved, or add an audio channel.