Есть ли другой способ экспортировать кадр из ffmpeg в текстуру2d? Мой код работает в Windows, но не в LinuxC#

Место общения программистов C#
Ответить
Anonymous
 Есть ли другой способ экспортировать кадр из ffmpeg в текстуру2d? Мой код работает в Windows, но не в Linux

Сообщение Anonymous »

Звук работает в Linux так же, как и в Windows. Но видео представляет собой просто черный экран, и когда я пытаюсь сохранить кадры в формате BMP, все они оказываются поврежденными/пустыми файлами. Я использую Ffmpeg.Autogen для взаимодействия с библиотеками. https://github.com/Ruslan-B/FFmpeg.AutoGen. Файл VP8 и OGG в контейнере MKV. Хотя расширение почему-то AVI.

Я попробовал немного повозиться с порядком кода. Я проверил, чтобы в сборке Ffmpeg для Linux был VP8. Я искал в Интернете, но мне было трудно найти другой способ сделать то, что я делаю. Это вклад в проект OpenVIII. Моя вилка-> https://github.com/Sebanisu/OpenVIII

Это просто подготавливает скалер к изменению формата пикселей, иначе у людей будут синие лица.

Код: Выделить всё

        private void PrepareScaler()
{

if (MediaType != AVMediaType.AVMEDIA_TYPE_VIDEO)
{
return;
}

ScalerContext = ffmpeg.sws_getContext(
Decoder.CodecContext->width, Decoder.CodecContext->height, Decoder.CodecContext->pix_fmt,
Decoder.CodecContext->width, Decoder.CodecContext->height, AVPixelFormat.AV_PIX_FMT_RGBA,
ffmpeg.SWS_ACCURATE_RND, null, null, null);
Return = ffmpeg.sws_init_context(ScalerContext, null, null);

CheckReturn();
}
Преобразует фрейм в BMP
Я думаю, проблема именно в этом. Потому что я добавил к этому bitmap.save и получил пустые BMP.

Код: Выделить всё

public Bitmap FrameToBMP()
{
Bitmap bitmap = null;
BitmapData bitmapData = null;

try
{
bitmap = new Bitmap(Decoder.CodecContext->width, Decoder.CodecContext->height, PixelFormat.Format32bppArgb);
AVPixelFormat v = Decoder.CodecContext->pix_fmt;

// lock the bitmap
bitmapData = bitmap.LockBits(new Rectangle(0, 0, Decoder.CodecContext->width, Decoder.CodecContext->height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

byte* ptr = (byte*)(bitmapData.Scan0);

byte*[] srcData = { ptr, null, null, null };
int[] srcLinesize = { bitmapData.Stride, 0, 0, 0 };

// convert video frame to the RGB bitmap
ffmpeg.sws_scale(ScalerContext, Decoder.Frame->data, Decoder.Frame->linesize, 0, Decoder.CodecContext->height, srcData, srcLinesize); //sws_scale broken on linux?
}
finally
{
if (bitmap != null && bitmapData != null)
{
bitmap.UnlockBits(bitmapData);
}
}
return bitmap;

}
После того, как я получил растровое изображение, мы превратили его в Texture2D, чтобы можно было его нарисовать.

Код: Выделить всё

 public Texture2D FrameToTexture2D()
{
//Get Bitmap.  there might be a way to skip this step.
using (Bitmap frame = FrameToBMP())
{
//string filename = Path.Combine(Path.GetTempPath(), $"{Path.GetFileNameWithoutExtension(DecodedFileName)}_rawframe.{Decoder.CodecContext->frame_number}.bmp");

//frame.Save(filename);
BitmapData bmpdata = null;
Texture2D frameTex = null;
try
{
//Create Texture
frameTex = new Texture2D(Memory.spriteBatch.GraphicsDevice, frame.Width, frame.Height, false, SurfaceFormat.Color); //GC will collect frameTex
//Fill it with the bitmap.
bmpdata = frame.LockBits(new Rectangle(0, 0, frame.Width, frame.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);// System.Drawing.Imaging.PixelFormat.Format32bppArgb);
byte[] texBuffer = new byte[bmpdata.Width * bmpdata.Height * 4]; //GC here
Marshal.Copy(bmpdata.Scan0, texBuffer, 0, texBuffer.Length);

frameTex.SetData(texBuffer);

}
finally
{
if (bmpdata != null)
{
frame.UnlockBits(bmpdata);
}
}
return frameTex;

}
}
Я могу опубликовать больше, если вы хотите, чтобы почти все было на моей вилке.

Видео будет воспроизводиться как это происходит в Windows. Настолько плавно, насколько это возможно при 15 кадрах в секунду. :)

Подробнее здесь: https://stackoverflow.com/questions/554 ... de-working
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»