关于ffmedia ,请问图像转发的过程中,怎么添加自己的图像处理过程

我是用python开发,在itx-3588j上运行程序,要用这个ff_pymedia对输入的视频,进行处理后,再发送到输出口,目前看文档 ,所有的组件,都是派生于ModuleMedia,想问一下,这个组件,怎么添加一个自定义图像处理的功能阿?
我想对输入的视频画面,自动添加一些字幕或者logo后,再发送到输出端,查看了接口文档,setOutputDataCallback和addExternalConsumer都不太行,想请教一下,应该从哪里解决这个问题?

这种需求应该不复杂,参考demo里的rga范例,在rga层添加前景图文进行合成

可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有设置回调)再输出给他的消费者模块。在回调中使用传进来的buffer 获取数据getActiveData,该接口返回的是np数组,你可以使用cv操作该数组,更改里面的内容,他的消费者模块会接收到你更改后的buffer。

nboxcn 发表于 2024-3-7 10:01
这种需求应该不复杂,参考demo里的rga范例,在rga层添加前景图文进行合成

哇哇,多谢大佬指导,去看了demo_rgablend.cpp里代码,主要是设置了一个setBlendCallback,然后下面这是我改成python版本的回调代码,这个代码运行倒是不报错,但是做的添加字幕的功能,也没生效,大佬可以帮忙看看么?另外方便的话,请求可以加一下微信详细聊吗?309934668,这是我微信号,多谢多谢

def callback_blendv1(obj, MediaBuffer):
vb = m.VideoBuffer.from_base(MediaBuffer)
print(‘t1’,vb)
#data = vb.getActiveData()
buf = vb.getData()
try:
img = buf.reshape((vb.getImagePara().vstride, vb.getImagePara().hstride, 3))
except ValueError:
exit(-1)
buf_fd = vb.getBufFd() # 为4
cv2.putText(buf, ‘test word’, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv2.LINE_AA)
vb.flushDrmBuf()
rag = m.ModuleRga()
rag.setPatBuffer(buf_fd,m.RGA_BLEND_MODE.BLEND_DST_OVER)

dengkx 发表于 2024-3-7 11:20
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有 …

我之前就是找不到添加回调函数的地方,刚刚经过提醒,参考demo里的demo_rgablend.cpp,利用setBlendCallback添加回调,然后参考着c的代码,写了python版本的代码,但是目前回调函数确实被调用了,就是对图像做的改动,没有生效,可以帮忙看看问题原因么{:4_96:},如果可以的话,可以加下微信好友吗?309934668,这是我微信,多谢多谢

dengkx 发表于 2024-3-7 11:20
可以设置输出回调函数,每个模块会处理生产者模块的数据生成对应buffer,该buffer会先经过回调函数(如果有 …

大佬在么?请问回调函数怎么添加阿?可以给个代码示例吗?cpp或者python的都行,这块实在搞不定阿

本帖最后由 dengkx 于 2024-3-8 11:40 编辑

chenwusong 发表于 2024-3-8 10:05
大佬在么?请问回调函数怎么添加阿?可以给个代码示例吗?cpp或者python的都行,这块实在搞不定阿

将demo.py做以下更改:
diff --git a/demo/demo.py b/demo/demo.py
index 2219ba4..42a7b69 100644
— a/demo/demo.py
+++ b/demo/demo.py
@@ -57,6 +57,9 @@ def cv2_extcall_back(obj, MediaBuffer):
resolution = find_two_numbers(data.size//3, vb.getImagePara().hstride, vb.getImagePara().vstride)
print(“Try the recommended resolution: -o {}x{}”.format(resolution[0], resolution[1]))
exit(-1)
+

  • cv2.putText(img, ‘test word’, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv2.LINE_AA)
  • vb.flushDrmBuf()
    for i in range(obj.count):
    cv2.imshow(obj.name + str(i), img)
    cv2.waitKey(1)
    @@ -221,9 +224,22 @@ def main():
    print(“Output image format is not ‘BGR24’, Use the ‘-b BGR24’ option to specify image format.”)
    return 1
    cv_display = Cv2Display(“Cv2Display”, None, sync, args.cvdisplay)
  •        cv_display.module = last_module.addExternalConsumer("Cv2Display", cv_display, cv2_extcall_back)
    
  •        #cv_display.module = last_module.addExternalConsumer("Cv2Display", cv_display, cv2_extcall_back)
    
  •        last_module.setOutputDataCallback(cv_display, cv2_extcall_back)
    

    if args.encodetype != -1:

  •    input_para = last_module.getOutputImagePara()
    
  •    if input_para.v4l2Fmt != m.v4l2GetFmtByName("NV12"):
    
  •        output_para = input_para
    
  •        output_para.v4l2Fmt = m.v4l2GetFmtByName("NV12")
    
  •        encRga = m.ModuleRga(output_para,  m.RgaRotate(0))
    
  •        encRga.setProductor(last_module)
    
  •        ret = encRga.init()
    
  •        if ret < 0:
    
  •            print("rga init failed")
    
  •            return 1
    
  •        last_module = encRga
    
  •    enc = m.ModuleMppEnc(m.EncodeType(args.encodetype))
       enc.setProductor(last_module)
       enc.setBufferCount(8)
    

使用命令:./demo.py -i ../firefly.mp4 -b BGR24 -c 1 -s 1 -e 0 -m out.mp4
-i指向你要播放的文件或者流,cv显示并将保存文件。可以看到cv显示的画面有添加的内容,并且其他工具播放保存的out.mp4也可看到添加的内容。
demo主要更改:

  1. cv回调中增加向视频帧添加文字,然后将添加的内容从cpu端刷新到dma端(flushDrmBuf)。
  2. 将cv显示部分从添加外部消费者更改到rga回调里,这样cv处理后的数据就能同步输出到rga模块的消费者模块。
  3. h264或h265编码需要YUV数据,添加rga模块将BGR24格式数据转成YUV数据给编码模块。

dengkx 发表于 2024-3-8 11:15
将demo.py做以下更改:
diff --git a/demo/demo.py b/demo/demo.py
index 2219ba4..42a7b69 100644

哇哇哇,多谢大佬提醒,看了大佬的代码,明白了一些原理,通过setOutputDataCallback可以设置图像的输出,不过需要把输出作为新的Producer,传给后面的显示器,才能生效。另外就是对图像的一些操作,不影响图像所在的内存地址,所以更改后的图像,才会往后传输。目前已经调通了代码,把更改后的图像,顺利显示在了显示器上。

另外有个新的问题,这是我更改图像的代码,如果我想对整个图像替换,目前的方法是,通过循环,重新给img进行赋值(即需要保证img的内存地址不变),实现图像的替换,请问有别的显式的方法,直接替换图像的方法吗?看了api,感觉setData、setActiveData这些函数像是显式的重新给图像赋值,但是直接传递图像np数组进去,又报错{:4_105:}
cv2.putText(img, ‘test word’, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv2.LINE_AA)

# 内存地址不变的情况下,把图像内容替换为新的内容
for i in range(img.shape[0]):
    img[i]=default_img[i]

#print(img.shape,default_img.shape)

vb.flushDrmBuf()