v4l2 codec hanging with certain input data when encoding to h.264

Open
#4,906 12 comments 0 reactions 1 assignee View on GitHub

@6by9 is already working on this.

Since Dec 22, 2022.

Assessment

This issue has not been assessed yet.

Description

Describe the bug

When feeding raw Data from a ADV7282-M CVBS to CSI2 decoder to the v4l2 codec (GStreamer v4l2h264enc) it can happen that the encoder starts to stop outputting data and is starting to use memory without freeing. This continuous till the Application gets killed trough OOM Management. See: https://forums.raspberrypi.com/viewtopic.php?t=329729

Steps to reproduce the behavior

I was able to reproduce this exact phenomen with feeding raw data from /dev/urandom to the v4l2 codec. Sample code is attached.

Code:

#include <stdio.h>
#include <stdbool.h>

#include <unistd.h>

#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappsink.h>
#include <gst/gstbuffer.h>
#include <gst/gstmemory.h>

#ifdef __arm__
#define IMAGE_WIDTH 720
#define IMAGE_HEIGHT 576
#endif

#define VIDEO_GST_DEBUG "*:3"
GstElement *pPipeline = NULL;
GstElement *pAppSrc = NULL;

void init_pipeline()
{
    if (pPipeline != NULL)
        return;

    unsigned int major, minor, micro, nano;

    /* initialize gstreamer */
    setenv("GST_DEBUG", VIDEO_GST_DEBUG, 5);
    gst_init(NULL, NULL);
    gst_version(&major, &minor, &micro, &nano);
    gst_update_registry();

    printf("Gstreamer initialized. \n");
    printf("Gstreamer version: %u %u %u %u \n", major, minor, micro, nano);

#ifdef __arm__
    char *pipelineStr = "appsrc name=appsrc ! video/x-raw, interlace-mode=interleaved, framerate=25/1, format=UYVY, width=720, height=576 ! "
                        "deinterlace method=linear ! videocrop top=16 left=16 right=16 bottom=16 ! videorate ! videoscale ! "
                        "video/x-raw, framerate=25/1, width=640, height=480 ! videoconvert ! "
                        "queue ! v4l2h264enc output-io-mode=2 extra-controls=\"controls,h264_profile=0,video_bitrate=1000000,h264_i_frame_period=10,repeat_sequence_header=1;\" ! "
                        "video/x-h264, level=(string)3, profile=baseline, stream-format=byte-stream ! filesink location=out.h264";

    pPipeline = gst_parse_launch(pipelineStr, NULL);

    printf("Pipeline: %s \n", pipelineStr);
#endif

    pAppSrc = gst_bin_get_by_name(GST_BIN(pPipeline), "appsrc");
    // ASSERT(pAppSrc != NULL);
    g_object_set(pAppSrc, "format", GST_FORMAT_TIME, NULL);

    if (pPipeline == NULL)
    {
        printf("Failed to init pipeline \n");
        exit(-1);
    }

    /* Start playing */
    gst_element_set_state(pPipeline, GST_STATE_PLAYING);
}

FILE *myfile = NULL;

void write_gst_data(char *buffer, size_t length)
{
    GstBuffer *gstbuffer;
    GstFlowReturn ret;
    GstMapInfo map;

    /* copy frame to gst buffer */
    gstbuffer = gst_buffer_new_and_alloc(length);
    gst_buffer_map(gstbuffer, &map, GST_MAP_WRITE);
    memcpy(map.data, buffer, length);
    gst_buffer_unmap(gstbuffer, &map);

    /* push data to appsrc */
    ret = gst_app_src_push_buffer(GST_APP_SRC(pAppSrc), gstbuffer);
    if (ret != GST_FLOW_OK)
    {
        printf("-EINVAL GST_FLOW! \n");
    }
}

int main(int argc, char *argv[])
{
    init_pipeline();

    while (true)
    {
        char *uyvybuffer = (char *)malloc(IMAGE_WIDTH * IMAGE_HEIGHT * 2);

        FILE *fp;
        fp = fopen("/dev/urandom", "r");
        fread(uyvybuffer, 1, IMAGE_WIDTH * IMAGE_HEIGHT * 2, fp);
        fclose(fp);

        write_gst_data(uyvybuffer, IMAGE_WIDTH * IMAGE_HEIGHT * 2);

        free(uyvybuffer);

        // 25FPS -> 40ms
        usleep(40 * 1000);
    }
}

Build:

gcc -g main.c -I. -o decoder `pkg-config --cflags --libs gstreamer-1.0` `pkg-config --cflags --libs gstreamer-app-1.0`
Device (s)

Raspberry Pi CM4

System
user@CM4:~ $ cat /etc/rpi-issue
Raspberry Pi reference 2021-10-30
Generated using pi-gen, https://github.com/RPi-Distro/pi-gen, 288b21fc27e128ea6b330777aca68e0061ebf4fe, stage2
user@CM4:~ $ sudo vcgencmd version
Oct 29 2021 10:47:33 
Copyright (c) 2012 Broadcom
version b8a114e5a9877e91ca8f26d1a5ce904b2ad3cf13 (clean) (release) (start)
user@CM4:~ $ uname -a
Linux CM4 5.15.24-v7l+ #4 SMP Thu Feb 24 11:43:31 CET 2022 armv7l GNU/Linux
Logs

No errors/warnings visible in GST/Syslog and dmesg Log. Also tried to enable debugging in bcm2835-v4l2-codec and mmal-vchiq but didn't get to any conclusion with it.

Additional context

No response

Dominant language
C
Stars
13.2k
Forks
5.5k
Avg merge
2d 21h
Merged PRs (30d)
21

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from raspberrypi/linux

All issues in raspberrypi/linux

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.