Remove all the scaling and conversion stuff. Use packet->decode. Set keyframe flag. return codes of functions are now -1 for failure, 0 for failure but no error and 1 for success.
This commit is contained in:
parent
7c9db96acc
commit
57542b01d5
|
@ -72,11 +72,7 @@ RemoteCameraRtsp::RemoteCameraRtsp(
|
|||
mRawFrame = nullptr;
|
||||
mFrame = nullptr;
|
||||
frameCount = 0;
|
||||
startTime=0;
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
mConvertContext = nullptr;
|
||||
#endif
|
||||
/* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */
|
||||
if ( colours == ZM_COLOUR_RGB32 ) {
|
||||
subpixelorder = ZM_SUBPIX_ORDER_RGBA;
|
||||
|
@ -96,13 +92,6 @@ RemoteCameraRtsp::~RemoteCameraRtsp() {
|
|||
av_frame_free(&mFrame);
|
||||
av_frame_free(&mRawFrame);
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mConvertContext ) {
|
||||
sws_freeContext(mConvertContext);
|
||||
mConvertContext = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( mCodecContext ) {
|
||||
avcodec_close(mCodecContext);
|
||||
mCodecContext = nullptr; // Freed by avformat_free_context in the destructor of RtspThread class
|
||||
|
@ -167,7 +156,6 @@ int RemoteCameraRtsp::PrimeCapture() {
|
|||
mVideoStreamId = -1;
|
||||
mAudioStreamId = -1;
|
||||
|
||||
|
||||
// Find the first video stream.
|
||||
for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ ) {
|
||||
if ( is_video_stream(mFormatContext->streams[i]) ) {
|
||||
|
@ -233,30 +221,8 @@ int RemoteCameraRtsp::PrimeCapture() {
|
|||
Fatal("Image size mismatch. Required: %d Available: %d", pSize, imagesize);
|
||||
}
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
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");
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
/*
|
||||
#if HAVE_LIBSWSCALE
|
||||
if(!sws_isSupportedInput(mCodecContext->pix_fmt)) {
|
||||
Fatal("swscale does not support the codec format: %c%c%c%c",(mCodecContext->pix_fmt)&0xff,((mCodecContext->pix_fmt>>8)&0xff),((mCodecContext->pix_fmt>>16)&0xff),((mCodecContext->pix_fmt>>24)&0xff));
|
||||
}
|
||||
|
||||
if(!sws_isSupportedOutput(imagePixFormat)) {
|
||||
Fatal("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff));
|
||||
}
|
||||
|
||||
#else // HAVE_LIBSWSCALE
|
||||
Fatal( "You must compile ffmpeg with the --enable-swscale option to use RTSP cameras" );
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} // end PrimeCapture
|
||||
|
||||
int RemoteCameraRtsp::PreCapture() {
|
||||
if ( !rtspThread->isRunning() )
|
||||
|
@ -265,7 +231,7 @@ int RemoteCameraRtsp::PreCapture() {
|
|||
Error("Cannot precapture, no RTP sources");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RemoteCameraRtsp::Capture(ZMPacket &zm_packet) {
|
||||
|
@ -273,13 +239,6 @@ int RemoteCameraRtsp::Capture( ZMPacket &zm_packet ) {
|
|||
int frameComplete = false;
|
||||
AVPacket *packet = &zm_packet.packet;
|
||||
|
||||
/* Request a writeable buffer of the target image */
|
||||
directbuffer = zm_packet.image->WriteBuffer(width, height, colours, subpixelorder);
|
||||
if ( directbuffer == nullptr ) {
|
||||
Error("Failed requesting writeable buffer for the captured image.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ( !frameComplete ) {
|
||||
buffer.clear();
|
||||
if ( !rtspThread->isRunning() )
|
||||
|
@ -305,6 +264,8 @@ int RemoteCameraRtsp::Capture( ZMPacket &zm_packet ) {
|
|||
lastPps = buffer;
|
||||
continue;
|
||||
} else if ( nalType == 5 ) {
|
||||
packet->flags |= AV_PKT_FLAG_KEY;
|
||||
zm_packet.keyframe = 1;
|
||||
// IDR
|
||||
buffer += lastSps;
|
||||
buffer += lastPps;
|
||||
|
@ -315,57 +276,23 @@ int RemoteCameraRtsp::Capture( ZMPacket &zm_packet ) {
|
|||
Debug(3, "Not an h264 packet");
|
||||
}
|
||||
|
||||
// Don't need to do this... as zmPacket does it.
|
||||
//av_init_packet( &packet );
|
||||
|
||||
while ( (!frameComplete) && (buffer.size() > 0) ) {
|
||||
packet->data = buffer.head();
|
||||
packet->size = buffer.size();
|
||||
bytes += packet->size;
|
||||
|
||||
// So I think this is the magic decode step. Result is a raw image?
|
||||
int len = zm_send_packet_receive_frame(mCodecContext, mRawFrame, *packet);
|
||||
if ( len < 0 ) {
|
||||
if ( 1 != zm_packet.decode(mCodecContext) ) {
|
||||
Error("Error while decoding frame %d", frameCount);
|
||||
Hexdump(Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size());
|
||||
buffer.clear();
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
int len = packet->size;
|
||||
|
||||
frameComplete = true;
|
||||
Debug(2, "Frame: %d - %d/%d", frameCount, len, buffer.size());
|
||||
buffer -= len;
|
||||
}
|
||||
// At this point, we either have a frame or ran out of buffer. What happens if we run out of buffer?
|
||||
if ( frameComplete ) {
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if ( mConvertContext == nullptr ) {
|
||||
mConvertContext = sws_getContext(
|
||||
mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt,
|
||||
width, height, imagePixFormat, SWS_BICUBIC, nullptr, nullptr, nullptr);
|
||||
|
||||
if ( mConvertContext == nullptr )
|
||||
Fatal("Unable to create conversion context");
|
||||
|
||||
if (
|
||||
((unsigned int)mRawFrame->width != width)
|
||||
||
|
||||
((unsigned int)mRawFrame->height != height)
|
||||
) {
|
||||
Warning("Monitor dimensions are %dx%d but camera is sending %dx%d",
|
||||
width, height, mRawFrame->width, mRawFrame->height);
|
||||
}
|
||||
}
|
||||
|
||||
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++;
|
||||
} /* frame complete */
|
||||
} /* getFrame() */
|
||||
} // end while true
|
||||
|
||||
|
@ -373,6 +300,6 @@ int RemoteCameraRtsp::Capture( ZMPacket &zm_packet ) {
|
|||
} // end int RemoteCameraRtsp::Capture(ZMPacket &packet)
|
||||
|
||||
int RemoteCameraRtsp::PostCapture() {
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif // HAVE_LIBAVFORMAT
|
||||
|
|
|
@ -55,22 +55,12 @@ protected:
|
|||
|
||||
#if HAVE_LIBAVFORMAT
|
||||
AVFormatContext *mFormatContext;
|
||||
int mVideoStreamId;
|
||||
int mAudioStreamId;
|
||||
AVCodecContext *mCodecContext;
|
||||
AVCodec *mCodec;
|
||||
AVFrame *mRawFrame;
|
||||
AVFrame *mFrame;
|
||||
_AVPIXELFORMAT imagePixFormat;
|
||||
#endif // HAVE_LIBAVFORMAT
|
||||
bool wasRecording;
|
||||
VideoStore *videoStore;
|
||||
char oldDirectory[4096];
|
||||
int64_t startTime;
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
struct SwsContext *mConvertContext;
|
||||
#endif
|
||||
|
||||
public:
|
||||
RemoteCameraRtsp( unsigned int p_monitor_id, const std::string &method, const std::string &host, const std::string &port, const std::string &path, int p_width, int p_height, bool p_rtsp_describe, int p_colours, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, bool p_record_audio );
|
||||
|
@ -86,6 +76,18 @@ public:
|
|||
int Capture( ZMPacket &p );
|
||||
int PostCapture();
|
||||
int Close() { return 0; };
|
||||
AVStream *get_VideoStream() {
|
||||
if ( mVideoStreamId != -1 )
|
||||
return mFormatContext->streams[mVideoStreamId];
|
||||
return nullptr;
|
||||
}
|
||||
AVStream *get_AudioStream() {
|
||||
if ( mAudioStreamId != -1 )
|
||||
return mFormatContext->streams[mAudioStreamId];
|
||||
return nullptr;
|
||||
}
|
||||
AVCodecContext *get_VideoCodecContext() { return mVideoCodecContext; };
|
||||
AVCodecContext *get_AudioCodecContext() { return mAudioCodecContext; };
|
||||
};
|
||||
|
||||
#endif // ZM_REMOTE_CAMERA_RTSP_H
|
||||
|
|
Loading…
Reference in New Issue