/* Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) Copyright (C) 2013 Matthias P. Braendli http://mpb.li Base class for buffered inputs */ /* This file is part of CRC-DabMux. CRC-DabMux 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. CRC-DabMux 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 CRC-DabMux. If not, see . */ #include "inputs/Input.h" #include "TcpLog.h" #include #include #include #include #include #include #include #ifndef _WIN32 # define O_BINARY 0 #endif extern TcpLog etiLog; int InputBuffered::ReadFrame(void* buffer, int size) { int retval = 0; bool rc; switch (m_bufferstate) { case PREBUFFERING: rc = FillBuffer(); if (rc) { m_prebuffer_count--; } if (m_prebuffer_count == 0) { etiLog.print(TcpLog::NOTICE, "input %s: pre-buffering complete\n", GetName()); m_bufferstate = RUNNING; } break; case RUNNING: rc = FillBuffer(); if (m_buffer.empty()) { etiLog.print(TcpLog::WARNING, "input %s input empty, re-enabling pre-buffering\n", GetName()); // reinitialise prebuffering m_bufferstate = PREBUFFERING; m_prebuffer_count = m_prebuffer_stages; } else { std::vector &buffer_head = m_buffer.front(); memcpy(buffer, &buffer_head.front(), size); etiLog.print(TcpLog::NOTICE, "input %s got %d, %d\n", GetName(), rc, m_buffer.size()); m_buffer.pop_front(); retval = size; } break; } // If we haven't filled buffer, return a nulled one if (retval == 0) { memset(buffer, 0, size); retval = size; } return retval; } // This implemenation of FillBuffer assumes that // input and output frames have same size. // That's not the case with DAB+ superframes bool InputBuffered::FillBuffer() { if (m_buffer.size() > m_overfull_thresh) { etiLog.print(TcpLog::WARNING, "input %s buffer full, dropping frame !\n", GetName()); // drop the surplus int num_frames_to_drop = m_buffer.size() - m_overfull_thresh; while (num_frames_to_drop--) m_buffer.pop_front(); return true; } else { // copy the input frame into the frame_buffer one to one std::vector frame(m_source_size); int rc = ReadSource(&frame.front(), m_source_size); if (rc == m_source_size) { m_buffer.push_back(frame); return true; } else { return false; } } }