diff options
| author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2013-12-21 17:46:41 +0100 | 
|---|---|---|
| committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2013-12-24 18:09:26 +0100 | 
| commit | 211d6a06ab5a286c623d2dce901115dec316a31d (patch) | |
| tree | 40e60dc7b47aeea21292dec2748d4fc72663f5d0 /src/inputs/InputBuffered.cpp | |
| parent | abec4838d2536812a4fe382334a1c9f500f7728b (diff) | |
| download | dabmux-211d6a06ab5a286c623d2dce901115dec316a31d.tar.gz dabmux-211d6a06ab5a286c623d2dce901115dec316a31d.tar.bz2 dabmux-211d6a06ab5a286c623d2dce901115dec316a31d.zip | |
Add InputBuffered
Diffstat (limited to 'src/inputs/InputBuffered.cpp')
| -rw-r--r-- | src/inputs/InputBuffered.cpp | 131 | 
1 files changed, 131 insertions, 0 deletions
| diff --git a/src/inputs/InputBuffered.cpp b/src/inputs/InputBuffered.cpp new file mode 100644 index 0000000..9eea2a7 --- /dev/null +++ b/src/inputs/InputBuffered.cpp @@ -0,0 +1,131 @@ +/* +   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 <http://www.gnu.org/licenses/>. +   */ + +#include "inputs/Input.h" + + +#include "TcpLog.h" + +#include <string> +#include <cstring> +#include <cstdlib> +#include <cstdio> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +#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<char> &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<char> 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; +        } +    } +} + | 
