Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot handle exception when extract frame and encode video #73

Open
huyphamquang opened this issue Mar 12, 2021 · 3 comments
Open

Cannot handle exception when extract frame and encode video #73

huyphamquang opened this issue Mar 12, 2021 · 3 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@huyphamquang
Copy link

I use this package to do some video task like extract frame and remake video from frame image. My code sometime raise exception like below. I try to add try-catch block to handle it but no luck. Pls show me how to handle exception from ffmpeg lib.

Exception info:
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at FFMediaToolkit.Decoding.Internal.InputContainer.ReadPacket() in C:\projects\ffmediatoolkit\FFMediaToolkit\Decoding\Internal\InputContainer.cs:line 174
at FFMediaToolkit.Decoding.Internal.InputContainer.GetPacketFromStream(Int32 streamIndex) in C:\projects\ffmediatoolkit\FFMediaToolkit\Decoding\Internal\InputContainer.cs:line 90
at FFMediaToolkit.Decoding.Internal.Decoder.DecodePacket() in C:\projects\ffmediatoolkit\FFMediaToolkit\Decoding\Internal\Decoder.cs:line 146
at FFMediaToolkit.Decoding.Internal.Decoder.ReadNextFrame() in C:\projects\ffmediatoolkit\FFMediaToolkit\Decoding\Internal\Decoder.cs:line 136
at FFMediaToolkit.Decoding.VideoStream.GetNextFrame() in C:\projects\ffmediatoolkit\FFMediaToolkit\Decoding\VideoStream.cs:line 51
at FFMediaToolkit.Decoding.VideoStream.TryGetNextFrame(ImageData& bitmap) in C:\projects\ffmediatoolkit\FFMediaToolkit\Decoding\VideoStream.cs:line 68

@jrz371
Copy link
Contributor

jrz371 commented Mar 12, 2021

Can you provide a code snippet and the video file? It's a bit hard to tell what's going on from just this

@huyphamquang
Copy link
Author

here is the source for extract frame:

`[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
private void timerCallback(object state)
{
MediaFile file = null;
long startTick = DateTime.Now.Ticks;
try
{
//int duration = 1000 / Properties.Settings.Default.FrameProcess;
if (PlayListInfo == null || PlayListInfo.Count == 0) return;
int idx = 0;
bool newVideo = true;
TimeSpan endTime = new TimeSpan();
double time_4_frame_ms = 0;
while (idx < PlayListInfo.Count && !request_stop)
{
var startProcess = DateTime.Now;
var curVideo = PlayListInfo[idx];
bool firstFrame = false;
if (newVideo)
{
if (file != null) file.Dispose();
startTick = DateTime.Now.Ticks;
file = MediaFile.Open(curVideo.fileName);
newVideo = false;
endTime = curVideo.stopTime < 0 ? file.Info.Duration : TimeSpan.FromSeconds(curVideo.stopTime);
if (!file.HasVideo)
{
Console.WriteLine($"Cannot load video file: {curVideo.fileName}");
}
else
{
Console.WriteLine($"Process video: {curVideo.fileName}, frame rate: {file.Video.Info.AvgFrameRate}");
time_4_frame_ms = file.Video.Info.NumberOfFrames == null ? 0 : file.Video.Info.Duration.TotalMilliseconds / file.Video.Info.NumberOfFrames.Value;
firstFrame = true;
}
}
TimeSpan sp = new TimeSpan(DateTime.Now.Ticks - startTick);
sp.Add(TimeSpan.FromSeconds(curVideo.startTime <= file.Info.StartTime.TotalSeconds ? file.Info.StartTime.TotalSeconds : curVideo.startTime));
ImageData img;
if (sp > endTime)
{
idx++;
newVideo = true;
continue;
}
if (file != null && file.HasVideo)
{
var t1 = DateTime.Now;
bool ck = false;
if (firstFrame)
{
ck = file.Video.TryGetFrame(sp, out img);
firstFrame = false;
}
else
{
do
{
ck = file.Video.TryGetNextFrame(out img);
}
while (ck && file.Video.Position < sp);
}
if (!ck)
{
Console.WriteLine($"Cannot read frame at {sp} of {curVideo.fileName}");
idx++;
newVideo = true;
continue;
}
else
using (var bitmap = ToBitmap(img))
{
var frametime = DateTime.Now - t1;
//Console.WriteLine($"Take {frametime.TotalMilliseconds} to extract frame of {curVideo.fileName}");
// dataShare.WriteFrameData(img.ImageSize.Width, img.ImageSize.Height,
//DataUtils.PixelFormatToBitCount(bitmap.PixelFormat), img.Data.ToArray());
if (checkBlankFrame(bitmap))
{
Console.WriteLine($"Found black frame at {sp} of {curVideo.fileName}");
}
else ProcessFrame(bitmap);
}
}
var processTime = DateTime.Now - startProcess;
//Console.WriteLine($"Process time of {curVideo.fileName}: {processTime.TotalMilliseconds}/ms");
int sleeptime = (int)(time_4_frame_ms - processTime.TotalMilliseconds);
if (sleeptime > 0)
System.Threading.Thread.Sleep(sleeptime);
}
}
catch (AccessViolationException ex)
{
Console.WriteLine(ex.ToString());
}
catch
{

        }

        finally
        {
            if (file != null)
            {
                try
                {
                    file.Dispose();
                }
                catch
                {

                }
                file = null;
            }
        }

    }`

here is the source code for making video from bitmap:
`private unsafe void PushFrame(Bitmap bitmap)
{
try
{
lock (this)
{
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
try
{
int len = data.Stride * data.Height;
byte[] bitmapData = new byte[len];
Marshal.Copy(data.Scan0, bitmapData, 0, len);
if (frameList.Count == 0) startTime = DateTime.Now.Ticks;
frameList.Add(bitmapData);
}
finally
{
bitmap.UnlockBits(data);
}
//ImageData data = VideoProcessEx.ToImageData(bitmap);
//mediaFile.Video.AddFrame(data);
TimeSpan sp = new TimeSpan(DateTime.Now.Ticks - startTime);
if (sp.TotalSeconds >= Properties.Settings.Default.LiveVideoDuration)
{
if (frameList.Count == 0) return;
videoCount++;
videoIndex = videoCount % 10;

                    var settings = new VideoEncoderSettings(width: bitmap.Width, height: bitmap.Height,
                        framerate: (int)(frameList.Count / sp.TotalSeconds), codec: VideoCodec.H264);
                    settings.EncoderPreset = EncoderPreset.Fast;
                    settings.CRF = 17;
                    //settings.VideoFormat = ImagePixelFormat.Rgb24;
                    string path = $"{VideoFolder}\\{videoIndex}.{videoExt}";
                    using (var mediaFile = MediaBuilder.CreateContainer(path)/*.UseFormatOption("g", "10").UseFormatOption("movflags", "frag_keyframe+empty_moov")*/.WithVideo(settings).Create())
                    {
                        Console.WriteLine($"create video: {MappingFile}.{videoIndex}.{videoExt} -- duration: {sp.TotalSeconds}, total frame: {frameList.Count}");
                        foreach (var item in frameList)
                        {
                            Span<byte> imgData = new Span<byte>(item, 0, item.Length);
                            //return new ImageData(imgData, ImagePixelFormat.Rgb24, bitmap.Size);
                            mediaFile.Video.AddFrame(new ImageData(imgData, ImagePixelFormat.Bgr24, bitmap.Size));
                            
                            //mediaFile.Video.Configuration.Framerate = (int)(mediaFile.Video.FramesCount / sp.TotalSeconds);
                        }
                        AddFileToPlayList(videoCount, $"{videoIndex}.{videoExt}", (decimal)sp.TotalSeconds);
                        //Task.Delay((int)(2) * 1000)
                        //    .ContinueWith((t) =>
                        //    {

                        //        AddFileToPlayList(videoCount, $"{videoIndex}.{videoExt}", (decimal)sp.TotalSeconds);
                        //    });
                    }
                    frameList.Clear();
                }
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }`

@huyphamquang
Copy link
Author

huyphamquang commented Mar 12, 2021

my application process a list of video file and that exeption occur ramdom, i'm not sure about the reson but I only want to catch if it raise exception

@radek-k radek-k added bug Something isn't working help wanted Extra attention is needed labels Jun 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants