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

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

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 事件,类似于:

private static void AppSink_NewSample(object o, NewSampleArgs args)
{
   
    if (o is AppSink aps)
    {
        var sample = aps.PullSample();
        var buf = sample.Buffer;
        buf.Map(out var info, MapFlags.Read);
 
        //application/x-rtp
        var tsMeta = buf.GetReferenceTimestampMeta();
        //NOTE tsMeta 不应为 null...
        //TODO 一些时间戳比较逻辑

        buf.Unmap(info);
    }

    Counter++;
}

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

提前感谢。

英文:

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:

  private static void AppSink_NewSample(object o, NewSampleArgs args)
    {
       
        if (o is AppSink aps)
        {
            var sample = aps.PullSample();
            var buf = sample.Buffer;
            buf.Map(out var info, MapFlags.Read);
     
            //application/x-rtp
            var tsMeta = buf.GetReferenceTimestampMeta();
            //NOTE tsMeta shouldn't be null there...
            //TODO some timestamps compare logic

            buf.Unmap(info);
        }

        Counter++;
    }

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

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

var appSink = (AppSink)readerPipe.GetByName("my_appsink");
readerPipe.SetName("frame_stepper");
var q = readerPipe.SetState(State.Playing);

var step = 1;
while (step < frameNumber)
{
    appSink.PullSample();
    step++;
}
英文:

I found the way, it is smth like:

            var appSink = (AppSink) readerPipe.GetByName(&quot;my_appsink&quot;);
            readerPipe.SetName($&quot;frame_stepper&quot;);
            var q = readerPipe.SetState(State.Playing);

            var step = 1; 
            while (step &lt; frameNumber)
            {
                appSink.PullSample();
                step++;
            }

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:

确定