0

I have a C# program which takes FFMPEG raw data and begins streaming it to a monitor connected to the network. The program works with still images so I assume I have something wrong with my stdin reading speed. I want the program to work like this:

  1. Begin reading stdin ffmpeg raw
  2. When the buffer is at a specified length (I have to form the frames myself from the raw data, this specified length is width * height * 3)
  3. Send frame & meantime start reading the next part of the raw data

Repeat until shutdown / video end. My current code can stream with 30 FPS, but its not quite good. I could achieve 60 FPS when sending still images. The timers are needed because I have to send the frames at very specific timestamps.

int width = 128;
int height = 64;
static Stream standard_input = Console.OpenStandardInput();
static byte[] buffer_one = new byte[width*height*3];

        public static void ReadStandardInput(){
            int in_len;
            while((in_len = standard_input.Read(buffer, 0, height*width*3)) > 0 ){
                if (in_len == height*width*3){
                    if (frame_delay_clock.IsRunning == false){
                        frame_delay_clock.Start();
                    }
                    if (frame_delay_clock.ElapsedMilliseconds >= wait_between_frames){
                        SendFrame(buffer, 15);
                        frame_delay_clock.Reset();
                    }
                    else{
                        continue;
                    }
                }
                else{
                    continue;
                }
                }
                System.Console.WriteLine("STDIN ended.");
                standard_input.Close();
            }

Malathiane
  • 31
  • 4
  • 1
    The problem isn't how you read from the stream. Unless you use multimedia APIs there's no guarantee your timers (which you haven't posted) will fire exactly when you want them. Or that they can even handle the short intervals required by video - the default timer resolution is 15.6ms, the system heartbeat. It's unclear what `SendFrame` does but it can also cause delays. – Panagiotis Kanavos May 12 '22 at 10:54
  • Applications can change the system heartbeat through system calls but that increases power consumption immensely. CPUs are sleeping when they have nothing to do and wake on every heartbeat to check for work. Older versions of Chrome would drain batteries in a very short time because they increased the timer frequency to ensure smooth animation. Windows (and all OSs) offer special support for multimedia, with high resolution multimedia timers, renderers and specialized thread scheduling. – Panagiotis Kanavos May 12 '22 at 11:01
  • In addition to the other comments, you seem to discard any data if the buffer length doesn’t exactly fit the frame size, meaning you discard partial frames as you receive them. That’s probably not your intent. – Konrad Rudolph May 12 '22 at 11:04
  • Multimedia timers are [described here](https://learn.microsoft.com/en-us/windows/win32/multimedia/multimedia-timers). [This answer](https://stackoverflow.com/a/24843946/134204) shows how to use a multimedia timer but it does increase the heartbeat. Games, audio and video apps use the DirectX APIs to ensure smooth audio and video. These offer a way to create OS-managed pipelines of operators that capture, transform and render multimedia data on time – Panagiotis Kanavos May 12 '22 at 11:08
  • I added the timers because in still image mode the frames were constructed & sent alot quicker than I needed them to be and I had to slow the process so the time between the frames and the packets(frames are split into ~64 packets) are within a certain threshold, else the process falls apart (monitor vibrates and such) these timers are around: wait between frames: 13.3 ms wait between packets: 0,0045 ms ( which totals to around 3-3.2 ms for all packets) and it worked quite well. The image was perfectly sent to the monitor. Also I am working from Linux so i can't call Windows M.M. API – Malathiane May 12 '22 at 11:11
  • What's your problem? Too slow or what else? – shingo May 12 '22 at 11:49
  • Yes, the wait between the frames became around to 30 ms since i'm sending videos with ffmpeg. All other timers are perfect, but the reading (im assuming) is quite slow. The problem did not occur with images send with ffmpeg, only videos. – Malathiane May 12 '22 at 11:53

0 Answers0