GStreamer: how to read mp4 frame by frame and extract capture (camera) time? Need to find closest to given ts frame

huangapple go评论126阅读模式
英文:

GStreamer: how to read mp4 frame by frame and extract capture (camera) time? Need to find closest to given ts frame

问题

给定一些时间戳(可能是秒或毫秒精度),我需要从 mp4 文件中提取与假定的摄像头时间戳(捕获时间,而不是 pts 或 dts)最接近的帧,那么更合适的流程是什么,以提取每个帧在其捕获时间戳内(类似于使用缓冲区中的 GetReferenceTimestampMeta)?考虑到我使用 gstreamer-sharp,我希望使用 appsink 事件,类似于:

  1. private static void AppSink_NewSample(object o, NewSampleArgs args)
  2. {
  3. if (o is AppSink aps)
  4. {
  5. var sample = aps.PullSample();
  6. var buf = sample.Buffer;
  7. buf.Map(out var info, MapFlags.Read);
  8. //application/x-rtp
  9. var tsMeta = buf.GetReferenceTimestampMeta();
  10. //NOTE tsMeta 不应为 null...
  11. //TODO 一些时间戳比较逻辑
  12. buf.Unmap(info);
  13. }
  14. Counter++;
  15. }

简而言之,我需要遍历帧并基于某些条件(实际上是最接近给定时间戳的条件)选择其中之一。

提前感谢。

英文:

Given some timestamp (probably second or ms precision), I need to exctract closest frame
in mp4 file with assumed camera timestamp(captured time, not pts or dts) for each frame, what is a more appropriate pipeline to exctract each frame within it's captured timestamp (smth like to use GetReferenceTimestampMeta from buffer)? Given that I work via gstreamer-sharp I expect to use appsink events, smth like:

  1. private static void AppSink_NewSample(object o, NewSampleArgs args)
  2. {
  3. if (o is AppSink aps)
  4. {
  5. var sample = aps.PullSample();
  6. var buf = sample.Buffer;
  7. buf.Map(out var info, MapFlags.Read);
  8. //application/x-rtp
  9. var tsMeta = buf.GetReferenceTimestampMeta();
  10. //NOTE tsMeta shouldn't be null there...
  11. //TODO some timestamps compare logic
  12. buf.Unmap(info);
  13. }
  14. Counter++;
  15. }

Put it simple -- I need to iterate over frames and select one based on some condition (actually, closest to given timestamp).

Thanks in advance.

答案1

得分: 0

我找到了方法,它类似于:

  1. var appSink = (AppSink)readerPipe.GetByName("my_appsink");
  2. readerPipe.SetName("frame_stepper");
  3. var q = readerPipe.SetState(State.Playing);
  4. var step = 1;
  5. while (step < frameNumber)
  6. {
  7. appSink.PullSample();
  8. step++;
  9. }
英文:

I found the way, it is smth like:

  1. var appSink = (AppSink) readerPipe.GetByName(&quot;my_appsink&quot;);
  2. readerPipe.SetName($&quot;frame_stepper&quot;);
  3. var q = readerPipe.SetState(State.Playing);
  4. var step = 1;
  5. while (step &lt; frameNumber)
  6. {
  7. appSink.PullSample();
  8. step++;
  9. }

huangapple
  • 本文由 发表于 2023年7月13日 16:52:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76677554.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定