invalid FPS detected from an AppSrc that is generating FLV

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

invalid FPS detected from an AppSrc that is generating FLV

Brian Dilley
I have an app that implements the RTMP protocol from an ingestion/server perspective.  This app properly implements the RTMP protocol and assembles messages for the other parts of my app to handle.  Currently I'm taking all of the video and audio messages and writing their payloads to an AppSrc in FLV format.

My app src is created like this:

        GstElement* ret = make_element("appsrc", name);
        GstCaps* parsedCaps = gst_caps_from_string("video/x-flv");
                     "caps",            parsedCaps,
                     "is-live",         true,
                     "block",           false,
                     "format",          GST_FORMAT_BYTES,
                     "duration",        GST_CLOCK_TIME_NONE,
                     "stream-type",     GST_APP_STREAM_TYPE_STREAM,
                     "max-bytes",       200000000,

I initially write an FLV header and an onMetaData tag to the appsrc giving it details like framerate, bitrate, etc.  Then for every video and audio message coming over the RTMP wire I write a corrosponding FLV tag to the app src.

The app source feeds into a decodebin and then further down to some other stuff.  The problem that I'm having is that the decodebin detects the framerate of the FLV incorrectly.  It's doing it at ~17 fps when it's really at ~30fps.  This results in the stream having the appearance of being much slower than it actually is.  I'm curious if I'm potentially missing something obvious with decodebin.

During debugging I wrote the FLV data to a file as well.  I found that playback of that file in vlc was also incorrectly assuming ~17fps however FFPlay (ffmpeg) played the file correctly (and ffprobe showed the correct framerate information).

Incase it's helpful, follows is the rest of my pipeline, each of the bins get stitched together in real time as the pipeline comes to life (this->input is the AppSrc element, and in this case this->output happens to be an rtmpsink):

    string decoderBinDesc = std::string("")
            + "queue name=input "
            + "   ! decodebin name=output ";

    string videoFilterBinDesc = std::string("")
            + "videoconvert name=input "
            + "   ! video/x-raw,format=" + frameFormat + " "
            + "   ! streamhubvideofilter name=output ";

    string videoEncoderBinDesc = std::string("")
            + "videoconvert name=input "
            + (!enableHwAccel
                ? "   ! x264enc bitrate=6000 pass=0 speed-preset=1 option-string=\"subq=4:bframes=2:b_pyramid=normal:weight_b\" "
                  "   ! video/x-h264,stream-format=avc,profile=main "
                : "   ! nvh264enc preset=low-latency-hp "
                  "   ! video/x-h264,profile=main ")
            + "   ! h264parse name=output ";

    string audioEncoderBinDesc = std::string("")
            + "audioconvert name=input "
            + "   ! audio/x-raw,channels=2 "
            + "   ! avenc_aac "
            + "   ! audio/mpeg,channels=2 "
            + "   ! aacparse name=output ";

    string muxerBinDesc = std::string("")
            + "multiqueue name=input max-size-bytes=0 "
            + "   ! flvmux name=output streamable=true ";

        this->decoderBin        = parse_bin(decoderBinDesc, false, "DecoderBin");
        this->videoFilterBin    = parse_bin(videoFilterBinDesc, false, "VideoFilterBin");
        this->videoEncoderBin   = parse_bin(videoEncoderBinDesc, false, "VideoEncoderBin");
        this->audioEncoderBin   = parse_bin(audioEncoderBinDesc, false, "AudioEncoderBin");
        this->muxerBin          = parse_bin(muxerBinDesc, false, "MuxerBin");
        this->input             = inputFactory("input");
        this->output            = outputFactory("output");

gstreamer-devel mailing list
[hidden email]