Beispiel #1
0
 private static extern void avcodec_free_context(AVCodecContext **avctx);
/**
 * Open an output file and the required encoder.
 * Also set some basic encoder parameters.
 * Some of these parameters are based on the input file's parameters.
 * @param      filename              File to be opened
 * @param      input_codec_context   Codec context of input file
 * @param[out] output_format_context Format context of output file
 * @param[out] output_codec_context  Codec context of output file
 * @return Error code (0 if successful)
 */
    int open_output_file(string filename, AVCodecContext *input_codec_context,
                         AVFormatContext **output_format_context, AVCodecContext **output_codec_context)
    {
        AVCodecContext *avctx             = null;
        AVIOContext *   output_io_context = null;
        AVStream *      stream            = null;
        AVCodec *       output_codec      = null;
        int             error;

        /* Open the output file to write to it. */
        if ((error = avio_open(&output_io_context, filename,
                               AVIO_FLAG_WRITE)) < 0)
        {
            Console.WriteLine($"error: Could not open output file '{filename}' (error '{LibAVErrorToString(error)}')");
            return(error);
        }

        /* Create a new format context for the output container format. */
        if ((*output_format_context = avformat_alloc_context()) == null)
        {
            Console.WriteLine("error: Could not allocate output format context");
            return(AVERROR(ENOMEM));
        }

        /* Associate the output file (pointer) with the container format context. */
        (*output_format_context)->pb = output_io_context;

        /* Guess the desired container format based on the file extension. */
        if (((*output_format_context)->oformat = av_guess_format(null, filename, null)) == null)
        {
            Console.WriteLine("error: Could not find output file format");
            goto cleanup;
        }

        if (((*output_format_context)->url = av_strdup(filename)) == null)
        {
            Console.WriteLine("error: Could not allocate url.");
            error = AVERROR(ENOMEM);
            goto cleanup;
        }
        /* Find the encoder to be used by its name. */
        if ((output_codec = avcodec_find_encoder(AVCodecID.AV_CODEC_ID_VORBIS)) == null)
        {
            Console.WriteLine("error: Could not find a vorbis encoder.");
            goto cleanup;
        }
        /* Create a new audio stream in the output file container. */
        if ((stream = avformat_new_stream(*output_format_context, null)) == null)
        {
            Console.WriteLine("error: Could not create new stream");
            error = AVERROR(ENOMEM);
            goto cleanup;
        }
        avctx = avcodec_alloc_context3(output_codec);
        if (avctx == null)
        {
            Console.WriteLine("error: Could not allocate an encoding context");
            error = AVERROR(ENOMEM);
            goto cleanup;
        }

        /* Set the basic encoder parameters.
         * The input file's sample rate is used to avoid a sample rate conversion. */

        /* NOTE: These parameters are tailored for vorbis.
         * See https://ffmpeg.org/ffmpeg-codecs.html#libvorbis
         * Other codecs may need different parameters */
        avctx->channels       = 2;
        avctx->channel_layout = (ulong)av_get_default_channel_layout((int)avctx->channels);
        avctx->sample_rate    = input_codec_context->sample_rate;
        avctx->sample_fmt     = output_codec->sample_fmts[0];
        avctx->global_quality = 7;

        /* Set the sample rate for the container. */
        avctx->time_base.den = input_codec_context->sample_rate;
        avctx->time_base.num = 1;

        /* Some container formats (like MP4) require global headers to be present.
         * Mark the encoder so that it behaves accordingly. */
        if (((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER) != 0)
        {
            avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
        }

        /* Open the encoder for the audio stream to use it later. */
        if ((error = avcodec_open2(avctx, output_codec, null)) < 0)
        {
            Console.WriteLine($"error: Could not open output codec (error '{LibAVErrorToString(error)}')");
            goto cleanup;
        }

        error = avcodec_parameters_from_context(stream->codecpar, avctx);
        if (error < 0)
        {
            Console.WriteLine("error: Could not initialize stream parameters");
            goto cleanup;
        }

        /* Save the encoder context for easier access later. */
        *output_codec_context = avctx;
        return(0);

cleanup:
        avcodec_free_context(&avctx);
        avio_closep(&(*output_format_context)->pb);
        avformat_free_context(*output_format_context);
        *output_format_context = null;
        return(error < 0 ? error : AVERROR_EXIT);
    }
/**
 * Open an input file and the required decoder.
 * @param      filename             File to be opened
 * @param[out] input_format_context Format context of opened file
 * @param[out] input_codec_context  Codec context of opened file
 * @return Error code (0 if successful)
 */
    int open_input_file(string filename,
                        AVFormatContext **input_format_context,
                        AVCodecContext **input_codec_context)
    {
        AVCodecContext *avctx;
        AVCodec *       input_codec;
        int             error;

        /* Open the input file to read from it. */
        if ((error = avformat_open_input(input_format_context, filename, null,
                                         null)) < 0)
        {
            Console.WriteLine($"error: Could not open input file '{filename}' (error '{LibAVErrorToString(error)}')");
            *input_format_context = null;
            return(error);
        }
        /* Get information on the input file (number of streams etc.). */
        if ((error = avformat_find_stream_info(*input_format_context, null)) < 0)
        {
            Console.WriteLine($"error: Could not open find stream info (error '{LibAVErrorToString(error)}')");
            avformat_close_input(input_format_context);
            return(error);
        }
        /* Make sure that there is only one stream in the input file. */
        if ((*input_format_context)->nb_streams != 1)
        {
            Console.WriteLine($"error: Expected one audio input stream, but found {(*input_format_context)->nb_streams}");
            avformat_close_input(input_format_context);
            return(AVERROR_EXIT);
        }
        /* Find a decoder for the audio stream. */
        if ((input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id)) == null)
        {
            Console.WriteLine("error: Could not find input codec");
            avformat_close_input(input_format_context);
            return(AVERROR_EXIT);
        }
        /* Allocate a new decoding context. */
        avctx = avcodec_alloc_context3(input_codec);
        if (avctx == null)
        {
            Console.WriteLine("error: Could not allocate a decoding context");
            avformat_close_input(input_format_context);
            return(AVERROR(ENOMEM));
        }
        /* Initialize the stream parameters with demuxer information. */
        error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar);
        if (error < 0)
        {
            Console.WriteLine($"error: Could not avcodec_parameters_to_context (error '{LibAVErrorToString(error)}')");
            avformat_close_input(input_format_context);
            avcodec_free_context(&avctx);
            return(error);
        }
        /* Open the decoder for the audio stream to use it later. */
        if ((error = avcodec_open2(avctx, input_codec, null)) < 0)
        {
            Console.WriteLine($"error: Could not open input codec (error '{LibAVErrorToString(error)}')");
            avcodec_free_context(&avctx);
            avformat_close_input(input_format_context);
            return(error);
        }
        /* Save the decoder context for easier access later. */
        *input_codec_context = avctx;
        return(0);
    }
Beispiel #4
0
 public static extern void avcodec_free_context(AVCodecContext **avctx);