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); }
public static extern void avcodec_free_context(AVCodecContext **avctx);