/* * Copyright 2019 Arcus Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.iris.video.recording.server.dao; import java.io.IOException; import java.nio.ByteBuffer; import java.util.UUID; import org.apache.commons.io.output.CountingOutputStream; import com.iris.media.H264Factory; import com.iris.media.IrisRtspSdp; import com.iris.video.VideoSessionRegistry; import com.iris.video.cql.VideoRecordingManager; import com.iris.video.recording.RecordingEventPublisher; import com.iris.video.recording.RecordingSession; import com.iris.video.recording.server.MpegTsH264Adapter; import com.iris.video.storage.VideoStorageSession; import io.netty.channel.ChannelHandlerContext; public class VideoRecordingSession extends RecordingSession implements H264Factory.VideoSession { private final MpegTsH264Adapter adapter; private final VideoStorageSession storage; private final CountingOutputStream mpegts; VideoRecordingSession( VideoSessionRegistry registry, ChannelHandlerContext ctx, VideoRecordingManager dao, RecordingEventPublisher eventPublisher, VideoStorageSession storage, double precapture, boolean stream, CountingOutputStream mpegts, double flushTimeInS ) throws IOException { super(registry, ctx, storage, dao, eventPublisher, stream, precapture, true); this.adapter = new Adapter(mpegts, flushTimeInS, storage.getRecordingId()); this.storage = storage; this.mpegts = mpegts; } @Override public UUID getRecordingId() { return storage.getRecordingId(); } @Override public void h264(ByteBuffer data, long ts, int naluHeader) throws IOException { adapter.h264(data, ts, naluHeader); } @Override public void startH264(ByteBuffer data, long ts, int naluHeader) throws IOException { adapter.startH264(data, ts, naluHeader); } @Override public void appendH264(ByteBuffer data, long ts, int naluHeader) throws IOException { adapter.appendH264(data, ts, naluHeader); } @Override public void finishH264(ByteBuffer data, long ts, int naluHeader) throws IOException { adapter.finishH264(data, ts, naluHeader); } @Override protected void onSdp(IrisRtspSdp sdp) { try { adapter.setSdp(sdp); } catch(IOException ioe) { throw new RuntimeException(ioe); } } @Override protected void doClose() { try { adapter.close(); } catch(IOException ioe) { throw new RuntimeException(ioe); } } @Override protected double durationInSeconds() { return adapter.getDurationInSeconds(); } @Override protected long byteCount() { return mpegts.getByteCount(); } private class Adapter extends MpegTsH264Adapter { Adapter(CountingOutputStream mpegts, double flushTimeInS, UUID recId) throws IOException { super(mpegts, flushTimeInS, recId); } @Override protected void handleFrameData(long tsIn90KHz, long lengthIn90KHz, long frameByteOffset, long frameByteSize, boolean isIFrame) throws Exception { } @Override protected void handleIFrameData(long tsIn90KHz, long lengthTillNextIn90KHz, long frameByteOffset, long frameByteSize) throws Exception { onIFrame(tsIn90KHz, frameByteOffset, frameByteSize); } } }