Подскажите кто имеет опыт разработки под Media Foundation
От: Alitrix  
Дата: 11.10.19 02:57
Оценка:
Проблема в целом такая, есть куча картинок в формате или jpg или png, это не важно,
их получаю и конвертирую в NV12 с помощью TransformCategoryGuids.VideoProcessor на c#
но сейчас не вопрос реализации или где взять функции или ещё что то, а только голая теори.
Так вот, после цвета конвертации я получаю на выходе IMFSample MediaType.Video MediaSubType.NV12,
эта часть программы работает хорошо делаю через
MFExtern.MFTEnumEx(TransformCategoryGuids.VideoProcessor , MFT_EnumFlag.All, registerTypeInfoIn,
registerTypeInfoOut, out mFActivates, out mFActivatesCount); с указанием типов и т.д.
для тестирования сделал обратное конвертирование и показ на форме результата, всё работает изображение видно.
Но вот с чем не могу понять так какие шаги нужно сделать, что бы теперь из эти IMFSample сформировать
H264 поток и потом его записать в файл ? Подскажите уже 2-ю неделю борюсь с этим, очень было бы полезно
если бы объяснили что нужно сделать типа :

1.IMFCreateSourceReader из IMFBytesStream
2.на полученый источник применить атрибуты или что то там...

Очень прошу помогите !!!!
Re: Подскажите кто имеет опыт разработки под Media Foundation
От: alexander_r  
Дата: 26.10.19 20:09
Оценка:
Здравствуйте, Alitrix, Вы писали:


A>Но вот с чем не могу понять так какие шаги нужно сделать, что бы теперь из эти IMFSample сформировать

A>H264 поток и потом его записать в файл ? Подскажите уже 2-ю неделю борюсь с этим, очень было бы полезно
A>если бы объяснили что нужно сделать типа :

Чтобы получить h264 поток нужен энкодер, создается он как и все остальные transform-ы, только будет асинхронным, что бы записать в файл можно использовать SinkWriter

пример как использовать на C#
Re[2]: Подскажите кто имеет опыт разработки под Media Foundation
От: Alitrix  
Дата: 31.10.19 00:13
Оценка:
Здравствуйте, alexander_r, Вы писали:

_>Здравствуйте, Alitrix, Вы писали:



A>>Но вот с чем не могу понять так какие шаги нужно сделать, что бы теперь из эти IMFSample сформировать

A>>H264 поток и потом его записать в файл ? Подскажите уже 2-ю неделю борюсь с этим, очень было бы полезно
A>>если бы объяснили что нужно сделать типа :

_>Чтобы получить h264 поток нужен энкодер, создается он как и все остальные transform-ы, только будет асинхронным, что бы записать в файл можно использовать SinkWriter


_>пример как использовать на C#



Подскажите хоть один пример асинхронного кодирования, без использования Сессий, фактически читаю файлы изображения,
и пишу их в поток h264, точнее не пишу через sinkwriter а использую IMFTransform и ProcessInput-ProcessOutput, но получается
что этот процесс синхронный, сдаю Сэмпл на вход проверяю если готов выходной поток забираю кодированный кадр.
Данную механику вообще можно оформить как асинхронную ? Может есть где ни будь информация ?
Re[3]: Подскажите кто имеет опыт разработки под Media Foundation
От: alexander_r  
Дата: 04.11.19 01:10
Оценка:
Здравствуйте, Alitrix, Вы писали:

A>Подскажите хоть один пример асинхронного кодирования, без использования Сессий, фактически читаю файлы изображения,

A>и пишу их в поток h264, точнее не пишу через sinkwriter а использую IMFTransform и ProcessInput-ProcessOutput, но получается
A>что этот процесс синхронный, сдаю Сэмпл на вход проверяю если готов выходной поток забираю кодированный кадр.
A>Данную механику вообще можно оформить как асинхронную ? Может есть где ни будь информация ?
в асинхронном режиме трансформ посылает сообщения
TransformNeedInput — значит что нужно передать ему данные,
TransformHaveOutput — данные готовы нужно их забрать, собственно и все
Asynchronous MFTs
пример на C#
Re[4]: Подскажите кто имеет опыт разработки под Media Foundation
От: Alitrix  
Дата: 20.11.19 00:37
Оценка:
Здравствуйте, alexander_r, Вы писали:

_>Здравствуйте, Alitrix, Вы писали:


A>>Подскажите хоть один пример асинхронного кодирования, без использования Сессий, фактически читаю файлы изображения,

A>>и пишу их в поток h264, точнее не пишу через sinkwriter а использую IMFTransform и ProcessInput-ProcessOutput, но получается
A>>что этот процесс синхронный, сдаю Сэмпл на вход проверяю если готов выходной поток забираю кодированный кадр.
A>>Данную механику вообще можно оформить как асинхронную ? Может есть где ни будь информация ?
_>в асинхронном режиме трансформ посылает сообщения
_>TransformNeedInput — значит что нужно передать ему данные,
_>TransformHaveOutput — данные готовы нужно их забрать, собственно и все
_>Asynchronous MFTs
_>пример на C#

Я разобрался с конвертацией цвета ARGB->NV12 после этого IMFTransform -> H264, на выходе получаю
IMFSample, хочу его декодировать обратно в NV12 и после этого сделать конвертацию цвета что бы показать кадр
но ни при каком условии Декодировщик не хочет выдавать сообщение SampleReady !
Постоянно transform.GetOutputStatus(out MFTOutputStatusFlags outputStatusFlags); всегда возвращает None !

Как можно победить, я получаю из не основного потока который выполняет кодирование IMFSample
и пытаюсь декодировать в потоке основного окна, но сколько бы я не давал входящих IMFSample нет ни чего на выходе.

В чем может быть причина ?
Re[5]: Подскажите кто имеет опыт разработки под Media Foundation
От: alexander_r  
Дата: 21.11.19 21:36
Оценка:
A>Я разобрался с конвертацией цвета ARGB->NV12 после этого IMFTransform -> H264, на выходе получаю
A>IMFSample, хочу его декодировать обратно в NV12 и после этого сделать конвертацию цвета что бы показать кадр

A>но ни при каком условии Декодировщик не хочет выдавать сообщение SampleReady !

A>Постоянно transform.GetOutputStatus(out MFTOutputStatusFlags outputStatusFlags); всегда возвращает None !

A>Как можно победить, я получаю из не основного потока который выполняет кодирование IMFSample

A>и пытаюсь декодировать в потоке основного окна, но сколько бы я не давал входящих IMFSample нет ни чего на выходе.

A>В чем может быть причина ?


Вы проверяли полученный после энкодера сэмпл? это действительно правильный h264?
А eсли не ждать SampleReady, а вызывать ProcessOutput
  Пример
        public bool ProcessSample(Sample inputSample, out Sample outputSample)
        {
            

            bool Result = false;
            outputSample = null;

            if (inputSample == null)
            {
                return false;
            }

            frameNumber++;
            inputSample.SampleTime = frameNumber * frameDuration;
            inputSample.SampleDuration = frameDuration;

            decoder.ProcessInput(0, inputSample, 0);

            //if (decoder.OutputStatus == (int)MftOutputStatusFlags.MftOutputStatusSampleReady)
            {

                decoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo);

                MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags;
                bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples);

                // Create output sample


                if (createSample)
                {
                    outputSample = MediaFactory.CreateSample();
                    using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize))
                    {
                        outputSample.AddBuffer(mediaBuffer);
                    }
                }

                TOutputDataBuffer[] outputDataBuffer = new TOutputDataBuffer[1];

                var data = new TOutputDataBuffer
                {
                    DwStatus = 0,
                    DwStreamID = 0,
                    PSample = outputSample,
                    PEvents = null,
                };
                outputDataBuffer[0] = data;

                //bool res = true;
                // processor.ProcessOutput(TransformProcessOutputFlags.None,  1, outputDataBuffer, out TransformProcessOutputStatus status);
                //var res = processor.ProcessOutput(TransformProcessOutputFlags.None,  data, out TransformProcessOutputStatus status);

                //logger.Debug("TryProcessOutput BEGIN");

                var res = decoder.TryProcessOutput(TransformProcessOutputFlags.None,  outputDataBuffer, out TransformProcessOutputStatus status);

               
                //var res = decoder.ProcessOutput(TransformProcessOutputFlags.None, data, out TransformProcessOutputStatus status);

                //logger.Debug("TryProcessOutput END " + res);
                if (res.Success)
                {


                    if (outputSample == null)
                    {
                        outputSample = outputDataBuffer[0].PSample;
                    }

                    Debug.Assert(outputSample != null, "res.Success && outputSample != null");

                    Result = true;
                }
                else
                {
                    if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput)
                    {
                        //logger.Warn(res.ToString() + " TransformNeedMoreInput");

                        Result = true;

                    }
                    else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange)
                    {
                        //...
                        logger.Warn(res.ToString() + " TransformStreamChange");

                        decoder.TryGetOutputAvailableType(outputStreamId, 0, out MediaType newOutputType);
                        decoder.SetOutputType(outputStreamId, newOutputType, 0);

                        if (OutputMediaType != null)
                        {
                            OutputMediaType.Dispose();
                            OutputMediaType = null;
                        }

                        OutputMediaType = newOutputType;
                        logger.Info("============== NEW OUTPUT TYPE==================");
                        logger.Info(MfTool.LogMediaType(newOutputType));
   

                    }
                    else
                    {
                        res.CheckError();
                    }
                }

            }

            return Result;
        }

если пользуетесь SharpDx.MediaFoundation, то там есть баг в функции ProcessOutput, в некоторых случаях она не возвращает PSample
Re[6]: Подскажите кто имеет опыт разработки под Media Foundation
От: Alitrix  
Дата: 24.11.19 23:31
Оценка:
Здравствуйте, alexander_r, Вы писали:

A>>Я разобрался с конвертацией цвета ARGB->NV12 после этого IMFTransform -> H264, на выходе получаю

A>>IMFSample, хочу его декодировать обратно в NV12 и после этого сделать конвертацию цвета что бы показать кадр

A>>но ни при каком условии Декодировщик не хочет выдавать сообщение SampleReady !

A>>Постоянно transform.GetOutputStatus(out MFTOutputStatusFlags outputStatusFlags); всегда возвращает None !

A>>Как можно победить, я получаю из не основного потока который выполняет кодирование IMFSample

A>>и пытаюсь декодировать в потоке основного окна, но сколько бы я не давал входящих IMFSample нет ни чего на выходе.

A>>В чем может быть причина ?


_>Вы проверяли полученный после энкодера сэмпл? это действительно правильный h264?

_>А eсли не ждать SampleReady, а вызывать ProcessOutput
_>
  Пример
_>
_>        public bool ProcessSample(Sample inputSample, out Sample outputSample)
_>        {
            

_>            bool Result = false;
_>            outputSample = null;

_>            if (inputSample == null)
_>            {
_>                return false;
_>            }

_>            frameNumber++;
_>            inputSample.SampleTime = frameNumber * frameDuration;
_>            inputSample.SampleDuration = frameDuration;

_>            decoder.ProcessInput(0, inputSample, 0);

_>            //if (decoder.OutputStatus == (int)MftOutputStatusFlags.MftOutputStatusSampleReady)
_>            {

_>                decoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo);

_>                MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags;
_>                bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples);

_>                // Create output sample


_>                if (createSample)
_>                {
_>                    outputSample = MediaFactory.CreateSample();
_>                    using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize))
_>                    {
_>                        outputSample.AddBuffer(mediaBuffer);
_>                    }
_>                }

_>                TOutputDataBuffer[] outputDataBuffer = new TOutputDataBuffer[1];

_>                var data = new TOutputDataBuffer
_>                {
_>                    DwStatus = 0,
_>                    DwStreamID = 0,
_>                    PSample = outputSample,
_>                    PEvents = null,
_>                };
_>                outputDataBuffer[0] = data;

_>                //bool res = true;
_>                // processor.ProcessOutput(TransformProcessOutputFlags.None,  1, outputDataBuffer, out TransformProcessOutputStatus status);
_>                //var res = processor.ProcessOutput(TransformProcessOutputFlags.None,  data, out TransformProcessOutputStatus status);

_>                //logger.Debug("TryProcessOutput BEGIN");

_>                var res = decoder.TryProcessOutput(TransformProcessOutputFlags.None,  outputDataBuffer, out TransformProcessOutputStatus status);

               
_>                //var res = decoder.ProcessOutput(TransformProcessOutputFlags.None, data, out TransformProcessOutputStatus status);

_>                //logger.Debug("TryProcessOutput END " + res);
_>                if (res.Success)
_>                {


_>                    if (outputSample == null)
_>                    {
_>                        outputSample = outputDataBuffer[0].PSample;
_>                    }

_>                    Debug.Assert(outputSample != null, "res.Success && outputSample != null");

_>                    Result = true;
_>                }
_>                else
_>                {
_>                    if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput)
_>                    {
_>                        //logger.Warn(res.ToString() + " TransformNeedMoreInput");

_>                        Result = true;

_>                    }
_>                    else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange)
_>                    {
_>                        //...
_>                        logger.Warn(res.ToString() + " TransformStreamChange");

_>                        decoder.TryGetOutputAvailableType(outputStreamId, 0, out MediaType newOutputType);
_>                        decoder.SetOutputType(outputStreamId, newOutputType, 0);

_>                        if (OutputMediaType != null)
_>                        {
_>                            OutputMediaType.Dispose();
_>                            OutputMediaType = null;
_>                        }

_>                        OutputMediaType = newOutputType;
_>                        logger.Info("============== NEW OUTPUT TYPE==================");
_>                        logger.Info(MfTool.LogMediaType(newOutputType));
   

_>                    }
_>                    else
_>                    {
_>                        res.CheckError();
_>                    }
_>                }

_>            }

_>            return Result;
_>        }
_>


_>если пользуетесь SharpDx.MediaFoundation, то там есть баг в функции ProcessOutput, в некоторых случаях она не возвращает PSample


А как я могу проверить верный ли Sample на выходе формата h264 ? Правда я использую не SharpDX а MF.Net.
Я пробовал записывать в файл последовательно полученные IMFSample с Энкодера, файл проигрывается wmplayer нормально,
и цвет и скорость. Пробовал как вы указали не ждать SampleReady, ны выход получаю просто зеленый экран вместо изображения.
Как я понял просто нули и нет декодированного кадра.
Re[7]: Подскажите кто имеет опыт разработки под Media Foundation
От: alexander_r  
Дата: 25.11.19 15:00
Оценка:
A> Пробовал как вы указали не ждать SampleReady, ны выход получаю просто зеленый экран вместо изображения.
A>Как я понял просто нули и нет декодированного кадра.
ProcessOutput при этом возвращает ошибку ??
проблема может быть где угодно, может быть декодер не правильно проинициализирован
что бы не гадать нужно видеть код, без кода сложно что то советовать...
Re[8]: Подскажите кто имеет опыт разработки под Media Foundation
От: Alitrix  
Дата: 09.12.19 04:21
Оценка:
Здравствуйте, alexander_r, Вы писали:


A>> Пробовал как вы указали не ждать SampleReady, ны выход получаю просто зеленый экран вместо изображения.

A>>Как я понял просто нули и нет декодированного кадра.
_>ProcessOutput при этом возвращает ошибку ??
_>проблема может быть где угодно, может быть декодер не правильно проинициализирован
_>что бы не гадать нужно видеть код, без кода сложно что то советовать...


А можно вашу почту ? я бы на неё скинул исходник
Re[9]: Подскажите кто имеет опыт разработки под Media Foundation
От: alexander_r  
Дата: 09.12.19 11:45
Оценка:
Здравствуйте, Alitrix, Вы писали:

A>А можно вашу почту ? я бы на неё скинул исходник

Зачем на почту то , залейте тестовое приложение на github, может еще кто то присоединится и что-нибудь подскажет...
Re[7]: Подскажите кто имеет опыт разработки под Media Founda
От: alexander_r  
Дата: 09.12.19 11:59
Оценка:
Здравствуйте, Alitrix, Вы писали:

A> Пробовал как вы указали не ждать SampleReady, ны выход получаю просто зеленый экран вместо изображения.

ProcessOutput() возвращает при этом ошибку??
обычно после первого сэмпла приходит MF_E_TRANSFORM_STREAM_CHANGE, нужно перенастроить декодер и дальше все должно заработать..

https://docs.microsoft.com/en-us/windows/win32/medfound/handling-stream-changes
Отредактировано 09.12.2019 12:08 alexander_r . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.