Electronics > Beginners
Learning FPGAs for Video Processing
xxninjabunnyxx:
--- Quote from: BrianHG on January 18, 2019, 09:23:33 am ---According to xxninjabunnyxx's Reply #9 on: January 15, 2019, 09:52:56 pm, I think what he is trying to say is that he doesn't know what a video signal is or how it works. Whether it's VGA, DVI, or HDMI, video has a vertical sync which reset's the vertical position to 0 and a horizontal sync which resets the horizontal position to 0. At every clock on the data coming in, the pixels are fed from left to right, top to bottom. Remember, DVI is exactly a VGA signal in digital form. HDMI usually only is sent in YUV instead of RGB, but, the picture pixel elements are broadcast in the exact same left to right, top to bottom order.
In HDMI and DVI, there is also an 'Active Video' flag. Like the Vertical sync flag and Horizontal sync flag, this flag tells you when during each pixel clock, a valid picture pixel is present. In analog VGA, you need to to scan for these borders in the source video as different video standards have different active video regions. Like I said, with DVI and HDMI, the 'Active video' or 'Video Enable' flag creates this rectangular region for you and it's embedded in the HDMI DVI standard.
--- End quote ---
I understand how video works. What I don't know to do is make a buffer that holds a few lines of video and sends them out at the correct time. I'm thinking that the HDMI encoder would have pulses sent over to the BRAM module when it ready to send a new line. I like I said before I'm very new to FPGAs and I don't know if this is the right method to take.
hamster_nz:
--- Quote from: xxninjabunnyxx on January 19, 2019, 11:47:14 pm ---
--- Quote from: BrianHG on January 18, 2019, 09:23:33 am ---According to xxninjabunnyxx's Reply #9 on: January 15, 2019, 09:52:56 pm, I think what he is trying to say is that he doesn't know what a video signal is or how it works. Whether it's VGA, DVI, or HDMI, video has a vertical sync which reset's the vertical position to 0 and a horizontal sync which resets the horizontal position to 0. At every clock on the data coming in, the pixels are fed from left to right, top to bottom. Remember, DVI is exactly a VGA signal in digital form. HDMI usually only is sent in YUV instead of RGB, but, the picture pixel elements are broadcast in the exact same left to right, top to bottom order.
In HDMI and DVI, there is also an 'Active Video' flag. Like the Vertical sync flag and Horizontal sync flag, this flag tells you when during each pixel clock, a valid picture pixel is present. In analog VGA, you need to to scan for these borders in the source video as different video standards have different active video regions. Like I said, with DVI and HDMI, the 'Active video' or 'Video Enable' flag creates this rectangular region for you and it's embedded in the HDMI DVI standard.
--- End quote ---
I understand how video works. What I don't know to do is make a buffer that holds a few lines of video and sends them out at the correct time. I'm thinking that the HDMI encoder would have pulses sent over to the BRAM module when it ready to send a new line. I like I said before I'm very new to FPGAs and I don't know if this is the right method to take.
--- End quote ---
You make a delay line.
You chain a few Block RAM blocks to make a 27-bit wide (for 24-bit RGB + hsync + vsync + video_active flags) , dual ported memory, and you write to address 'i', read from address 'I+horizontal_count)'.
Makes it look like a big long shift register....
BrianHG:
Use a dual port, dual clock fifo in the FPGA. The output of the fifo should run at the pixel clock. On the internal system clock use the 'Almost Full' flag to decide how to transfer data. This method can have syncing issues as you need to pass the horizontal alignment into the buffer and fill the buffer with exact pixel counts per line.
My working method is a dual port ram, which has a multiple of 2048 x (X lines of cache) x 24 bits. On the output clock side, running at the pixel clock, with my horizontal raster line generator and address counter reset to the beginning of active video, on the output of that dual port ram I feed the data into my HDMI out and for the MSB on the dual port ram, I place a 2 bit counter which increments on the HS out only during an active video region and it resets on VS. This means, if the output mode is 1920, in that cache ram, I will waste 2048-1920=128 pixels. In lower resolution modes, less of this buffer will be used. On the system clock side, all I monitor is an asynchronous VS from the output and the 2 bit counter on the output to tell where my vertical position is in my 4 line output buffer. In other words, right after a VS out before new active video, I begin to fill my 4 line video out dual port cache ram. As it's 2 bit output counter increases, I know I have free new lines to fill. This means I have a video raster generator on the output clock and only 3 asynchronous signals are going back to the system core clock, VSout and a 2 bit vertical buffer position. (This makes making any core DDR video system ram, or scan rate converters a breeze when paging a fill line of DDR ram in at a time making the fastest possible burst leaving blank DDR cycles for other uses)
Yes there are more advanced methods to do this, but with the scope of you project time, choose this extra simple method to fill a clean line by line video out, and the exact reverse for a video in buffer.
The rules get simpler and change for real time processing where the output image format matches the input image format where you enhance video on the fly. But going that way, you will not be able to cache an image in DDR Memory and play back a full screen buffer. You will also need to sync copy in and out syncs with and appropriate delay of clocks or line to do this.
xxninjabunnyxx:
--- Quote from: hamster_nz on January 20, 2019, 12:38:50 am ---
You make a delay line.
You chain a few Block RAM blocks to make a 27-bit wide (for 24-bit RGB + hsync + vsync + video_active flags) , dual ported memory, and you write to address 'i', read from address 'I+horizontal_count)'.
Makes it look like a big long shift register....
--- End quote ---
So let me see if I got this right. Create BRAM that has full, empty, almost full, and almost empty flags. Decode the HDMI and encode it into 27-bit wide serial signal and write that to the BRAM with the address of the hsync value. Then create a module that reads from the BRAM when the empty flag is not set, edits the signal and writes it back to the BRAM at the same address. Then create an HDMI encoder that reads the BRAM when the almost full flag is set at the start of the BRAM and incrementing a counter. So the address counter would work like program counter on a virtual machine (Java VM or Python VM, not VirtualBox VM).
BrianHG:
--- Quote from: xxninjabunnyxx on January 20, 2019, 01:41:58 am ---
--- Quote from: hamster_nz on January 20, 2019, 12:38:50 am ---
You make a delay line.
You chain a few Block RAM blocks to make a 27-bit wide (for 24-bit RGB + hsync + vsync + video_active flags) , dual ported memory, and you write to address 'i', read from address 'I+horizontal_count)'.
Makes it look like a big long shift register....
--- End quote ---
So let me see if I got this right. Create BRAM that has full, empty, almost full, and almost empty flags. Decode the HDMI and encode it into 27-bit wide serial signal and write that to the BRAM with the address of the hsync value. Then create a module that reads from the BRAM when the empty flag is not set, edits the signal and writes it back to the BRAM at the same address. Then create an HDMI encoder that reads the BRAM when the almost full flag is set at the start of the BRAM and incrementing a counter. So the address counter would work like program counter on a virtual machine (Java VM or Python VM, not VirtualBox VM).
--- End quote ---
My above method (https://www.eevblog.com/forum/beginners/learning-fpgas-for-video-processing/msg2134117/#msg2134117) gives you an X/Y position counter. However, the Y position is the bottom 2 bits only, you need to keep track of all the upper bits as the picture is fed out. (Note you can increase the line cache size if you line, 3 bits for 8 lines of cache, ect. Same goes if you reverse the process for video input.)
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version