Esempio n. 1
0
void Parser::InitResampler()
{
    swr_ctx = swr_alloc_set_opts(NULL,
                                 av_get_default_channel_layout(cdc_ctx_out->channels),
                                 cdc_ctx_out->sample_fmt,
                                 cdc_ctx_out->sample_rate,
                                 channelLayoutIn,
                                 (AVSampleFormat)sampleFormatIn,
                                 sampleRateIn,
                                 0,0);

    if(!swr_ctx)
        throw ContextCreatorException() << errno_code(MIR_ERR_ALLOC_SWR_CONTEXT);

    // set options
    av_opt_set_int(swr_ctx, "in_channel_layout",    channelLayoutIn, 0);
    av_opt_set_int(swr_ctx, "in_sample_rate",       sampleRateIn, 0);
    av_opt_set_int(swr_ctx, "in_bit_rate",          bitRateIn, 0);
    av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", (AVSampleFormat)sampleFormatIn, 0);

    av_opt_set_int(swr_ctx, "out_channel_layout",    cdc_ctx_out->channel_layout, 0);
    av_opt_set_int(swr_ctx, "out_sample_rate",       cdc_ctx_out->sample_rate, 0);
    av_opt_set_int(swr_ctx, "out_bit_rate",          cdc_ctx_out->bit_rate, 0);
    av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", cdc_ctx_out->sample_fmt, 0);

    if (swr_init(swr_ctx) < 0)
        throw ContextCreatorException() << errno_code(MIR_ERR_INIT_SWR_CONTEXT);
}
Esempio n. 2
0
void Parser::setStream()
{
    int error = 0;

    AVCodec *codec = NULL;
    AVCodecID codecID = getCodecID();

    codec = avcodec_find_encoder(codecID);
    fmt_ctx_out->audio_codec = codec;
    stm_out = avformat_new_stream(fmt_ctx_out, codec);

    if (!stm_out)
        throw StreamException() << errno_code(MIR_ERR_OPEN_STREAM_1);

    cdc_ctx_out = stm_out->codec;
    cdc_ctx_out->codec = codec;
    cdc_ctx_out->codec_id = codecID;
    cdc_ctx_out->codec_type = AVMEDIA_TYPE_AUDIO;

    cdc_ctx_out->sample_fmt = getSampleFormat(codecID);

    if (!isVBR)
        cdc_ctx_out->bit_rate = bitRate;
    else
    {
        cdc_ctx_out->rc_max_rate = 0;
        cdc_ctx_out->rc_min_rate = 0;
        cdc_ctx_out->bit_rate_tolerance = bitRate;
        cdc_ctx_out->bit_rate = bitRate;
    }

    cdc_ctx_out->sample_rate = sampleRate;
    cdc_ctx_out->channels = nbChannel;
    cdc_ctx_out->channel_layout = av_get_default_channel_layout(nbChannel);

    error = avcodec_open2(cdc_ctx_out, codec, NULL);

    if (error < 0)
        throw StreamException() << errno_code(MIR_ERR_OPEN_STREAM_2);

    if (codecID == AV_CODEC_ID_PCM_S16LE || codecID == AV_CODEC_ID_MP3)
        cdc_ctx_out->frame_size = av_rescale_rnd(nbSamplesIn,
                                                 cdc_ctx_out->sample_rate, sampleRateIn, AV_ROUND_UP);
    else if (codecID == AV_CODEC_ID_AAC)
    {
        cdc_ctx_out->profile = FF_PROFILE_AAC_LOW;
        cdc_ctx_out->frame_size = 1024;

        // some formats want stream headers to be separate
        if(fmt_ctx_out->oformat->flags & AVFMT_GLOBALHEADER)
            cdc_ctx_out->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

    cdc_out = codec;

    if (audioFormat == AUDIOFORMAT::arq)
    {
        fmt_ctx_out->oformat->flags |= AVFMT_ALLOW_FLUSH;
    }
}
Esempio n. 3
0
void Parser::setBuffer(string arqName, vector<vector<vector<uint8_t>>> value,
                       int nbSamplesIn, int sampleFormatIn, int sampleRateIn,
                       uint64_t channelLayoutIn, int nbChannelsIn)
{
    int error;

    this->fileName = arqName;
    this->bufFrames = value;

    this->nbSamplesIn = nbSamplesIn;
    this->sampleFormatIn = sampleFormatIn;
    this->sampleRateIn = sampleRateIn;
    this->channelLayoutIn = channelLayoutIn;
    this->nbChannelsIn = nbChannelsIn;

    if (swr_ctx)
        swr_free(&swr_ctx);

    InitResampler();

    if (audioFormat == AUDIOFORMAT::arq)
    {
        AVIOContext **io_ctx = &fmt_ctx_out->pb;

        if (*io_ctx)
            avio_close(*io_ctx);

        error = avio_open(io_ctx, fileName.c_str(), AVIO_FLAG_WRITE);
        if (error < 0)
        {
            char error_buffer[255];
            av_strerror(error, error_buffer, sizeof(error_buffer));
            objLog->mr_printf(MR_LOG_ERROR, idRadio, "Error: %s - %s\n", fileName.c_str(), error_buffer);
            throw ConvertException() << errno_code(MIR_ERR_OPEN_OUTPUT_FILE);
        }

av_dump_format(fmt_ctx_out, 0, fileName.c_str(), 1);

        error = avformat_write_header(fmt_ctx_out, NULL);

        if (error < 0)
        {
            char error_buffer[255];
            av_strerror(error, error_buffer, sizeof(error_buffer));
            objLog->mr_printf(MR_LOG_ERROR, idRadio, "Error: %s - %s\n", fileName.c_str(), error_buffer);
            throw StreamException() << errno_code(MIR_ERR_OPEN_STREAM_3);
        }
    }
}
Esempio n. 4
0
/** Create an `error_code` from `errno` (and clear it) */
inline
std::error_code errno_code()
{
  int errnum = errno;
  errno = 0;
  return errno_code(errnum);
}
Esempio n. 5
0
void Parser::createFrames()
{

    // Frame In
    frame_in = NULL;
    try
    {
        frame_in = av_frame_alloc();
        if (frame_in == NULL)
            throw ResampleException() << errno_code(MIR_ERR_FRAME_ALLOC_3);
    }
    catch(ResampleException& err)
    {
        throw;
    }

    // Frame Out
    frame_out = NULL;
    try
    {
        frame_out = av_frame_alloc();
        if (frame_out == NULL)
            throw ResampleException() << errno_code(MIR_ERR_FRAME_ALLOC_4);
    }
    catch(ResampleException& err)
    {
        throw;
    }

    try
    {
        frame_out->nb_samples = cdc_ctx_out->frame_size;
        frame_out->format = cdc_ctx_out->sample_fmt;
        frame_out->sample_rate = sampleRate;
        frame_out->channel_layout = av_get_default_channel_layout(nbChannel);

        if (av_frame_get_buffer(frame_out, 1) < 0)
            throw ResampleException() << errno_code(MIR_ERR_BUFFER_ALLOC_OUT);
    }
    catch(ResampleException& err)
    {
        throw;
    }
}
Esempio n. 6
0
void Parser::CreateContext()
{
    int error = 0;

    error = avformat_alloc_output_context2(&fmt_ctx_out, NULL,
                        audioFormatList[audioFormat].c_str(), fileName.c_str());

    if (error < 0)
        throw ContextCreatorException() << errno_code(MIR_ERR_BADALLOC_CONTEXT);

    if(audioFormat == AUDIOFORMAT::raw)
        fmt_ctx_out->oformat->flags |= AVFMT_NOFILE;
}
Esempio n. 7
0
void Parser::Resample()
{
    int got_frame;

    int idxFrame;
    int idxBuff;

    bool isExtAAC = false;
    if (cdc_ctx_in->codec_id == AV_CODEC_ID_AAC)
        isExtAAC = sampleFormatIn == (int)AVSampleFormat::AV_SAMPLE_FMT_FLTP;

    try
    {
        try
        {
            if (nbSamplesIn > 0)
            {
                if (isExtAAC)
                {
                    frame_in->nb_samples = 2048;
                    frame_in->channels = cdc_ctx_in->channels;
                }
                else
                {
                    frame_in->nb_samples = nbSamplesIn;
                    frame_in->channels = nbChannelsIn;
                }
                frame_in->format = sampleFormatIn;
                frame_in->sample_rate = sampleRateIn;
                frame_in->channel_layout = channelLayoutIn;

                if (av_frame_get_buffer(frame_in, 1) < 0)
                    throw ResampleException() << errno_code(MIR_ERR_BUFFER_ALLOC_IN);

                if (isExtAAC)
                    frame_in->nb_samples = nbSamplesIn;
            }
            else
                throw ResampleException() << errno_code(MIR_ERR_BUFFER_ALLOC_NULL);
        }
        catch(SignalException& err)
        {
            throw ExceptionClass("parser", "Resample", "Segmentation error");
        }
        catch(ResampleException& err)
        {
            throw;
        }

/**
        try
        {
            frame_out->nb_samples = cdc_ctx_out->frame_size;
            frame_out->format = cdc_ctx_out->sample_fmt;
            frame_out->sample_rate = sampleRate;
            frame_out->channel_layout = av_get_default_channel_layout(nbChannel);

            if (av_frame_get_buffer(frame_out, 1) < 0)
                throw ResampleException() << errno_code(MIR_ERR_BUFFER_ALLOC_OUT);
        }
        catch(ResampleException& err)
        {
            throw;
        }
/**/

        for (idxFrame = 0; idxFrame < (int)this->bufFrames.size(); idxFrame++)
        {
            try
            {
                vetAux = bufFrames[idxFrame];

                //!< carregando dados no frame de entrada
                try
                {
                    nbBuffers = av_sample_fmt_is_planar((AVSampleFormat)frame_in->format) ? frame_in->channels : 1;
                    if ((int)vetAux.size() != nbBuffers)
                        throw FifoException() << errno_code(MIR_ERR_FIFO_DATA1);

                    for (idxBuff = 0; idxBuff < (int)vetAux.size(); idxBuff++)
                    {
                        if ((int)vetAux[idxBuff].size() > frame_in->linesize[0])
                            throw FifoException() << errno_code(MIR_ERR_FIFO_DATA2);

                        try
                        {
                            memcpy(frame_in->data[idxBuff], vetAux[idxBuff].data(), frame_in->linesize[0]);
                        }
                        catch(SignalException& err)
                        {
                            throw ExceptionClass("parser", "Resample", err.what());
                        }
                    }

                    for (int idxBuff = 0; idxBuff < (int)vetAux.size(); idxBuff++)
                        if (vetAux[idxBuff].size() > 0)
                            vetAux[idxBuff].clear();
                    if (vetAux.size() > 0)
                        vetAux.clear();
                }
                catch (ExceptionClass& err)
                {
                    throw;
                }
                catch (FifoException& err)
                {
                    throw;
                }
                catch (...)
                {
                    throw FifoException() << errno_code(MIR_ERR_FIFO_DATA3);
                }

                //!< convertendo dados
                if (swr_convert(swr_ctx, (uint8_t**)&frame_out->data, frame_out->nb_samples,
                                 (const uint8_t**)&frame_in->data, frame_in->nb_samples) >= 0)
                {
                    got_frame = 0;
                    av_init_packet(&pkt_out);
                    pkt_out.data = NULL;
                    pkt_out.size = 0;

                    if (avcodec_encode_audio2(cdc_ctx_out, &pkt_out, frame_out, &got_frame) >= 0)
                        EndResample();
                    else
                    {
                        av_free_packet(&pkt_out);
                        throw ResampleException() << errno_code(MIR_ERR_ENCODE);
                    }

                    av_free_packet(&pkt_out);
                }
                else
                    throw ResampleException() << errno_code(MIR_ERR_RESAMPLE);
            }
            catch(ExceptionClass& err)
            {
                objLog->mr_printf(MR_LOG_ERROR, idRadio, "%s\n", err.what());
            }
            catch(FifoException& err)
            {
                char aux[200];

                switch(*boost::get_error_info<errno_code>(err))
                {
                    case MIR_ERR_FIFO_DATA1:
                        sprintf(aux, "Error (%d) : vetAux.size = %d    nbBuffers = %d\n", MIR_ERR_FIFO_DATA1,
                                (int)vetAux.size(), nbBuffers);
                        break;
                    case MIR_ERR_FIFO_DATA2:
/**
                        sprintf(aux, "Error (%d) : vetAux[idxBuff].size = %d    linesize = %d\n", MIR_ERR_FIFO_DATA2,
                                (int)vetAux[idxBuff].size(), frame_in->linesize[0]);
/**/
                        sprintf(aux, "Error (%d) : vetAux[idxBuff].size = %d    linesize = %d    channels = %d"
                                "    channelsLayout = %d    format = %d    nb_samples = %d\n",
                                MIR_ERR_FIFO_DATA2,
                                (int)vetAux[idxBuff].size(),
                                frame_in->linesize[0],
                                frame_in->channels,
                                frame_in->channel_layout,
                                frame_in->format,
                                frame_in->nb_samples);
/**/
                        break;
                    case MIR_ERR_FIFO_DATA3:
                        sprintf(aux, "Error (%d) : General Frame allocation error\n", MIR_ERR_FIFO_DATA3);
                        break;
                    default :
                        break;
                }

                objLog->mr_printf(MR_LOG_ERROR, idRadio, aux);

                for (int idxBuff = 0; idxBuff < (int)vetAux.size(); idxBuff++)
                    if (vetAux[idxBuff].size() > 0)
                        vetAux[idxBuff].clear();
                if (vetAux.size() > 0)
                    vetAux.clear();
            }
            catch(ResampleException& err)
            {
                objLog->mr_printf(MR_LOG_ERROR, idRadio, "Frame Resample Exception : %d\n", *boost::get_error_info<errno_code>(err));
            }
        }

        av_frame_unref(frame_in);
//        av_frame_unref(frame_out);

        for (int idxFrame = 0; idxFrame < (int)this->bufFrames.size(); idxFrame++)
        {
            for (int idxBuff = 0; idxBuff < (int)bufFrames[idxFrame].size(); idxBuff++)
                if (bufFrames[idxFrame][idxBuff].size() > 0)
                    bufFrames[idxFrame][idxBuff].clear();
            if (bufFrames[idxFrame].size() > 0)
                bufFrames[idxFrame].clear();
        }
        if (bufFrames.size() > 0)
            bufFrames.clear();
    }
    catch (SignalException& err)
    {
        if (frame_in)
        {
            av_frame_free(&frame_in);
            frame_in = NULL;
        }

        if (frame_out)
        {
            av_frame_free(&frame_out);
            frame_out = NULL;
        }

        for (int idxBuff = 0; idxBuff < (int)vetAux.size(); idxBuff++)
            if (vetAux[idxBuff].size() > 0)
                vetAux[idxBuff].clear();
        if (vetAux.size() > 0)
            vetAux.clear();

        for (int idxFrame = 0; idxFrame < (int)this->bufFrames.size(); idxFrame++)
        {
            for (int idxBuff = 0; idxBuff < (int)bufFrames[idxFrame].size(); idxBuff++)
                if (bufFrames[idxFrame][idxBuff].size() > 0)
                    bufFrames[idxFrame][idxBuff].clear();
            if (bufFrames[idxFrame].size() > 0)
                bufFrames[idxFrame].clear();
        }
        if (bufFrames.size() > 0)
            bufFrames.clear();

        throw;
    }
    catch(...)
    {
        if (frame_in)
        {
            av_frame_free(&frame_in);
            frame_in = NULL;
        }

        if (frame_out)
        {
            av_frame_free(&frame_out);
            frame_out = NULL;
        }

        for (int idxBuff = 0; idxBuff < (int)vetAux.size(); idxBuff++)
            if (vetAux[idxBuff].size() > 0)
                vetAux[idxBuff].clear();
        if (vetAux.size() > 0)
            vetAux.clear();

        for (int idxFrame = 0; idxFrame < (int)this->bufFrames.size(); idxFrame++)
        {
            for (int idxBuff = 0; idxBuff < (int)bufFrames[idxFrame].size(); idxBuff++)
                if (bufFrames[idxFrame][idxBuff].size() > 0)
                    bufFrames[idxFrame][idxBuff].clear();
            if (bufFrames[idxFrame].size() > 0)
                bufFrames[idxFrame].clear();
        }
        if (bufFrames.size() > 0)
            bufFrames.clear();

        throw;
    }
}
Esempio n. 8
0
inline
std::system_error errno_error(const char* what)
{
  return std::system_error(errno_code(), what);
}
Esempio n. 9
0
/** Create a `system_code` from `errno` (and clear it) */
inline
std::system_error errno_error()
{
  return std::system_error(errno_code());
}
Esempio n. 10
0
inline
std::system_error errno_error(int errnum, const char* what)
{
  return std::system_error(errno_code(errnum), what);
}
Esempio n. 11
0
/** Create a `system_error` from an `errno` value
 *
 *  This is expected to to whatever is right to create a
 *  `system_error` from a given `errno` value.
 */
inline
std::system_error errno_error(int errnum)
{
  return std::system_error(errno_code(errnum));
}