bytedeco / javacv

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

Javacv push problem #780

Open RivsDC opened 6 years ago

RivsDC commented 6 years ago
 new Thread(){
                    public void run() {
                        FrameGrabber grabber = null;
                        try {
                            grabber = FFmpegFrameGrabber.createDefault(cameraInfo.getRtspHD());         
                            System.out.println(grabber.getPixelFormat()); //3 
                        } catch (org.bytedeco.javacv.FrameGrabber.Exception e2) {
                            e2.printStackTrace();
                        }  
                        grabber.setOption("rtsp_transport", "tcp");
                        grabber.setImageHeight(576);
                        grabber.setImageWidth(720);
                        String path = getPath(cameraInfo.getId());
                        FrameRecorder recorder = null;
                        try {
                            recorder = FrameRecorder.createDefault(path, 720, 576);
                        } catch (org.bytedeco.javacv.FrameRecorder.Exception e2) {
                            e2.printStackTrace();
                        } 
                        recorder.setVideoOption("tune","zerolatency");
                        recorder.setVideoOption("preset","ultrafast");
                        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
                        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
                        recorder.setVideoBitrate(400000);
                        recorder.setFormat("flv");  
                        recorder.setFrameRate(25);  
                        recorder.setGopSize(25); 
                        try {  
                            grabber.start();  
                        } catch (Exception e) {  
                            try {  
                                grabber.restart(); 
                            } catch (Exception e1) {  
                                e1.printStackTrace();
                            }  
                        }  
                        try {  
                            recorder.start();  
                        } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {  
                            try {  
                                if(recorder!=null)  
                                {  
                                    recorder.stop();  
                                    recorder.start();  
                                }   
                            } catch (org.bytedeco.javacv.FrameRecorder.Exception e1) {  
                                e1.printStackTrace();
                            }  
                        }  
                        Frame grabframe = null;
                        long startTime=0;
                        try {
                            while ((grabframe=grabber.grab()) != null) {  
                                if (startTime == 0) {  
                                    startTime = System.currentTimeMillis();  
                                }  
                                long segment = System.currentTimeMillis() - startTime;
                                recorder.setTimestamp(1000 * (segment));
                                if(grabframe!=null){  
                                    recorder.record(grabframe);  
                                }  
                            }
                        } catch (org.bytedeco.javacv.FrameGrabber.Exception
                                | org.bytedeco.javacv.FrameRecorder.Exception e) {
                            e.printStackTrace();
                        }     
                        try {
                            recorder.stop();
                        } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
                            e.printStackTrace();
                        }  
                        try {
                            recorder.release();
                        } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
                            e.printStackTrace();
                        }  
                        try {
                            grabber.stop();
                        } catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
                            e.printStackTrace();
                        }   
                    }    
                }.start();                

The console prints the following information all the time,What's the solution?

[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
[swscaler @ 00000000287a4480] deprecated pixel format used, make sure you did set range correctly
saudet commented 6 years ago

If your camera uses MJPEG, it looks like this could be a workaround. Could you give it a try? https://stackoverflow.com/a/23216860/523744

thhart commented 6 years ago

This happens in "simple" frame grabbing as well. No scaling used whatsover. It looks like happening with specific camera models like Axis for instance, there is no chance to modify the pixel format there:

Stream #0:0: Video: h264 (Main), yuvj420p(pc, bt709, progressive), 1024x768 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 90k tbn, 180k tbc MJPEG is simply no option since it is magnitudes more inefficient and the H264 decoding is working really well. The only problem is the repeated warning in the console. It is really jamming. Is it possible to put out this only once or set an environment variable to get rid of these informations at all?

thhart commented 6 years ago

JFYI, I patched the ffmpeg sources to not using the warning level for this and pushed a new libswscale.so into the jar. I also committed to FFMPEG but only god knows if it goes through, whoever is interested should check this:

---
  libswscale/utils.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/libswscale/utils.c b/libswscale/utils.c
 index dcab70..af4aa1 100644
 --- a/libswscale/utils.c
 +++ b/libswscale/utils.c
 @@ -1182,7 +1182,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
      c->dstRange |= handle_jpeg(&c->dstFormat);

      if(srcFormat!=c->srcFormat || dstFormat!=c->dstFormat)
 -        av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
 +        av_log(c, AV_LOG_DEBUG, "deprecated pixel format used, make sure you did set range correctly\n");

      if (!c->contrast && !c->saturation && !c->dstFormatBpp)
          sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], c->srcRange,
--
saudet commented 6 years ago

@thhart According to the material above, we just need to override the pixel format in FFmpegFrameGrabber...

thhart commented 6 years ago

@saudet Which material? You mean like the code below? Not improving:

               FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("rtsp://192.168.0.160/axis-media/media.amp") {
                  public int getPixelFormat() {
                     int pixFormat = super.getPixelFormat();
                     switch (pixFormat) {
                     case AV_PIX_FMT_YUVJ420P :
                         pixFormat = AV_PIX_FMT_YUV420P;
                         break;
                     case AV_PIX_FMT_YUVJ422P  :
                         pixFormat = AV_PIX_FMT_YUV422P;
                         break;
                     case AV_PIX_FMT_YUVJ444P   :
                         pixFormat = AV_PIX_FMT_YUV444P;
                         break;
                     case AV_PIX_FMT_YUVJ440P :
                         pixFormat = AV_PIX_FMT_YUV440P;
                     default:
                         break;
                     }
                     return pixFormat;
                  }
               };
saudet commented 6 years ago

We need to modify that inside FFmpegFrameGrabber...

salamanders commented 6 years ago

New user, I believe I'm running into the same thing when trying to do a hello-world copy of an input mp4 to an output mp4.

saudet commented 6 years ago

@salamanders Just ignore the warning message until someone sends a pull request to fix this :)

gowridev commented 6 years ago

@saudet could you please tell us how to Make ffmpeg/javacv less verbose in java. So that we can hide the error. I am looking for similar solution. Could you please guide me regarding this.

saudet commented 6 years ago

Call av_log_set_level(AV_LOG_WARNING) or less: https://github.com/bytedeco/javacv/blob/master/src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java#L580

lessthanoptimal commented 6 years ago

Just wanted to clarify @saudet 's last comment. It still spams when you set the log level to warning, but when you set it to errors the billion warnings go away! Finally I can read the console output!

av_log_set_level(AV_LOG_ERROR);

RivsDC commented 6 years ago

@thhart I think I have found a good way, the code is as follows:   avutil.av_log_set_level(MAX_PRIORITY); Set the priority of the log to the highest level, and then the console will have no warning output.

mgroth0 commented 1 year ago

Is there another solution that doesn't involve setting the log level to ERROR? I want to see warnings in general, and the workaround in the previous comments have the side effect of disabling all warnings.