[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gstreamer-devel
Subject:    fdsrc from python socket ?
From:       Adrien Aubourg <adrien.aubourg () gmail ! com>
Date:       2014-03-29 17:56:34
Message-ID: CAAf7ACpFHNTfH-W3QQeDrv09x_63uiRVAzHb7A+DNq_RRCoo_g () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Heya !

Prior to the brand new version of Python which include the new asyncio
module, I wanted to play a bit around a server/client streaming
architecture using multifdsink and fdsrc.

If I use udpsink/udpsrc and tcpsink/tcpsrc, streamings work as expected.
But if I use created socket (TCP connection) from Python asyncio module (or
just with the Python socket module), I can't make it work anymore:

The sender sends gstreamer buffer to multifdsink. By looking at the client
socket, I can see the buffer flowing. By putting a filesink just behing the
fdsrc, the dump is not null. But once I put any element behind the fdsrc
(like an encoder for instance), the filesink is null.

I read this blog entry [1], and I'm pretty sure that the file descriptor is
not freed, I still keep a reference to it. The author use gdppay/gdpdepay
around the socket sink/src element. I did that and there were no buffer
from gdpdepay (filesink file is empty, but it's not if I put it right after
the fdsrc).

Python scripts are attached (Python3.4 only !).

Thank you very much !
Adrien

[1] http://base-art.net/Articles/107/

[Attachment #5 (text/html)]

<div dir="ltr"><div><div><div>Heya !<br><br></div>Prior to the brand new version of \
Python which include the new asyncio module, I wanted to play a bit around a \
server/client streaming architecture using multifdsink and fdsrc.<br> <br></div>If I \
use udpsink/udpsrc and tcpsink/tcpsrc, streamings work as expected. But if I use \
created socket (TCP connection) from Python asyncio module (or just with the Python \
socket module), I can&#39;t make it work anymore:<br> <br></div><div>The sender sends \
gstreamer buffer to multifdsink. By looking at the client socket, I can see the \
buffer flowing. By putting a filesink just behing the fdsrc, the dump is not null. \
But once I put any element behind the fdsrc (like an encoder for instance), the \
filesink is null.<br> <br></div><div>I read this blog entry [1], and I&#39;m pretty \
sure that the file descriptor is not freed, I still keep a reference to it. The \
author use gdppay/gdpdepay around the socket sink/src element. I did that and there \
were no buffer from gdpdepay (filesink file is empty, but it&#39;s not if I put it \
right after the fdsrc).<br> <br></div><div>Python scripts are attached (Python3.4 \
only !).<br><br></div><div>Thank you very much \
!<br></div><div>Adrien<br></div><div><br>[1] <a \
href="http://base-art.net/Articles/107/">http://base-art.net/Articles/107/</a><br> \
</div></div>

--e89a8ffba0ed04e07504f5c28abd--


["client.py" (text/x-python)]

#!/usr/bin/python3

import asyncio, threading
from gi.repository import GObject, Gst

connList = {}

def createPipeline(conn):
    """ Function doc """
    print('creating pipe')
    print('sockno: {}'.format(connList[conn]))
    pipe = Gst.Pipeline()
    src = Gst.ElementFactory.make('fdsrc', None)
    enc = Gst.ElementFactory.make('x264enc', None)
    sink = Gst.ElementFactory.make('filesink', None)
    src.set_property('fd', connList[conn])
    sink.set_property('location', 'test')
    pipe.add(src)
    pipe.add(enc)
    pipe.add(sink)
    src.link(enc)
    enc.link(sink)
    pipe.set_state(Gst.State.PLAYING)

class EchoClient(asyncio.Protocol):
    
    def __init__(self):
        """ Function doc """
        super().__init__()

    def connection_made(self, transport):
        print('connection made: {}'.format(transport.get_extra_info('peername')))
        print('creating pipeline')
        connList[self] = transport.get_extra_info('socket').fileno()
        createPipeline(self)

    def connection_lost(self, exc):
        print('server closed the connection')
        del connList[self]
        asyncio.get_event_loop().stop()
        
    def data_received(self, data):
        print(len(data))


if __name__ == "__main__":
    GObject.threads_init()
    Gst.init(None)
    gstThread = threading.Thread(target=GObject.MainLoop().run, daemon=True)
    gstThread.start()
    
    mainLoop = asyncio.get_event_loop()
    coro = mainLoop.create_connection(EchoClient, '127.0.0.1', 12000)
    mainLoop.run_until_complete(coro)
    mainLoop.run_forever()
    mainLoop.close()


["server.py" (text/x-python)]

#!/usr/bin/python3

import asyncio, threading
from gi.repository import GObject, Gst

DEFAULT_HOST = '127.0.0.1'
DEFAULT_PORT = 12000

connList = {}

def createPipeline(conn):
    """ Function doc """
    print('creating pipe')
    print('sockno: {}'.format(connList[conn]))
    pipe = Gst.Pipeline()
    src = Gst.ElementFactory.make('videotestsrc', None)
    sink = Gst.ElementFactory.make('multifdsink', None)
    sink.set_property('sync-method',0)
    pipe.add(src)
    pipe.add(sink)
    src.link(sink)
    pipe.set_state(Gst.State.READY)
    sink.emit('add', connList[conn])
    pipe.set_state(Gst.State.PLAYING)

class PyVicoServer(asyncio.Protocol):
    """ Class doc """
    
    def __init__(self):
        """ Function doc """
        super().__init__()
        
    def connection_made(self, transport):
        """ Function doc """
        print('new connection from {}'.format(transport.get_extra_info('peername')))
        connList[self] = transport.get_extra_info('socket').fileno()
        print(connList)
        createPipeline(self)

    def connection_lost(self, info):
        """ Function doc """
        print('lost connection: {}'.format(info))
        del connList[self]
        print(connList)

if __name__ == "__main__":
    GObject.threads_init()
    Gst.init(None)
    gstThread = threading.Thread(target=GObject.MainLoop().run, daemon=True)
    gstThread.start()
    
    mainLoop = asyncio.get_event_loop()
    serverCoroutine = mainLoop.create_server(PyVicoServer, DEFAULT_HOST, DEFAULT_PORT)
    mainLoop.run_until_complete(serverCoroutine)
    
    try:
        mainLoop.run_forever()
    except KeyboardInterrupt:
        print('exit')
    finally:
        serverCoroutine.close()
        mainLoop.close()


_______________________________________________
gstreamer-devel mailing list
gstreamer-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic