<div dir="ltr"><div><div>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.<br><br></div>Thanks,<br></div>Brian<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 11, 2016 at 5:10 PM, Brian Panneton <span dir="ltr"><<a href="mailto:brian.panneton@gmail.com" target="_blank">brian.panneton@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div>All,<br><br></div>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.<br><br></div>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.<br><br></div>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: <a href="http://jell.yfish.us/media/jellyfish-25-mbps-hd-h264.mkv" target="_blank">http://jell.yfish.us/media/jel<wbr>lyfish-25-mbps-hd-h264.mkv</a><br><br></div><div><code><br>from gi.repository import Gst, GObject<br>import sys<br>import os<br>import glob<br><br>def test_file(inc):<br>    filename = "jellyfish-25-mbps-hd-h264.mkv<wbr>"<br>    elements = {}<br><br>    def demuxer_callback(demuxer, pad):<br>        if pad.get_property("template").n<wbr>ame_template == "video_%u":<br>            pad.link(elements['h264parse']<wbr>.get_static_pad("sink"))<br><br>    #GObject.threads_init()<br>    Gst.init()<br>    Gst.debug_set_active(True)<br>    Gst.debug_set_default_threshol<wbr>d(1)<br>    pipeline_front = Gst.Pipeline()<br>    pipeline_end = Gst.Pipeline()<br><br>    elements['filesrc'] = Gst.ElementFactory.make('files<wbr>rc', str(inc)+'_filesrc')<br>    elements['filesrc'].set_proper<wbr>ty('location', filename)<br>    elements['matroskademux'] = Gst.ElementFactory.make('matro<wbr>skademux', str(inc)+'_matroskademux')<br>    elements['matroskademux'].conn<wbr>ect('pad-added', demuxer_callback)<br>    elements['h264parse'] = Gst.ElementFactory.make('h264p<wbr>arse', str(inc)+'_h264parse')<br>    elements['raw1queue'] = Gst.ElementFactory.make('queue<wbr>', str(inc)+'_raw1queue')<br>    elements['innersink'] = Gst.ElementFactory.make('appsi<wbr>nk', str(inc)+'_appsink')<br><br>    elements['mp4appsrc'] = Gst.ElementFactory.make('appsr<wbr>c')<br>    elements['mp4h264parse'] = Gst.ElementFactory.make('h264p<wbr>arse')<br>    elements['mp4queue'] = Gst.ElementFactory.make('queue<wbr>')<br>    elements['mp4mux'] = Gst.ElementFactory.make('mp4mu<wbr>x')<br>    elements['mp4mqueue'] = Gst.ElementFactory.make('queue<wbr>')<br>    elements['mp4filesink'] = Gst.ElementFactory.make('files<wbr>ink')<br>    elements['mp4filesink'].set_pr<wbr>operty('location', "{}.mp4".format(inc))<br><br>    pipeline_front.add(elements['f<wbr>ilesrc'])<br>    pipeline_front.add(elements['m<wbr>atroskademux'])<br>    pipeline_front.add(elements['h<wbr>264parse'])<br>    pipeline_front.add(elements['r<wbr>aw1queue'])<br>    pipeline_front.add(elements['i<wbr>nnersink'])<br><br>    pipeline_end.add(elements['mp4<wbr>appsrc'])<br>    pipeline_end.add(elements['mp4<wbr>h264parse'])<br>    pipeline_end.add(elements['mp4<wbr>queue'])<br>    pipeline_end.add(elements['mp4<wbr>mux'])<br>    pipeline_end.add(elements['mp4<wbr>mqueue'])<br>    pipeline_end.add(elements['mp4<wbr>filesink'])<br><br>    elements['filesrc'].link(eleme<wbr>nts['matroskademux'])<br>    elements['matroskademux'].link<wbr>(elements['h264parse'])<br>    elements['h264parse'].link(ele<wbr>ments['raw1queue'])<br>    elements['raw1queue'].link(ele<wbr>ments['innersink'])<br><br>    elements['mp4appsrc'].link(ele<wbr>ments['mp4queue'])<br>    elements['mp4queue'].link(elem<wbr>ents['mp4h264parse'])<br>    elements['mp4h264parse'].link(<wbr>elements['mp4mux'])<br>    elements['mp4mux'].link(elemen<wbr>ts['mp4mqueue'])<br>    elements['mp4mqueue'].link(ele<wbr>ments['mp4filesink'])<br><br>    pipeline_front.set_state(Gst.S<wbr>tate.READY)<br>    pipeline_front.set_state(Gst.S<wbr>tate.PAUSED)<br><br>    pipeline_end.set_state(Gst.Sta<wbr>te.READY)<br>    pipeline_end.set_state(Gst.Sta<wbr>te.PAUSED)<br>    pipeline_end.set_state(Gst.Sta<wbr>te.PLAYING)<br>    print 'Front Setup Status:', pipeline_front.get_state(Gst.C<wbr>LOCK_TIME_NONE)[0]<br>    print 'Start', inc<br>    completed = False<br>    last = None<br>    while True:<br>        if not completed:<br>            pipeline_front.get_state(Gst.C<wbr>LOCK_TIME_NONE)[0]<br>            elements['innersink'].send_eve<wbr>nt(Gst.Event.new_step(Gst.Form<wbr>at.BUFFERS, 1, 1, True, False))<br>            inner_sample = elements['innersink'].emit('pu<wbr>ll-preroll')<br>            inner_buffer = inner_sample.get_buffer()<br>            elements['mp4appsrc'].set_prop<wbr>erty('caps', inner_sample.get_caps())<br>            elements['mp4appsrc'].emit('pu<wbr>sh-buffer', inner_buffer)<br><br>        # Check position for completion <br>        # Can't figure out how to tell there are no more frames<br>        pos = elements['innersink'].query_po<wbr>sition(Gst.Format.TIME)[1]<br>        dur = elements['innersink'].query_du<wbr>ration(Gst.Format.TIME)[1]<br>        print 'Loc:', pos, dur<br><br>        if pos > dur:<br>            completed = True<br>        if pos == last:<br>            completed = True<br><br>        bus = pipeline_front.get_bus()<br>        while True:<br>            message = bus.pop_filtered(Gst.MessageTy<wbr>pe.ANY)<br>            if not message:<br>                break<br>            elif message.type in [Gst.MessageType.EOS]:<br>                completed = True<br>                break<br><br>        # Close stream if completed <br>        if completed:<br>            elements['mp4appsrc'].emit('en<wbr>d-of-stream')<br>            break<br>        last = pos<br></div><div><br>    pipeline_front.set_state(Gst.S<wbr>tate.NULL)<br>    pipeline_end.set_state(Gst.Sta<wbr>te.NULL)<br>    print 'End', inc, pos, dur<br><br></div><div>test_file(0)<br></div><div></code><br></div><div><br></div>Thanks,<br></div>Brian<br><br><br></div>
</blockquote></div><br></div>