This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Video tearing in IPIPE Resizer, only when h264 encoding

We have previously been able to capture NTSC frames (720x480), resize them to our target display (320x240) and display them at the full input rate of 30 FPS. We are now trying to incorporate this operation into the DVSDK encode demo, but we have run into some trouble. In the capture thread, I replaced all of the original code regarding capture and display with my own code which was working fine for simple "pass-through" to the display. This still works fine, but as soon as I introduce the code to get/put buffers from the video thread (which should in turn start the h264 codec running), I get tearing effects in my output buffer. Now here's the part that actually worries me: At no time do I ever try to copy or send either my capture or resized output buffers to the video thread: I am merely getting a buffer handle from the video thread, and then after capture-resize-display, I return it untouched.

My current guess as to what is happening, is that the resizer and h264 peripherals are fighting over the DMA peripheral(s) and the resizer is losing.

Despite the tearing, we did attempt to push on and encode the capture video, which provides some interesting points of information:

  • When using Framecopy_exceute from my output buffer (mem-mapped from the framebuffer device) to the video thread's buffer, the artifacts seen on the screen are visible 1-for-1 in the encoded file. (Play back on the host PC shows the same effect)
  • Trying to isolate the issue, I inserted code to manually fill first the output buffers with a simple test pattern (alternating colored vertical bars): This eliminated the problem. (So the issue must be occurring before Framecopy and display swap)
  • I disabled the output buffer test pattern and applied a similar (larger dimensions) test pattern to the dequeued capture buffer and found that the problem is plainly visible.
  • I then disable the Framecopy sections of the code (so now I am acquiring/returning buffers from/to the video thread but am not touch their contents)
  • Re-running the application I see the exact same issue
  • Finally, I disable the code that acquires and returns the video thread buffers, and the problem disappears.

See the following image and attached m4v video to see what I'm talking about. (VLC or QuickTime are required to view the video file which is a raw h264 video stream)

As my code has three capture buffers, I chose the fill color based on the current buffer index: dark gray for frame 0, light gray for frame 1 and white for frame 2. I neglected to enforce this ordering, but it appears that the capture device always returns the next buffer in the sequence.

5822.encode.m4v

  • On recommendation of Marc D'Amato, I also tried to bypass the resizer by directly copying a subsection from the (manufactured) capture buffer to the output buffer. As expected, the issue does not occur. See attached encode.

    8512.encode.m4v

  • Further information about our software setup:

    We are using an mostly unmodified DVSDK 3.10.00.19. We are using the supplied Linux kernel, but have changed the configuration to suit our needs. Sub component versions are as follows:

    bios_5_41_00_06
    biosutils_1_02_02
    codec_engine_2_25_05_16
    dm355_codecs_03_10_00_02
    dmai_2_10_00_12
    dsplink_linux_1_64
    dvsdk_demos_3_10_00_16
    dvtb_4_20_10
    edma3_lld_01_11_00_03
    framework_components_2_25_02_06
    linuxutils_2_25_04_10
    xdais_6_25_02_11
    xdctools_3_16_01_27

    Our code is directly based on the encode demo in dvsdk_3_10_00_19/dvsdk_demos_3_10_00_16/dm355/encode. We removed the OSD and control related code to make it simpler command line program. We then stripped all of the original Capture and Display related code from the Capture thread and incorporated the code from our own working video capture-resize-display code.

  • And even more information ;-) These are the exact steps that occur in our capture thread (not including initialization/cleanup)

    1. Dequeue video buffer from fifo (320x240)
    2. Dequeue capture buffer (720x480)
    3. Fill capture buffer with test pattern (720x480)
    4. Resize from capture buffer to display buffer (720x480 -> 320x240)
    5. Queue capture buffer (720x480)
    6. Framecopy from display buffer to video buffer (320x240 -> 320x240)
    7. Swap display buffers (320x240 -> 320x240, originally we were alternating between 2 display buffers like in vid_pass, but the effect happens the same when using 3 buffers)
    8. Queue video buffer to fifo (320x240)
    9. Dequeue video buffer from fifo (320x240)
    10. Jump to step #2
  • I believe we've found the problem! My rsz_single_shot_config is cleared to zero before I start filling in any settings for the resizer. One of the settings I skipped over is "input.clk_div", which apparently can be used to slow down the rate at which the IPIPE (Resizer/Previewer) operate. If left at the default value of 0, this results in 1/2 of the VPSS clock, which was apparently just fine for my system when I doing only capture-resize-display (pass-through). Now that I'm doing capture-resize-encode-display, the bandwidth is being overused by the resizer and encoder, resulting in odd behavior. Raising clk_div to 1 (1/3 of VPSS) is enough to get everything working smoothly and without artifact. I've also tested up to 4 (1/6) but at that point the resizer is taking too long and my framerate drops.

    This answer was found for me by Marc D'Amato in the following thread: http://e2e.ti.com/support/embedded/linux/f/354/t/84900.aspx While this person ultimately found that the issue was with their own buffer management, Anshuman made the suggestion of reducing the IPIPE clock rate. :-)