create zm_packet
parent
980b088d57
commit
f19b3d5505
|
@ -4,7 +4,7 @@
|
|||
configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY)
|
||||
|
||||
# Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc)
|
||||
set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_camera.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp)
|
||||
set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_camera.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packet.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp)
|
||||
|
||||
# A fix for cmake recompiling the source files for every target.
|
||||
add_library(zm STATIC ${ZM_BIN_SRC_FILES})
|
||||
|
|
|
@ -63,6 +63,7 @@ FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::stri
|
|||
mOpenStart = 0;
|
||||
mReopenThread = 0;
|
||||
videoStore = NULL;
|
||||
video_last_pts = 0;
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
mConvertContext = NULL;
|
||||
|
@ -645,24 +646,24 @@ Debug(5, "After av_read_frame (%d)", ret );
|
|||
|
||||
// Need to write out all the frames from the last keyframe?
|
||||
unsigned int packet_count = 0;
|
||||
AVPacket *queued_packet;
|
||||
ZMPacket *queued_packet;
|
||||
while ( ( queued_packet = packetqueue.popPacket() ) ) {
|
||||
AVPacket *avp = queued_packet->av_packet();
|
||||
packet_count += 1;
|
||||
//Write the packet to our video store
|
||||
Debug(2, "Writing queued packet stream: %d KEY %d, remaining (%d)", queued_packet->stream_index, queued_packet->flags & AV_PKT_FLAG_KEY, packetqueue.size() );
|
||||
if ( queued_packet->stream_index == mVideoStreamId ) {
|
||||
ret = videoStore->writeVideoFramePacket( queued_packet );
|
||||
} else if ( queued_packet->stream_index == mAudioStreamId ) {
|
||||
ret = videoStore->writeAudioFramePacket( queued_packet );
|
||||
Debug(2, "Writing queued packet stream: %d KEY %d, remaining (%d)", avp->stream_index, avp->flags & AV_PKT_FLAG_KEY, packetqueue.size() );
|
||||
if ( avp->stream_index == mVideoStreamId ) {
|
||||
ret = videoStore->writeVideoFramePacket( avp );
|
||||
} else if ( avp->stream_index == mAudioStreamId ) {
|
||||
ret = videoStore->writeAudioFramePacket( avp );
|
||||
} else {
|
||||
Warning("Unknown stream id in queued packet (%d)", queued_packet->stream_index );
|
||||
Warning("Unknown stream id in queued packet (%d)", avp->stream_index );
|
||||
ret = -1;
|
||||
}
|
||||
if ( ret < 0 ) {
|
||||
//Less than zero and we skipped a frame
|
||||
}
|
||||
zm_av_packet_unref( queued_packet );
|
||||
av_free( queued_packet );
|
||||
delete queued_packet;
|
||||
} // end while packets in the packetqueue
|
||||
Debug(2, "Wrote %d queued packets", packet_count );
|
||||
} // end if ! wasRecording
|
||||
|
@ -682,7 +683,7 @@ Debug(5, "After av_read_frame (%d)", ret );
|
|||
packetqueue.clearQueue();
|
||||
}
|
||||
if ( packet.pts && video_last_pts > packet.pts ) {
|
||||
Warning( "Clearing queue due to out of order pts");
|
||||
Warning( "Clearing queue due to out of order pts packet.pts=%d video_last_pts=%d", packet.pts, video_last_pts );
|
||||
packetqueue.clearQueue();
|
||||
}
|
||||
}
|
||||
|
@ -706,6 +707,24 @@ Debug(5, "After av_read_frame (%d)", ret );
|
|||
}
|
||||
}
|
||||
Debug(4, "about to decode video" );
|
||||
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||
ret = avcodec_send_packet( mVideoCodecContext, &packet );
|
||||
if ( ret < 0 ) {
|
||||
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
|
||||
Error( "Unable to send packet at frame %d: %s, continuing", frameCount, errbuf );
|
||||
zm_av_packet_unref( &packet );
|
||||
continue;
|
||||
}
|
||||
ret = avcodec_receive_frame( mVideoCodecContext, mRawFrame );
|
||||
if ( ret < 0 ) {
|
||||
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
|
||||
Error( "Unable to send packet at frame %d: %s, continuing", frameCount, errbuf );
|
||||
zm_av_packet_unref( &packet );
|
||||
continue;
|
||||
}
|
||||
frameComplete = 1;
|
||||
# else
|
||||
ret = zm_avcodec_decode_video( mVideoCodecContext, mRawFrame, &frameComplete, &packet );
|
||||
if ( ret < 0 ) {
|
||||
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
|
||||
|
@ -713,6 +732,7 @@ Debug(5, "After av_read_frame (%d)", ret );
|
|||
zm_av_packet_unref( &packet );
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
Debug( 4, "Decoded video packet at frame %d", frameCount );
|
||||
|
||||
|
@ -728,7 +748,9 @@ Debug(5, "After av_read_frame (%d)", ret );
|
|||
zm_av_packet_unref( &packet );
|
||||
return (-1);
|
||||
}
|
||||
avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height);
|
||||
// avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height);
|
||||
av_image_fill_arrays(mFrame->data, mFrame->linesize, directbuffer, imagePixFormat, width, height, 1);
|
||||
|
||||
|
||||
if (sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize,
|
||||
0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0) {
|
||||
|
@ -758,7 +780,7 @@ Debug(5, "After av_read_frame (%d)", ret );
|
|||
}
|
||||
} else {
|
||||
#if LIBAVUTIL_VERSION_CHECK(54, 23, 0, 23, 0)
|
||||
Debug( 3, "Some other stream index %d, %s", packet.stream_index, av_get_media_type_string( mFormatContext->streams[packet.stream_index]->codec->codec_type) );
|
||||
Debug( 3, "Some other stream index %d, %s", packet.stream_index, av_get_media_type_string( mFormatContext->streams[packet.stream_index]->codecpar->codec_type) );
|
||||
#else
|
||||
Debug( 3, "Some other stream index %d", packet.stream_index );
|
||||
#endif
|
||||
|
|
|
@ -1357,6 +1357,7 @@ bool Monitor::Analyse() {
|
|||
if ( event ) {
|
||||
//TODO: We shouldn't have to do this every time. Not sure why it clears itself if this isn't here??
|
||||
snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile());
|
||||
Debug( 3, "Detected new event at (%d.%d)", timestamp->tv_sec,timestamp->tv_usec );
|
||||
|
||||
if ( section_length ) {
|
||||
int section_mod = timestamp->tv_sec%section_length;
|
||||
|
@ -3029,7 +3030,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
ref_image.WriteJpeg( diag_path );
|
||||
}
|
||||
|
||||
ref_image.Delta( comp_image, &delta_image);
|
||||
ref_image.Delta( comp_image, &delta_image );
|
||||
|
||||
if ( config.record_diag_images ) {
|
||||
static char diag_path[PATH_MAX] = "";
|
||||
|
@ -3117,6 +3118,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
if ( alarm ) {
|
||||
for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) {
|
||||
Zone *zone = zones[n_zone];
|
||||
// Wasn't this zone already checked above?
|
||||
if ( !zone->IsInclusive() ) {
|
||||
continue;
|
||||
}
|
||||
|
@ -3151,7 +3153,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z
|
|||
zoneSet.insert( zone->Label() );
|
||||
}
|
||||
}
|
||||
} // end if alaram or not
|
||||
} // end if alarm or not
|
||||
}
|
||||
|
||||
if ( top_score > 0 ) {
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
//ZoneMinder Packet Implementation Class
|
||||
//Copyright 2017 ZoneMinder LLC
|
||||
//
|
||||
//This file is part of ZoneMinder.
|
||||
//
|
||||
//ZoneMinder is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//ZoneMinder is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with ZoneMinder. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "zm_packet.h"
|
||||
#include "zm_ffmpeg.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ZMPacket::ZMPacket( AVPacket *p ) {
|
||||
av_init_packet( &packet );
|
||||
if ( zm_av_packet_ref( &packet, p ) < 0 ) {
|
||||
Error("error refing packet");
|
||||
}
|
||||
gettimeofday( ×tamp, NULL );
|
||||
}
|
||||
|
||||
ZMPacket::ZMPacket( AVPacket *p, struct timeval *t ) {
|
||||
av_init_packet( &packet );
|
||||
if ( zm_av_packet_ref( &packet, p ) < 0 ) {
|
||||
Error("error refing packet");
|
||||
}
|
||||
timestamp = *t;
|
||||
}
|
||||
|
||||
ZMPacket::~ZMPacket() {
|
||||
zm_av_packet_unref( &packet );
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
//ZoneMinder Packet Wrapper Class
|
||||
//Copyright 2017 ZoneMinder LLC
|
||||
//
|
||||
//This file is part of ZoneMinder.
|
||||
//
|
||||
//ZoneMinder is free software: you can redistribute it and/or modify
|
||||
//it under the terms of the GNU General Public License as published by
|
||||
//the Free Software Foundation, either version 3 of the License, or
|
||||
//(at your option) any later version.
|
||||
//
|
||||
//ZoneMinder is distributed in the hope that it will be useful,
|
||||
//but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
//GNU General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU General Public License
|
||||
//along with ZoneMinder. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#ifndef ZM_PACKET_H
|
||||
#define ZM_PACKET_H
|
||||
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
|
||||
class ZMPacket {
|
||||
public:
|
||||
|
||||
AVPacket packet;
|
||||
struct timeval timestamp;
|
||||
public:
|
||||
AVPacket *av_packet() { return &packet; }
|
||||
ZMPacket( AVPacket *packet, struct timeval *timestamp );
|
||||
ZMPacket( AVPacket *packet );
|
||||
~ZMPacket();
|
||||
};
|
||||
|
||||
#endif /* ZM_PACKET_H */
|
|
@ -33,41 +33,38 @@ zm_packetqueue::~zm_packetqueue() {
|
|||
|
||||
}
|
||||
|
||||
bool zm_packetqueue::queuePacket( AVPacket* packet ) {
|
||||
bool zm_packetqueue::queuePacket( ZMPacket* zm_packet ) {
|
||||
pktQueue.push( zm_packet );
|
||||
|
||||
return true;
|
||||
}
|
||||
bool zm_packetqueue::queuePacket( AVPacket* av_packet ) {
|
||||
|
||||
AVPacket *input_ref = (AVPacket *)av_malloc(sizeof(AVPacket));
|
||||
av_init_packet( input_ref );
|
||||
if ( zm_av_packet_ref( input_ref, packet ) < 0 ) {
|
||||
Error("error refing packet");
|
||||
av_free(input_ref);
|
||||
return false;
|
||||
}
|
||||
ZMPacket *zm_packet = new ZMPacket( av_packet );
|
||||
|
||||
pktQueue.push( input_ref );
|
||||
pktQueue.push( zm_packet );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AVPacket* zm_packetqueue::popPacket( ) {
|
||||
ZMPacket* zm_packetqueue::popPacket( ) {
|
||||
if ( pktQueue.empty() ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVPacket *packet = pktQueue.front();
|
||||
ZMPacket *packet = pktQueue.front();
|
||||
pktQueue.pop();
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
void zm_packetqueue::clearQueue() {
|
||||
AVPacket *packet = NULL;
|
||||
ZMPacket *packet = NULL;
|
||||
while(!pktQueue.empty()) {
|
||||
|
||||
packet = pktQueue.front();
|
||||
pktQueue.pop();
|
||||
// If we clear it, then no freeing gets done, whereas when we pop off, we assume that the packet was freed somewhere else.
|
||||
zm_av_packet_unref( packet );
|
||||
av_free( packet );
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
//#include <boost/interprocess/containers/map.hpp>
|
||||
//#include <boost/interprocess/allocators/allocator.hpp>
|
||||
#include <queue>
|
||||
#include "zm_packet.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
|
@ -33,18 +34,17 @@ class zm_packetqueue {
|
|||
public:
|
||||
zm_packetqueue();
|
||||
virtual ~zm_packetqueue();
|
||||
bool queuePacket( AVPacket* packet, struct timeval *timestamp );
|
||||
bool queuePacket( ZMPacket* packet );
|
||||
bool queuePacket( AVPacket* packet );
|
||||
AVPacket * popPacket( );
|
||||
bool popVideoPacket(AVPacket* packet);
|
||||
bool popAudioPacket(AVPacket* packet);
|
||||
ZMPacket * popPacket( );
|
||||
bool popVideoPacket(ZMPacket* packet);
|
||||
bool popAudioPacket(ZMPacket* packet);
|
||||
void clearQueue( );
|
||||
unsigned int size();
|
||||
private:
|
||||
std::queue<AVPacket *> pktQueue;
|
||||
std::queue<ZMPacket *> pktQueue;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* ZM_PACKETQUEUE_H */
|
||||
|
||||
|
|
|
@ -470,7 +470,11 @@ Debug(1, "Have audio encoder, need to flush it's output" );
|
|||
int64_t size;
|
||||
|
||||
while(1) {
|
||||
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
|
||||
ret = avcodec_receive_packet( audio_output_context, &pkt );
|
||||
#else
|
||||
ret = avcodec_encode_audio2( audio_output_context, &pkt, NULL, &got_packet );
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
Error("ERror encoding audio while flushing");
|
||||
break;
|
||||
|
@ -871,8 +875,11 @@ av_frame_get_best_effort_timestamp(output_frame)
|
|||
* Encode the audio frame and store it in the temporary packet.
|
||||
* The output audio stream encoder is used to do this.
|
||||
*/
|
||||
if (( ret = avcodec_encode_audio2( audio_output_context, &opkt,
|
||||
output_frame, &data_present )) < 0) {
|
||||
#if LIBAVCODEC_VERSION_CHECK(58, 0, 0, 0, 0)
|
||||
if (( ret = avcodec_receive_packet( audio_output_context, &opkt )) < 0 ) {
|
||||
#else
|
||||
if (( ret = avcodec_encode_audio2( audio_output_context, &opkt, output_frame, &data_present )) < 0) {
|
||||
#endif
|
||||
Error( "Could not encode frame (error '%s')",
|
||||
av_make_error_string(ret).c_str());
|
||||
zm_av_packet_unref(&opkt);
|
||||
|
|
Loading…
Reference in New Issue