Example #1
0
        static bool EncodeH264Stream(Options opt, Transcoder transcoder)
        {
            bool success = false;

            try
            {
                using (var file = System.IO.File.OpenRead(opt.InputFile))
                {
                    int videoBufferSize = MediaSample.VideoBufferSizeInBytes(opt.Width, opt.Height, opt.Color.Id);

                    if (videoBufferSize <= 0)
                    {
                        return(false);
                    }

                    MediaSample mediaSample = new MediaSample();
                    MediaBuffer mediaBuffer = new MediaBuffer(videoBufferSize);
                    mediaSample.Buffer = mediaBuffer;

                    int readBytes;

                    while (true)
                    {
                        mediaBuffer.SetData(0, videoBufferSize);
                        readBytes = file.Read(mediaBuffer.Start, 0, mediaBuffer.DataSize);
                        if (readBytes == videoBufferSize)
                        {
                            mediaBuffer.SetData(0, readBytes);

                            if (!transcoder.Push(0, mediaSample))
                            {
                                PrintStatus("Transcoder push", transcoder.Error);
                                success = false;
                                break;
                            }

                            success = true;
                        }
                        else
                        {
                            if (!transcoder.Flush())
                            {
                                success = false;
                            }

                            PrintStatus("Transcoder flush", transcoder.Error);

                            break;
                        }
                    }
                }
            }
            catch (System.IO.DirectoryNotFoundException dnfe)
            {
                Console.WriteLine(dnfe);
                success = false;
            }

            return(success);
        }
Example #2
0
        static void PrintNalus(MediaBuffer buffer)
        {
            // This parsing code assumes that MediaBuffer contains
            // a single Access Unit of one or more complete NAL Units
            while (buffer.DataSize > 1)
            {
                int dataOffset = buffer.DataOffset;
                int dataSize   = buffer.DataSize;

                // is this a NALU with a 3 byte start code prefix
                if (dataSize >= 3 &&
                    0x00 == buffer.Start[dataOffset + 0] &&
                    0x00 == buffer.Start[dataOffset + 1] &&
                    0x01 == buffer.Start[dataOffset + 2])
                {
                    PrintNaluHeader(buffer.Start[dataOffset + 3]);

                    // advance in the buffer
                    buffer.SetData(dataOffset + 3, dataSize - 3);
                }
                // OR is this a NALU with a 4 byte start code prefix
                else if (dataSize >= 4 &&
                         0x00 == buffer.Start[dataOffset + 0] &&
                         0x00 == buffer.Start[dataOffset + 1] &&
                         0x00 == buffer.Start[dataOffset + 2] &&
                         0x01 == buffer.Start[dataOffset + 3])
                {
                    PrintNaluHeader(buffer.Start[dataOffset + 4]);

                    // advance in the buffer
                    buffer.SetData(dataOffset + 4, dataSize - 4);
                }
                else
                {
                    // advance in the buffer
                    buffer.SetData(dataOffset + 1, dataSize - 1);
                }

                // NOTE: Some NALUs may have a trailing zero byte. The `while`
                // condition `buffer->dataSize() > 1` will effectively
                // skip the trailing zero byte.
            }
        }
Example #3
0
        public bool NextAudioBuffer(byte[] buffer, ref int length)
        {
            if (_cancellationPending)
            {
                length = 0;
                return(false);
            }

            lock (_csAVQueue)
            {
                int bytesWritten = 0;

                while ((_audioQueue.Count > 0) && (bytesWritten < buffer.Length))
                {
                    MediaSample mediaSample = _audioQueue.First.Value;

                    if (_unmanaged)
                    {
                        UnmanagedMediaBuffer mediaBuffer = mediaSample.UnmanagedBuffer;

                        int chunk = Math.Min(mediaBuffer.DataSize, buffer.Length - bytesWritten);
                        Marshal.Copy(mediaBuffer.DataPtr, buffer, bytesWritten, chunk);

                        bytesWritten += chunk;
                        mediaBuffer.Remove(chunk);

                        if (mediaBuffer.DataSize == 0)
                        {
                            mediaBuffer.Release();
                            _audioQueue.RemoveFirst();
                        }
                    }
                    else
                    {
                        MediaBuffer mediaBuffer = mediaSample.Buffer;

                        int chunk = Math.Min(mediaBuffer.DataSize, buffer.Length - bytesWritten);
                        Array.Copy(mediaBuffer.Start, mediaBuffer.DataOffset, buffer, bytesWritten, chunk);

                        bytesWritten += chunk;

                        {
                            int newDataOffset = mediaBuffer.DataOffset + chunk;
                            int newDataSize   = mediaBuffer.DataSize - chunk;
                            if (0 == newDataSize)
                            {
                                newDataOffset = 0;
                            }

                            mediaBuffer.SetData(newDataOffset, newDataSize);
                        }

                        if (mediaBuffer.DataSize == 0)
                        {
                            _audioQueue.RemoveFirst();
                        }
                    }
                }

                length = bytesWritten;
            }

            return(true);
        }
Example #4
0
        static bool SplitFile(string inputFile)
        {
            string       outputFileExt     = ".mpg";
            string       encodingPreset    = Preset.Video.DVD.NTSC_4x3_PCM;
            const double splitPartDuration = 10;     // seconds

            int audioStreamIndex = -1;
            int videoStreamIndex = -1;

            int audioFrameSize  = 0;
            int audioSampleRate = 0;

            using (var transcoder1 = new Transcoder())
            {
                // In order to use the OEM release for testing (without a valid license) the transcoder demo mode must be enabled.
                transcoder1.AllowDemoMode = true;

                using (var inputInfo = new MediaInfo())
                {
                    inputInfo.Inputs[0].File = inputFile;
                    if (!inputInfo.Open())
                    {
                        PrintError("Open MediaInfo", inputInfo.Error);
                        return(false);
                    }

                    // Configure transcoder1 input and output
                    var inputSocket = MediaSocket.FromMediaInfo(inputInfo);
                    transcoder1.Inputs.Add(inputSocket);

                    for (int i = 0; i < inputSocket.Pins.Count; i++)
                    {
                        StreamInfo inputStreamInfo = inputSocket.Pins[i].StreamInfo;

                        if ((inputStreamInfo.MediaType == MediaType.Video) && videoStreamIndex < 0)
                        {
                            var streamInfo = new VideoStreamInfo();

                            VideoStreamInfo inputVideoStreamInfo = inputStreamInfo as VideoStreamInfo;

                            streamInfo.ColorFormat = ColorFormat.YUV420;
                            streamInfo.StreamType  = StreamType.UncompressedVideo;
                            streamInfo.ScanType    = inputVideoStreamInfo.ScanType;

                            streamInfo.FrameWidth         = inputVideoStreamInfo.FrameWidth;
                            streamInfo.FrameHeight        = inputVideoStreamInfo.FrameHeight;
                            streamInfo.DisplayRatioWidth  = inputVideoStreamInfo.DisplayRatioWidth;
                            streamInfo.DisplayRatioHeight = inputVideoStreamInfo.DisplayRatioHeight;

                            var outputPin = new MediaPin();
                            outputPin.StreamInfo = streamInfo;

                            var outputSocket = new MediaSocket();
                            outputSocket.Pins.Add(outputPin);
                            outputSocket.StreamType = streamInfo.StreamType;

                            videoStreamIndex = transcoder1.Outputs.Count;
                            transcoder1.Outputs.Add(outputSocket);
                        }

                        if ((inputStreamInfo.MediaType == MediaType.Audio) && audioStreamIndex < 0)
                        {
                            var streamInfo = new AudioStreamInfo();

                            AudioStreamInfo inputAudioStreamInfo = inputStreamInfo as AudioStreamInfo;

                            streamInfo.StreamType = StreamType.LPCM;

                            streamInfo.PcmFlags      = inputAudioStreamInfo.PcmFlags;
                            streamInfo.Channels      = inputAudioStreamInfo.Channels;
                            streamInfo.SampleRate    = inputAudioStreamInfo.SampleRate;
                            streamInfo.BitsPerSample = inputAudioStreamInfo.BitsPerSample;

                            var outputPin = new MediaPin();
                            outputPin.StreamInfo = streamInfo;

                            var outputSocket = new MediaSocket();
                            outputSocket.Pins.Add(outputPin);
                            outputSocket.StreamType = streamInfo.StreamType;

                            audioStreamIndex = transcoder1.Outputs.Count;
                            transcoder1.Outputs.Add(outputSocket);

                            audioFrameSize  = inputAudioStreamInfo.Channels * inputAudioStreamInfo.BitsPerSample / 8;
                            audioSampleRate = inputAudioStreamInfo.SampleRate;
                        }
                    }
                }

                bool res = transcoder1.Open();
                PrintError("Open Transcoder1", transcoder1.Error);
                if (!res)
                {
                    return(false);
                }

                var sample = new MediaSample();
                int outputIndex;

                int        splitPartNum  = 0;
                double     splitTime     = splitPartDuration;
                double     partStartTime = 0;
                Transcoder transcoder2   = null;

                List <SplitRecord> splitStats = new List <SplitRecord>();

                List <MediaSample> audioSamplesQueue = new List <MediaSample>();

                try
                {
                    for (; ;)
                    {
                        if ((audioSamplesQueue.Count > 0) && (audioSamplesQueue[0].StartTime < splitTime))
                        {
                            outputIndex = audioStreamIndex;
                            sample      = audioSamplesQueue[0];
                            audioSamplesQueue.RemoveAt(0);
                        }
                        else
                        {
                            if (!transcoder1.Pull(out outputIndex, sample))
                            {
                                break;
                            }

                            if ((outputIndex != audioStreamIndex) &&
                                (outputIndex != videoStreamIndex))
                            {
                                continue;
                            }
                        }

                        if (outputIndex == audioStreamIndex)
                        {
                            double sampleDuration = (double)(sample.Buffer.DataSize) / (double)(audioFrameSize * audioSampleRate);
                            if (sample.StartTime >= splitTime)
                            {
                                audioSamplesQueue.Add(sample);
                                sample = new MediaSample();
                                continue;
                            }
                            else if ((sample.StartTime + sampleDuration) > splitTime)
                            {
                                double sample1Duration   = splitTime - sample.StartTime;
                                int    sample1BufferSize = (int)(sample1Duration * audioSampleRate) * audioFrameSize;

                                if (sample1BufferSize < sample.Buffer.DataSize)
                                {
                                    int buffer2Size = sample.Buffer.DataSize - sample1BufferSize;
                                    var buffer2     = new MediaBuffer(new byte[buffer2Size]);
                                    buffer2.SetData(0, buffer2Size);

                                    Array.Copy(sample.Buffer.Start, sample1BufferSize, buffer2.Start, 0, buffer2Size);

                                    var sample2 = new MediaSample();
                                    sample2.StartTime = sample.StartTime + sample1Duration;
                                    sample2.Buffer    = buffer2;

                                    if (sample1BufferSize > 0)
                                    {
                                        sample.Buffer.SetData(sample.Buffer.DataOffset, sample1BufferSize);
                                    }
                                    else
                                    {
                                        sample.Buffer.SetData(0, 0);
                                    }

                                    audioSamplesQueue.Add(sample2);
                                }
                            }
                        }


                        if ((transcoder2 == null) ||
                            ((sample.StartTime + 0.0001 >= splitTime) && (outputIndex == videoStreamIndex)))
                        {
                            if (transcoder2 != null)
                            {
                                transcoder2.Flush();
                                transcoder2.Close();
                                transcoder2.Dispose();
                            }

                            SplitRecord splitStat = new SplitRecord();
                            splitStat.StartTime       = splitTime;
                            splitStat.StartTimeActual = sample.StartTime;

                            splitPartNum += 1;
                            splitTime     = splitPartNum * splitPartDuration;
                            partStartTime = sample.StartTime;

                            transcoder2 = new Transcoder();
                            transcoder2.AllowDemoMode = true;

                            // Configure transcoder2 input and output
                            {
                                for (int i = 0; i < transcoder1.Outputs.Count; i++)
                                {
                                    var streamInfo = transcoder1.Outputs[i].Pins[0].StreamInfo.Clone() as StreamInfo;
                                    var pin        = new MediaPin();
                                    pin.StreamInfo = streamInfo;

                                    var socket = new MediaSocket();
                                    socket.Pins.Add(pin);
                                    socket.StreamType = streamInfo.StreamType;

                                    transcoder2.Inputs.Add(socket);
                                }

                                var outputSocket = MediaSocket.FromPreset(encodingPreset);

                                string fileName = GenerateOutputFileName(inputFile, splitPartNum) + outputFileExt;
                                string filePath = Path.Combine(GetExeDir(), fileName);

                                try
                                {
                                    File.Delete(filePath);
                                }
                                catch { }

                                outputSocket.File = filePath;
                                transcoder2.Outputs.Add(outputSocket);

                                splitStat.FileName = fileName;
                            }

                            if (splitStats.Count > 0)
                            {
                                SplitRecord lastRecord = splitStats[splitStats.Count - 1];
                                lastRecord.EndTime       = splitStat.StartTime;
                                lastRecord.EndTimeActual = splitStat.StartTimeActual;
                            }

                            splitStats.Add(splitStat);

                            res = transcoder2.Open();
                            PrintError("Open Transcoder2", transcoder2.Error);
                            if (!res)
                            {
                                return(false);
                            }
                        }

                        if ((splitStats.Count > 0))
                        {
                            SplitRecord lastRecord = splitStats[splitStats.Count - 1];
                            lastRecord.EndTime       = sample.StartTime;
                            lastRecord.EndTimeActual = lastRecord.EndTime;
                        }

                        if (sample.StartTime >= 0)
                        {
                            sample.StartTime = sample.StartTime - partStartTime;
                        }

                        res = transcoder2.Push(outputIndex, sample);
                        if (!res)
                        {
                            PrintError("Push Transcoder2", transcoder2.Error);
                            return(false);
                        }
                    }
                }
                finally
                {
                    if (transcoder2 != null)
                    {
                        transcoder2.Flush();
                        transcoder2.Close();
                        transcoder2.Dispose();
                        transcoder2 = null;
                    }
                }

                if ((transcoder1.Error.Facility != ErrorFacility.Codec) ||
                    (transcoder1.Error.Code != (int)CodecError.EOS))
                {
                    PrintError("Pull Transcoder1", transcoder1.Error);
                    return(false);
                }

                transcoder1.Close();

                // print split stats
                Console.WriteLine();
                foreach (var record in splitStats)
                {
                    Console.WriteLine("{0} start: {1} end: {2} act. start: {3} act. end: {4}", record.FileName,
                                      FormatTime(record.StartTime), FormatTime(record.EndTime), FormatTime(record.StartTimeActual), FormatTime(record.EndTimeActual));
                }
                Console.WriteLine();
            }

            return(true);
        }