예제 #1
0
        /// <summary>
        /// Initializes the output context and writes the file header.
        /// </summary>
        /// <param name="inputContext">The input context</param>
        private void Initialize(AVFormatContext *inputContext)
        {
            var result = 0;

            try
            {
                var outputFilePath = GuessOutputFilePath(inputContext);
                AVFormatContext *outputContext;
                result = ffmpeg.avformat_alloc_output_context2(&outputContext, null, null, outputFilePath);

                if (result < 0)
                {
                    throw new InvalidOperationException("Unable to allocate output context");
                }

                OutputContext = outputContext;
                StreamMappings.Clear();

                foreach (var streamIndex in Media.MediaInfo.Streams.Keys)
                {
                    var codecParams = inputContext->streams[streamIndex]->codecpar;
                    var stream      = ffmpeg.avformat_new_stream(OutputContext, null);

                    if (stream == null)
                    {
                        result = -ffmpeg.ENOMEM;
                        throw new InvalidOperationException($"Unable to create output stream for stream index {streamIndex}");
                    }

                    result = ffmpeg.avcodec_parameters_copy(stream->codecpar, codecParams);

                    if (result < 0)
                    {
                        throw new InvalidOperationException($"Unable to copy codec parameters to stream index {streamIndex}");
                    }

                    stream->codecpar->codec_tag = 0;
                    StreamMappings[streamIndex] = stream->index;
                }

                result = ffmpeg.avio_open(&outputContext->pb, outputFilePath, ffmpeg.AVIO_FLAG_WRITE);
                if (result < 0)
                {
                    throw new InvalidOperationException($"Could not open output file '{outputFilePath}'");
                }

                result = ffmpeg.avformat_write_header(OutputContext, null);
                if (result < 0)
                {
                    throw new InvalidOperationException($"Could not write header to '{outputFilePath}'");
                }

                HasInitialized = true;
            }
            catch (Exception ex)
            {
                Media.LogError(nameof(TransportStreamRecorder), $"Error Code {result}: {ex.Message}");
                Release();
            }
        }