Frame Stepping

Brian Panneton brian.panneton at gmail.com
Mon Aug 15 16:16:03 UTC 2016


I realized that I'm ending early with pos == last because multiple frames
seem to have the same date. Is this supposed to happen? I'm really hoping
there is an easy way to determine the end of the stream while in PAUSED
mode.

Thanks,
Brian

On Thu, Aug 11, 2016 at 5:10 PM, Brian Panneton <brian.panneton at gmail.com>
wrote:

> All,
>
> I've been trying to step through frame by frame with one pipeline and pass
> through to another. Basically I want to look at every h264 frame and then
> pipe it off into a filesink. I have made an example of what I thought would
> work below.
>
> It should take an MKV file, step thought the h264 frames and pipe them to
> a MP4 file without missing any frames (It is important that I get the
> actual frames here). So the first pipeline is in PAUSE mode and the second
> pipeline is in PLAYING (I don't think writing to a file can be done in
> paused mode?). I understand I could do this by removing the appsink->appsrc
> but that is not what I am looking for and wont work in my application.
>
> My big problem at the moment is that I can't seem to determine when the
> end-of-stream occurs since I am in paused mode. My best attempt was to use
> pos > dur, but I have found this isn't always true. In the current case I
> either end early or never end (when I remove the pos == last section). If
> there is a better way to do this I would appreciate any ideas. Sample code
> is below! Sample MKV file: http://jell.yfish.us/media/jel
> lyfish-25-mbps-hd-h264.mkv
>
> <code>
> from gi.repository import Gst, GObject
> import sys
> import os
> import glob
>
> def test_file(inc):
>     filename = "jellyfish-25-mbps-hd-h264.mkv"
>     elements = {}
>
>     def demuxer_callback(demuxer, pad):
>         if pad.get_property("template").name_template == "video_%u":
>             pad.link(elements['h264parse'].get_static_pad("sink"))
>
>     #GObject.threads_init()
>     Gst.init()
>     Gst.debug_set_active(True)
>     Gst.debug_set_default_threshold(1)
>     pipeline_front = Gst.Pipeline()
>     pipeline_end = Gst.Pipeline()
>
>     elements['filesrc'] = Gst.ElementFactory.make('filesrc',
> str(inc)+'_filesrc')
>     elements['filesrc'].set_property('location', filename)
>     elements['matroskademux'] = Gst.ElementFactory.make('matroskademux',
> str(inc)+'_matroskademux')
>     elements['matroskademux'].connect('pad-added', demuxer_callback)
>     elements['h264parse'] = Gst.ElementFactory.make('h264parse',
> str(inc)+'_h264parse')
>     elements['raw1queue'] = Gst.ElementFactory.make('queue',
> str(inc)+'_raw1queue')
>     elements['innersink'] = Gst.ElementFactory.make('appsink',
> str(inc)+'_appsink')
>
>     elements['mp4appsrc'] = Gst.ElementFactory.make('appsrc')
>     elements['mp4h264parse'] = Gst.ElementFactory.make('h264parse')
>     elements['mp4queue'] = Gst.ElementFactory.make('queue')
>     elements['mp4mux'] = Gst.ElementFactory.make('mp4mux')
>     elements['mp4mqueue'] = Gst.ElementFactory.make('queue')
>     elements['mp4filesink'] = Gst.ElementFactory.make('filesink')
>     elements['mp4filesink'].set_property('location', "{}.mp4".format(inc))
>
>     pipeline_front.add(elements['filesrc'])
>     pipeline_front.add(elements['matroskademux'])
>     pipeline_front.add(elements['h264parse'])
>     pipeline_front.add(elements['raw1queue'])
>     pipeline_front.add(elements['innersink'])
>
>     pipeline_end.add(elements['mp4appsrc'])
>     pipeline_end.add(elements['mp4h264parse'])
>     pipeline_end.add(elements['mp4queue'])
>     pipeline_end.add(elements['mp4mux'])
>     pipeline_end.add(elements['mp4mqueue'])
>     pipeline_end.add(elements['mp4filesink'])
>
>     elements['filesrc'].link(elements['matroskademux'])
>     elements['matroskademux'].link(elements['h264parse'])
>     elements['h264parse'].link(elements['raw1queue'])
>     elements['raw1queue'].link(elements['innersink'])
>
>     elements['mp4appsrc'].link(elements['mp4queue'])
>     elements['mp4queue'].link(elements['mp4h264parse'])
>     elements['mp4h264parse'].link(elements['mp4mux'])
>     elements['mp4mux'].link(elements['mp4mqueue'])
>     elements['mp4mqueue'].link(elements['mp4filesink'])
>
>     pipeline_front.set_state(Gst.State.READY)
>     pipeline_front.set_state(Gst.State.PAUSED)
>
>     pipeline_end.set_state(Gst.State.READY)
>     pipeline_end.set_state(Gst.State.PAUSED)
>     pipeline_end.set_state(Gst.State.PLAYING)
>     print 'Front Setup Status:', pipeline_front.get_state(Gst.C
> LOCK_TIME_NONE)[0]
>     print 'Start', inc
>     completed = False
>     last = None
>     while True:
>         if not completed:
>             pipeline_front.get_state(Gst.CLOCK_TIME_NONE)[0]
>             elements['innersink'].send_event(Gst.Event.new_step(Gst.Format.BUFFERS,
> 1, 1, True, False))
>             inner_sample = elements['innersink'].emit('pull-preroll')
>             inner_buffer = inner_sample.get_buffer()
>             elements['mp4appsrc'].set_property('caps',
> inner_sample.get_caps())
>             elements['mp4appsrc'].emit('push-buffer', inner_buffer)
>
>         # Check position for completion
>         # Can't figure out how to tell there are no more frames
>         pos = elements['innersink'].query_position(Gst.Format.TIME)[1]
>         dur = elements['innersink'].query_duration(Gst.Format.TIME)[1]
>         print 'Loc:', pos, dur
>
>         if pos > dur:
>             completed = True
>         if pos == last:
>             completed = True
>
>         bus = pipeline_front.get_bus()
>         while True:
>             message = bus.pop_filtered(Gst.MessageType.ANY)
>             if not message:
>                 break
>             elif message.type in [Gst.MessageType.EOS]:
>                 completed = True
>                 break
>
>         # Close stream if completed
>         if completed:
>             elements['mp4appsrc'].emit('end-of-stream')
>             break
>         last = pos
>
>     pipeline_front.set_state(Gst.State.NULL)
>     pipeline_end.set_state(Gst.State.NULL)
>     print 'End', inc, pos, dur
>
> test_file(0)
> </code>
>
> Thanks,
> Brian
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160815/edc0cb2a/attachment.html>


More information about the gstreamer-devel mailing list