omxh264 encoded data bitrate bigger than set

1.I use this pipline to encode:
pipeline = gst_parse_launch(“appsrc name=appsrc0 ! videoparse width=1920 height=1080 format=nv12 ! omxh264enc bitrate=1000000 ! video/x-h264,stream-format=(string)byte-stream ! appsink name=appsink0”, NULL);
2.use appsrc to push data to encode.

3.use appsink to pull encoded data.

4.then i got frame type and len as flow:
Framerate set to : 25 at NvxVideoEncoderSetParameter
NvMMLiteOpen : Block : BlockType = 4
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4
H264: Profile = 66, Level = 40
1 65 len 185025 pts:0
2 61 len 176536 pts:3600
3 61 len 176154 pts:7200
4 61 len 174877 pts:10800
5 61 len 174000 pts:14400
6 61 len 173006 pts:18000
7 61 len 171751 pts:21600
8 61 len 172233 pts:25200
9 61 len 170326 pts:28800
10 61 len 169802 pts:32400
11 61 len 169955 pts:36000
12 61 len 169730 pts:39600
13 61 len 170158 pts:43200
14 61 len 168533 pts:46800
15 61 len 168988 pts:50400
16 61 len 169784 pts:54000
17 61 len 169027 pts:57600
18 61 len 169680 pts:61200
19 61 len 168414 pts:64800
20 61 len 167930 pts:68400
21 61 len 167938 pts:72000
22 61 len 168033 pts:75600
23 61 len 167829 pts:79200
24 61 len 168500 pts:82800
25 61 len 167445 pts:86400
26 61 len 168055 pts:90000
27 61 len 167437 pts:93600
28 61 len 167643 pts:97200
29 61 len 167690 pts:100800
30 61 len 166698 pts:104400
31 67 len 185067 pts:108000
32 61 len 177553 pts:111600
33 61 len 175277 pts:115200
34 61 len 175009 pts:118800
35 61 len 173096 pts:122400
36 61 len 173209 pts:126000
37 61 len 170971 pts:129600
38 61 len 171106 pts:133200
39 61 len 169912 pts:136800
40 61 len 170049 pts:140400
41 61 len 169317 pts:144000
42 61 len 169365 pts:147600
43 61 len 168547 pts:151200
44 61 len 168735 pts:154800
45 61 len 167807 pts:158400
46 61 len 168317 pts:162000
47 61 len 167962 pts:165600
48 61 len 168128 pts:169200
49 61 len 167979 pts:172800
50 61 len 167386 pts:176400
51 61 len 167141 pts:180000
52 61 len 166540 pts:183600
53 61 len 166626 pts:187200
54 61 len 166588 pts:190800
55 61 len 166911 pts:194400
56 61 len 167698 pts:198000
57 61 len 167495 pts:201600
58 61 len 167037 pts:205200
59 61 len 167220 pts:208800
Deleting pipeline

  1. some code:

bool CGstEnc::StartEnc(int width, int height, int bitrate)
{
this->width = width;
this->height = height;

pipeline = gst_parse_launch("appsrc name=appsrc0 ! videoparse width=1920 height=1080 format=nv12 ! omxh264enc bitrate=500000 ! video/x-h264,stream-format=(string)byte-stream ! appsink name=appsink0", NULL);


if (!pipeline)
{
    return false;
}
int id = 0;

bus = gst_element_get_bus(pipeline);
std::string str2 = "appsrc" + std::to_string(id);
appsrc = gst_bin_get_by_name(GST_BIN(pipeline), str2.c_str());

g_object_set(appsrc, "format", GST_FORMAT_TIME, NULL);

str2 = "appsink" + std::to_string(id);
appsink = gst_bin_get_by_name(GST_BIN(pipeline), str2.c_str());


GstStateChangeReturn ret;

ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
    gst_object_unref(pipeline);;
    pipeline = NULL;
    return false;
}
// Create gstreamer loop
loop = g_main_loop_new(NULL, FALSE);

// add a message handler
bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);

CThread::Start();
return true;

}

void CGstEnc::PushBuffer(std::shared_ptr node)
{
GstFlowReturn ret;
GstBuffer *buffer;

buffer = gst_buffer_new_allocate(NULL, node->used, NULL);

GstMapInfo info;
gst_buffer_map(buffer, &info, GST_MAP_WRITE);
unsigned char *buf = info.data;
memmove(buf, node->pData.get(), node->used);
gst_buffer_unmap(buffer, &info);

//GST_BUFFER_DTS(buffer) = GST_BUFFER_PTS(buffer) = idx * 33333333;
GST_BUFFER_DTS(buffer) = GST_BUFFER_PTS(buffer) = node->pts;

ret = gst_app_src_push_buffer(GST_APP_SRC(appsrc), buffer);
}

std::shared_ptr CGstEnc::PullBuffer()
{

GstClockTime timeout = 30*1000000;

// Will block until sample is ready. In our case “sample” is encoded picture.
GstSample *sample = gst_app_sink_try_pull_sample(GST_APP_SINK(appsink),timeout);

if (sample == NULL) {
//fprintf(stderr, “gst_app_sink_pull_sample returned null\n”);
return NULL;
}

// Actual compressed image is stored inside GstSample.
GstBuffer *buffer = gst_sample_get_buffer(sample);
GstMapInfo map;
gst_buffer_map(buffer, &map, GST_MAP_READ);

// Allocate appropriate buffer to store compressed image
std::shared_ptr node(new DataNode(map.size));

memmove(node->pData.get(), map.data, map.size);
node->pts = GST_BUFFER_PTS(buffer);
gst_buffer_unmap(buffer, &map);
gst_sample_unref(sample);

node->used = map.size;

return node;
}

int main(int argc, char *argv)
{

setvbuf(stdout, 0, _IONBF, 0);

int  width = atoi(argv[2]);
int  height = atoi(argv[3]);

// Validate command line arguments
if (width < 100 || width > 4096 || height < 100 || height > 4096) {
  fprintf(stderr,
          "width and/or height or quality is bad, not running conversion\n");
  return -1;
}


int img_size = width * height * 3 / 2;

std::shared_ptr<DataNode> node(new DataNode(img_size));

FILE * fi = fopen(argv[1], "rb");
if (fi)
{
    fread(node->pData.get(), 1, img_size, fi);
    fclose(fi);
    node->used = img_size;
}
else
{
    fprintf(stderr, "openfile  %s fail", argv[1]);
    return -1;
}



CGstEnc enc;
enc.StartEnc(width, height, 10);

int64_t pts = 0;
for(int i= 0; i< 60; i++)
{
    node->pts = pts;
    enc.PushBuffer(node);
    pts += 3600;
    usleep(30*1000);

    std::shared_ptr<DataNode> data = enc.PullBuffer();

    if (data != NULL)
    {
        printf("%d %x  len %d pts:%lld\n",

            i, data->pData.get()[4] , data->used, data->pts);
    }
    else
    {

    }
}

enc.StopEnc();


return 0;

}

  1. question: 170K * 30(framerate) * 8(byte to bit) = 40Mbit/s, this is bigger than 1Mbit/s I set, why?

Hi,
Please try to configure qp-range. You may set qp-range=“35,51:35,51:-1,-1”
https://devtalk.nvidia.com/default/topic/1054909/jetson-nano/increase-quality-of-h-265-encoding-question-/post/5347626/#5347626

1Mbps is very strict for 1080p30. Suggest you try larger bitrate setting.
We have seen minimum in 1.5Mbps at high motion case:
https://devtalk.nvidia.com/default/topic/973295/jetson-tx1/constant-bitrate-help/post/5011599/#5011599

I change to this pipline : pipeline = gst_parse_launch(“appsrc name=appsrc0 ! videoparse width=1920 height=1080 format=nv12 ! omxh264enc bitrate=1300000 qp-range=“40,51:40,51:-1,-1” preset-level=4 ! video/x-h264,stream-format=(string)byte-stream ! appsink name=appsink0”, NULL);

the bitrate don’t change .

Hi,
Do you set ‘buffer->pts’ in your appsrc? For 30fps, it has to be configured in 33ms interval. Here is a sample.