diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 89df6bc00..5cec89125 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -1259,6 +1259,7 @@ bool EventStream::sendFrame( int delta_us ) { static struct stat filestat; FILE *fdj = NULL; + // This needs to be abstracted. if ( monitor->GetOptSaveJPEGs() & 1) { snprintf( filepath, sizeof(filepath), Event::capture_file_format, event_data->path, curr_frame_id ); } else if ( monitor->GetOptSaveJPEGs() & 2 ) { @@ -1269,10 +1270,75 @@ bool EventStream::sendFrame( int delta_us ) { } } else { + AVFormatContext *pFormatCtx = NULL; + snprintf( filepath, sizeof(filepath), "%s/%d-video.mp4", event_data->path, event_date->id ); + + // Open video file + if(avformat_open_input(&pFormatCtx, , NULL, 0, NULL)!=0) + return false; // Couldn't open file + } + +int i; +AVCodecContext *pCodecCtxOrig = NULL; +AVCodecContext *pCodecCtx = NULL; + +// Find the first video stream +videoStream=-1; +for(i=0; inb_streams; i++) + if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { + videoStream=i; + break; + } +if(videoStream==-1) + return -1; // Didn't find a video stream + +// Get a pointer to the codec context for the video stream +pCodecCtx=pFormatCtx->streams[videoStream]->codec; Fatal("JPEGS not saved.zms is not capable of streaming jpegs from mp4 yet"); return false; } +AVCodec *pCodec = NULL; + +// Find the decoder for the video stream +pCodec=avcodec_find_decoder(pCodecCtx->codec_id); +if(pCodec==NULL) { + fprintf(stderr, "Unsupported codec!\n"); + return -1; // Codec not found +} +// Copy context +pCodecCtx = avcodec_alloc_context3(pCodec); +if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) { + fprintf(stderr, "Couldn't copy codec context"); + return -1; // Error copying codec context +} +// Open codec +if(avcodec_open2(pCodecCtx, pCodec)<0) + return -1; // Could not open codec + +AVFrame *pFrame = NULL; + +// Allocate video frame +pFrame=av_frame_alloc(); + +// Allocate an AVFrame structure +pFrameRGB=av_frame_alloc(); +if(pFrameRGB==NULL) + return -1; + +uint8_t *buffer = NULL; +int numBytes; +// Determine required buffer size and allocate buffer +numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, + pCodecCtx->height); +buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); + +// Assign appropriate parts of buffer to image planes in pFrameRGB +// Note that pFrameRGB is an AVFrame, but AVFrame is a superset +// of AVPicture +avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, + pCodecCtx->width, pCodecCtx->height); + #if HAVE_LIBAVCODEC if ( type == STREAM_MPEG ) { Image image( filepath ); diff --git a/web/skins/classic/views/montagereview.php b/web/skins/classic/views/montagereview.php index 5d4e279ed..5a153dd9e 100644 --- a/web/skins/classic/views/montagereview.php +++ b/web/skins/classic/views/montagereview.php @@ -107,7 +107,7 @@ if ( !empty($_REQUEST['group']) ) { $row = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($_REQUEST['group']) ); $monitorsSql = "SELECT * FROM Monitors WHERE Function != 'None' AND find_in_set( Id, '".$row['MonitorIds']."' ) "; } else { - $monitorsSql = "SELECT * FROM Monitors WHERE 1>0"; + $monitorsSql = "SELECT * FROM Monitors WHERE Function != 'None'"; $group = ''; } @@ -125,8 +125,6 @@ $eventsSql = ' INNER JOIN Monitors AS M ON (E.MonitorId = M.Id) WHERE NOT isnull(E.Frames) AND NOT isnull(StartTime)'; - - // select E.Id,E.Name,UNIX_TIMESTAMP(E.StartTime) as StartTimeSecs,UNIX_TIMESTAMP(max(DATE_ADD(E.StartTime, Interval Delta+0.5 Second))) as CalcEndTimeSecs, E.Length,max(F.FrameId) as Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId // from Events as E // inner join Monitors as M on (E.MonitorId = M.Id)