简体   繁体   中英

Gstreamer Python: pipeline not receiving EOS

I'm new to Gstreamer. I'm making a simple pipeline to record both video and audio. The pipeline should run for a pre-determined duration, then stop properly with an EOS event.

I check my log and see the EOS is properly fired every time. However, sometime the pipeline doesn't stop and keep running forever. What is the problem?

My code:

import sys

import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib

# Initializes Gstreamer, it's variables, paths
Gst.init(sys.argv)
GObject.threads_init()


def end_recording(_a, _b, _c, pipeline):
    logger.info('Timer fired, sending EOS...')
    pipeline.send_event(Gst.Event.new_eos())
    return False


def handle_gstreamer_message(_bus: Gst.Bus, message: Gst.Message, loop: GObject.MainLoop):
    """Show ERROR, WARN or message during the capture."""
    message_type = message.type
    # GStreamer Message Types and how to parse
    # https://lazka.github.io/pgi-docs/Gst-1.0/flags.html#Gst.MessageType
    if message_type == Gst.MessageType.EOS:
        logger.info('End of stream')
        loop.quit()
    elif message_type == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        logger.error(err)
        logger.debug(debug)
        loop.quit()
    elif message_type == Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        logger.error(err)
        logger.debug(debug)
    return True


def capture(
        output_path: str,
        frame_height: int = 0,
        frame_width: int = 0,
        record_time_seconds: int = 0,
) -> int:

    return_code = os.EX_OK
    loop = None
    pipeline = (
        f'v4l2src'
        f' ! videorate'
        f' ! video/x-raw, height={frame_height}, width={frame_width}, framerate={fps}/1'
        f' ! nvvidconv'
        f' ! omxh264enc'
        f' ! mux. '
        f'pulsesrc device={audio_device}'
        f' ! audio/x-raw, rate=44100, channels=2, width=32, depth=32'
        f' ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0'
        f' ! lamemp3enc bitrate=256'
        f' ! mux. '
        f'qtmux name=mux'
        f' ! filesink location={output_path}'
    )
    logger.debug(pipeline)

    try:
        pipeline = Gst.parse_launch(pipeline)
        bus = pipeline.get_bus()
        clock = pipeline.get_pipeline_clock()
        recording_end_time = clock.get_time() + record_time_seconds * 1000000000
        trigger = Gst.SystemClock.new_single_shot_id(clock, recording_end_time)
        Gst.Clock.id_wait_async(trigger, end_recording, pipeline)

        bus.add_signal_watch()
        pipeline.set_state(Gst.State.PLAYING)
        loop = GObject.MainLoop()
        bus.connect('message', handle_gstreamer_message, loop)

        loop.run()

    except GLib.Error:
        logger.error(f'GLib exception occurred while  capturing {output_path}', exc_info=True)
        return_code = os.EX_CANTCREAT
    except IOError:
        logger.error(f'IO exception occurred while capturing {output_path}', exc_info=True)
        return_code = os.EX_IOERR
    except MemoryError:
        logger.error(f'Memory exception occurred while capturing {output_path}', exc_info=True)
        return_code = os.EX_CANTCREAT
    finally:
        if loop is not None and loop.is_running():
            loop.quit()
        if pipeline is not None:
            pipeline.set_state(Gst.State.NULL)
        if return_code == os.EX_OK:
            logger.info(f'Video saved at {output_path}')
        if return_code != os.EX_OK:
            return return_code

    return return_code

The issue seems to be from the deprecated omxh264enc . The code was running on an NVIDIA Jetson Nano. After changing omxh264enc to nvv4l2h264enc , the problem went away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM