From 83e477e6be6b0e7b118edcc2de39c401fbaa13d9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 23 Sep 2019 10:52:57 -0400 Subject: [PATCH] CaptureAndRecord in remote camera rtsp doesn't work. Remove it. --- src/zm_remote_camera_rtsp.cpp | 293 +++++++--------------------------- src/zm_remote_camera_rtsp.h | 2 +- 2 files changed, 60 insertions(+), 235 deletions(-) diff --git a/src/zm_remote_camera_rtsp.cpp b/src/zm_remote_camera_rtsp.cpp index a26e2626d..cda60a32c 100644 --- a/src/zm_remote_camera_rtsp.cpp +++ b/src/zm_remote_camera_rtsp.cpp @@ -58,7 +58,7 @@ RemoteCameraRtsp::RemoteCameraRtsp( else if ( p_method == "rtpRtspHttp" ) method = RtspThread::RTP_RTSP_HTTP; else - Fatal( "Unrecognised method '%s' when creating RTSP camera %d", p_method.c_str(), monitor_id ); + Fatal("Unrecognised method '%s' when creating RTSP camera %d", p_method.c_str(), monitor_id); if ( capture ) { Initialise(); @@ -88,23 +88,23 @@ RemoteCameraRtsp::RemoteCameraRtsp( subpixelorder = ZM_SUBPIX_ORDER_NONE; imagePixFormat = AV_PIX_FMT_GRAY8; } else { - Panic("Unexpected colours: %d",colours); + Panic("Unexpected colours: %d", colours); } } // end RemoteCameraRtsp::RemoteCameraRtsp(...) RemoteCameraRtsp::~RemoteCameraRtsp() { - av_frame_free( &mFrame ); - av_frame_free( &mRawFrame ); + av_frame_free(&mFrame); + av_frame_free(&mRawFrame); #if HAVE_LIBSWSCALE if ( mConvertContext ) { - sws_freeContext( mConvertContext ); + sws_freeContext(mConvertContext); mConvertContext = NULL; } #endif if ( mCodecContext ) { - avcodec_close( mCodecContext ); + avcodec_close(mCodecContext); mCodecContext = NULL; // Freed by avformat_free_context in the destructor of RtspThread class } @@ -120,14 +120,9 @@ void RemoteCameraRtsp::Initialise() { // This allocates a buffer able to hold a raw fframe, which is a little artbitrary. Might be nice to get some // decent data on how large a buffer is really needed. I think in ffmpeg there are now some functions to do that. - buffer.size( max_size ); + buffer.size(max_size); - if ( logDebugging() ) - av_log_set_level( AV_LOG_DEBUG ); - else - av_log_set_level( AV_LOG_QUIET ); - - av_register_all(); + FFMPEGInit(); Connect(); } @@ -137,11 +132,11 @@ void RemoteCameraRtsp::Terminate() { } int RemoteCameraRtsp::Connect() { - rtspThread = new RtspThread( monitor_id, method, protocol, host, port, path, auth, rtsp_describe ); + rtspThread = new RtspThread(monitor_id, method, protocol, host, port, path, auth, rtsp_describe); rtspThread->start(); - return( 0 ); + return 0; } int RemoteCameraRtsp::Disconnect() { @@ -151,18 +146,18 @@ int RemoteCameraRtsp::Disconnect() { delete rtspThread; rtspThread = 0; } - return( 0 ); + return 0; } int RemoteCameraRtsp::PrimeCapture() { - Debug( 2, "Waiting for sources" ); + Debug(2, "Waiting for sources"); for ( int i = 0; i < 100 && !rtspThread->hasSources(); i++ ) { - usleep( 100000 ); + usleep(100000); } if ( !rtspThread->hasSources() ) - Fatal( "No RTSP sources" ); + Fatal("No RTSP sources"); - Debug( 2, "Got sources" ); + Debug(2, "Got sources"); mFormatContext = rtspThread->getFormatContext(); @@ -182,7 +177,7 @@ int RemoteCameraRtsp::PrimeCapture() { mVideoStreamId = i; continue; } else { - Debug(2, "Have another video stream." ); + Debug(2, "Have another video stream."); } } else #if (LIBAVCODEC_VERSION_CHECK(52, 64, 0, 64, 0) || LIBAVUTIL_VERSION_CHECK(50, 14, 0, 14, 0)) @@ -194,7 +189,7 @@ int RemoteCameraRtsp::PrimeCapture() { if ( mAudioStreamId == -1 ) { mAudioStreamId = i; } else { - Debug(2, "Have another audio stream." ); + Debug(2, "Have another audio stream."); } } else { Debug(1, "Have unknown codec type in stream %d : %d", i, mFormatContext->streams[i]->codec->codec_type); @@ -202,25 +197,25 @@ int RemoteCameraRtsp::PrimeCapture() { } // end foreach stream if ( mVideoStreamId == -1 ) - Fatal( "Unable to locate video stream" ); + Fatal("Unable to locate video stream"); if ( mAudioStreamId == -1 ) - Debug( 3, "Unable to locate audio stream" ); + Debug(3, "Unable to locate audio stream"); // Get a pointer to the codec context for the video stream mCodecContext = mFormatContext->streams[mVideoStreamId]->codec; // Find the decoder for the video stream - mCodec = avcodec_find_decoder( mCodecContext->codec_id ); + mCodec = avcodec_find_decoder(mCodecContext->codec_id); if ( mCodec == NULL ) - Panic( "Unable to locate codec %d decoder", mCodecContext->codec_id ); + Panic("Unable to locate codec %d decoder", mCodecContext->codec_id); // Open codec #if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0) - if ( avcodec_open( mCodecContext, mCodec ) < 0 ) + if ( avcodec_open(mCodecContext, mCodec) < 0 ) #else - if ( avcodec_open2( mCodecContext, mCodec, 0 ) < 0 ) + if ( avcodec_open2(mCodecContext, mCodec, 0) < 0 ) #endif - Panic( "Can't open codec" ); + Panic("Can't open codec"); // Allocate space for the native video frame #if LIBAVCODEC_VERSION_CHECK(55, 28, 1, 45, 101) @@ -236,17 +231,17 @@ int RemoteCameraRtsp::PrimeCapture() { mFrame = avcodec_alloc_frame(); #endif - if(mRawFrame == NULL || mFrame == NULL) - Fatal( "Unable to allocate frame(s)"); + if ( mRawFrame == NULL || mFrame == NULL ) + Fatal("Unable to allocate frame(s)"); #if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) - int pSize = av_image_get_buffer_size( imagePixFormat, width, height, 1 ); + int pSize = av_image_get_buffer_size(imagePixFormat, width, height, 1); #else - int pSize = avpicture_get_size( imagePixFormat, width, height ); + int pSize = avpicture_get_size(imagePixFormat, width, height); #endif if ( (unsigned int)pSize != imagesize ) { - Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); + Fatal("Image size mismatch. Required: %d Available: %d", pSize, imagesize); } /* #if HAVE_LIBSWSCALE @@ -263,17 +258,17 @@ int RemoteCameraRtsp::PrimeCapture() { #endif // HAVE_LIBSWSCALE */ - return( 0 ); + return 0; } int RemoteCameraRtsp::PreCapture() { if ( !rtspThread->isRunning() ) - return( -1 ); + return -1; if ( !rtspThread->hasSources() ) { - Error( "Cannot precapture, no RTP sources" ); - return( -1 ); + Error("Cannot precapture, no RTP sources"); + return -1; } - return( 0 ); + return 0; } int RemoteCameraRtsp::Capture( Image &image ) { @@ -293,10 +288,10 @@ int RemoteCameraRtsp::Capture( Image &image ) { if ( !rtspThread->isRunning() ) return -1; - if ( rtspThread->getFrame( buffer ) ) { - Debug( 3, "Read frame %d bytes", buffer.size() ); - Debug( 4, "Address %p", buffer.head() ); - Hexdump( 4, buffer.head(), 16 ); + if ( rtspThread->getFrame(buffer) ) { + Debug(3, "Read frame %d bytes", buffer.size()); + Debug(4, "Address %p", buffer.head()); + Hexdump(4, buffer.head(), 16); if ( !buffer.size() ) return -1; @@ -322,25 +317,25 @@ int RemoteCameraRtsp::Capture( Image &image ) { Debug(3, "Not an h264 packet"); } - av_init_packet( &packet ); + av_init_packet(&packet); - while ( !frameComplete && buffer.size() > 0 ) { + while ( !frameComplete && (buffer.size() > 0) ) { packet.data = buffer.head(); packet.size = buffer.size(); // So I think this is the magic decode step. Result is a raw image? #if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0) - int len = avcodec_decode_video2( mCodecContext, mRawFrame, &frameComplete, &packet ); + int len = avcodec_decode_video2(mCodecContext, mRawFrame, &frameComplete, &packet); #else - int len = avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size ); + int len = avcodec_decode_video(mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size); #endif if ( len < 0 ) { - Error( "Error while decoding frame %d", frameCount ); - Hexdump( Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size() ); + Error("Error while decoding frame %d", frameCount); + Hexdump(Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size()); buffer.clear(); continue; } - Debug( 2, "Frame: %d - %d/%d", frameCount, len, buffer.size() ); + Debug(2, "Frame: %d - %d/%d", frameCount, len, buffer.size()); //if ( buffer.size() < 400 ) //Hexdump( 0, buffer.head(), buffer.size() ); @@ -349,29 +344,32 @@ int RemoteCameraRtsp::Capture( Image &image ) { // At this point, we either have a frame or ran out of buffer. What happens if we run out of buffer? if ( frameComplete ) { - Debug( 3, "Got frame %d", frameCount ); + Debug(3, "Got frame %d", frameCount); - avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height ); + avpicture_fill((AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); #if HAVE_LIBSWSCALE - if(mConvertContext == NULL) { - mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL ); + if ( mConvertContext == NULL ) { + mConvertContext = sws_getContext( + mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, + width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL); - if(mConvertContext == NULL) - Fatal( "Unable to create conversion context"); + if ( mConvertContext == NULL ) + Fatal("Unable to create conversion context"); } - if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 ) - Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount ); + if ( sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize) < 0 ) + Fatal("Unable to convert raw format %u to target format %u at frame %d", + mCodecContext->pix_fmt, imagePixFormat, frameCount ); #else // HAVE_LIBSWSCALE - Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" ); + Fatal("You must compile ffmpeg with the --enable-swscale option to use RTSP cameras"); #endif // HAVE_LIBSWSCALE frameCount++; } /* frame complete */ - zm_av_packet_unref( &packet ); + zm_av_packet_unref(&packet); } /* getFrame() */ if ( frameComplete ) @@ -385,180 +383,7 @@ int RemoteCameraRtsp::Capture( Image &image ) { //Function to handle capture and store -int RemoteCameraRtsp::CaptureAndRecord(Image &image, timeval recording, char* event_file ) { - AVPacket packet; - uint8_t* directbuffer; - int frameComplete = false; - - while ( true ) { - -// WHY Are we clearing it? Might be something good in it. - buffer.clear(); - - if ( !rtspThread->isRunning() ) - return (-1); - - //Video recording - if ( recording.tv_sec ) { - // The directory we are recording to is no longer tied to the current event. - // Need to re-init the videostore with the correct directory and start recording again - // Not sure why we are only doing this on keyframe, al - if ( videoStore && (strcmp(oldDirectory, event_file)!=0) ) { - //don't open new videostore until we're on a key frame..would this require an offset adjustment for the event as a result?...if we store our key frame location with the event will that be enough? - Info("Re-starting video storage module"); - if ( videoStore ) { - delete videoStore; - videoStore = NULL; - } - } // end if changed to new event - - if ( ! videoStore ) { - //Instantiate the video storage module - - videoStore = new VideoStore((const char *)event_file, "mp4", - mFormatContext->streams[mVideoStreamId], - mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId], - this->getMonitor() ); - strcpy(oldDirectory, event_file); - } // end if ! videoStore - - } else { - if ( videoStore ) { - Info("Deleting videoStore instance"); - delete videoStore; - videoStore = NULL; - } - } // end if recording or not - - if ( rtspThread->getFrame( buffer ) ) { - Debug( 3, "Read frame %d bytes", buffer.size() ); - Debug( 4, "Address %p", buffer.head() ); - Hexdump( 4, buffer.head(), 16 ); - - if ( !buffer.size() ) - return( -1 ); - - if ( mCodecContext->codec_id == AV_CODEC_ID_H264 ) { - // SPS and PPS frames should be saved and appended to IDR frames - int nalType = (buffer.head()[3] & 0x1f); - - // SPS - if(nalType == 7) { - lastSps = buffer; - continue; - } else if(nalType == 8) { - // PPS - lastPps = buffer; - continue; - } else if(nalType == 5) { - // IDR - buffer += lastSps; - buffer += lastPps; - } - } // end if H264, what about other codecs? - - av_init_packet( &packet ); - - // Keep decoding until a complete frame is had. - while ( !frameComplete && buffer.size() > 0 ) { - packet.data = buffer.head(); - packet.size = buffer.size(); - - // Why are we checking for it being the video stream? Because it might be audio or something else. - // Um... we just initialized packet... we can't be testing for what it is yet.... - if ( packet.stream_index == mVideoStreamId ) { - // So this does the decode -#if LIBAVCODEC_VERSION_CHECK(52, 23, 0, 23, 0) - int len = avcodec_decode_video2( mCodecContext, mRawFrame, &frameComplete, &packet ); -#else - int len = avcodec_decode_video( mCodecContext, mRawFrame, &frameComplete, packet.data, packet.size ); -#endif - if ( len < 0 ) { - Error( "Error while decoding frame %d", frameCount ); - Hexdump( Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size() ); - buffer.clear(); - continue; - } - Debug( 2, "Frame: %d - %d/%d", frameCount, len, buffer.size() ); - //if ( buffer.size() < 400 ) - //Hexdump( 0, buffer.head(), buffer.size() ); - - buffer -= len; - - if ( frameComplete ) { - - Debug( 3, "Got frame %d", frameCount ); - - /* Request a writeable buffer of the target image */ - directbuffer = image.WriteBuffer(width, height, colours, subpixelorder); - if(directbuffer == NULL) { - Error("Failed requesting writeable buffer for the captured image."); - return (-1); - } - -#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) - av_image_fill_arrays(mFrame->data, mFrame->linesize, - directbuffer, imagePixFormat, width, height, 1); -#else - avpicture_fill( (AVPicture *)mFrame, directbuffer, - imagePixFormat, width, height); -#endif - - } // endif frameComplete - - if ( videoStore ) { - //Write the packet to our video store - int ret = videoStore->writeVideoFramePacket(&packet);//, &lastKeyframePkt); - if ( ret < 0 ) {//Less than zero and we skipped a frame -// Should not - zm_av_packet_unref( &packet ); - return 0; - } - } // end if videoStore, so we are recording - -#if HAVE_LIBSWSCALE - // Why are we re-scaling after writing out the packet? - if ( mConvertContext == NULL ) { - mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL ); - - if ( mConvertContext == NULL ) - Fatal( "Unable to create conversion context"); - } - - if ( sws_scale( mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mCodecContext->height, mFrame->data, mFrame->linesize ) < 0 ) - Fatal( "Unable to convert raw format %u to target format %u at frame %d", mCodecContext->pix_fmt, imagePixFormat, frameCount ); -#else // HAVE_LIBSWSCALE - Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" ); -#endif // HAVE_LIBSWSCALE - - frameCount++; - - } else if ( packet.stream_index == mAudioStreamId ) { - Debug( 4, "Got audio packet" ); - if ( videoStore && record_audio ) { - Debug( 4, "Storing Audio packet" ); - //Write the packet to our video store - int ret = videoStore->writeAudioFramePacket( &packet ); //FIXME no relevance of last key frame - if ( ret < 0 ) { //Less than zero and we skipped a frame - zm_av_packet_unref( &packet ); - return 0; - } - } - } // end if video or audio packet - - zm_av_packet_unref( &packet ); - } // end while ! framecomplete and buffer.size() - if(frameComplete) - return (1); - } /* getFrame() */ - -} // end while true - -// can never get here. - return (0) ; -} // int RemoteCameraRtsp::CaptureAndRecord( Image &image, bool recording, char* event_file ) - int RemoteCameraRtsp::PostCapture() { - return( 0 ); + return 0; } #endif // HAVE_LIBAVFORMAT diff --git a/src/zm_remote_camera_rtsp.h b/src/zm_remote_camera_rtsp.h index 5fa5a0778..be7542a84 100644 --- a/src/zm_remote_camera_rtsp.h +++ b/src/zm_remote_camera_rtsp.h @@ -85,7 +85,7 @@ public: int PreCapture(); int Capture( Image &image ); int PostCapture(); - int CaptureAndRecord( Image &image, timeval recording, char* event_directory ); + int CaptureAndRecord( Image &image, timeval recording, char* event_directory ) {return 0;}; int Close() { return 0; }; };