Пример #1
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;
    }
}
Пример #2
0
    bool VideoEncoder::init(const Desc& desc)
    {
        // Register the codecs
        av_register_all();

        // create the output context
        avformat_alloc_output_context2(&mpOutputContext, nullptr, nullptr, mFilename.c_str());
        if(mpOutputContext == nullptr)
        {
            // The sample tries again, while explicitly requesting mpeg format. I chose not to do it, since it might lead to a container with a wrong extension
            return error(mFilename, "File output format not recognized. Make sure you use a known file extension (avi/mpeg/mp4)");
        }

        // Get the output format of the container
        AVOutputFormat* pOutputFormat = mpOutputContext->oformat;
        assert((pOutputFormat->flags & AVFMT_NOFILE) == 0); // Problem. We want a file.

        // create the video codec
        AVCodec* pVideoCodec;
        mpOutputStream = createVideoStream(mpOutputContext, desc.fps, getCodecID(desc.codec), mFilename, pVideoCodec);
        if(mpOutputStream == nullptr)
        {
            return false;
        }

        mpCodecContext = createCodecContext(mpOutputContext, desc.width, desc.height, desc.fps, desc.bitrateMbps, desc.gopSize, getCodecID(desc.codec), pVideoCodec);
        if(mpCodecContext == nullptr)
        {
            return false;
        }

        // Open the video stream
        if(openVideo(pVideoCodec, mpCodecContext, mpFrame, mFilename) == false)
        {
            return false;
        }

        // copy the stream parameters to the muxer
        if(avcodec_parameters_from_context(mpOutputStream->codecpar, mpCodecContext) < 0)
        {
            return error(desc.filename, "Could not copy the stream parameters\n");
        }

        av_dump_format(mpOutputContext, 0, mFilename.c_str(), 1);

        // Open the output file
        assert((pOutputFormat->flags & AVFMT_NOFILE) == 0); // No output file required. Not sure if/when this happens.
        if(avio_open(&mpOutputContext->pb, mFilename.c_str(), AVIO_FLAG_WRITE) < 0)
        {
            return error(mFilename, "Can't open output file.");
        }

        // Write the stream header
        if(avformat_write_header(mpOutputContext, nullptr) < 0)
        {
            return error(mFilename, "Can't write file header.");
        }

        mFormat = desc.format;
        mRowPitch = getFormatBytesPerBlock(desc.format) * desc.width;
        if(desc.flipY)
        {
            mpFlippedImage = new uint8_t[desc.height * mRowPitch];
        }

        mpSwsContext = sws_getContext(desc.width, desc.height, getPictureFormatFromFalcorFormat(desc.format), desc.width, desc.height, mpCodecContext->pix_fmt, SWS_POINT, nullptr, nullptr, nullptr);
        if(mpSwsContext == nullptr)
        {
            return error(mFilename, "Failed to allocate SWScale context");
        }
        return true;
    }