This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MP4 files doesn't play with APPSRC

Hello,

I am trying to play MP4 files on GStreamer. I do have a pipeline that works with FILESRC. Here it is:

gst-launch-1.0 filesrc location=inputfilename.mp4 ! qtdemux name=dmux dmux. ! queue ! h264parse ! ducatih264dec ! kmssink connector=16
dmux. ! queue ! faad ! alsasink


But, when I do it with APPSRC, I get  an error "FILE STREAM NOT SUPPORTED" in the bus call (GST_MESSAGE_ERROR). It seems like APPSRC doesn't link with qtdemux element.

Because of some reasons, I may not be able to use FILESRC.

Kindly help me.

Warm Regards,

Shylesh S.

  • Hello,

    Are you able to play elementary stream with appsrc for example?

    Could you add the full debug log(gst-debug=3)?

    BR
    Margarita
  • Hello,


    What is your pipeline (complete), please provide more details while posting your query.

    Cheers,

    --Prabhakar Lad

  • Dear Margarita/Prabhakar,

    The above mentioned pipeline is my working pipeline for FILESRC.  But, I try to read the .mp4 files using fread() call and then copy it in a buffer, which in turn is pushed into the appsrc buffer using "gst_app_src_push_buffer()". I require this kind of method because, I send my video packets from one node to other through socket. I receive them in the listening end and push them into the appsrc buffer.

    As far as I know, the elements to be used for linking doesn't vary from FILESRC and APPSRC. When I try with the same elements in linking, I see that the stream is not played. I will include the log print here,

    root@dra7xx-evm:/opt/work# ./armmp4
    GSTREAMER ELEMENTS CREATED SUCCESSFULY
    GSTREAMER PC ELEMENTS LINKED SUCCESSFULY
    Video thread created
    going to add pad
    g sig conn succ
    [ 1175.010345] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1
    loop starting..
    GST_MESSAGE_ERROR
    This file is invalid and cannot be played.
    loop end..
    Buffer Injection Failed ret=-2
    Buffer Injection Failed ret=-2

    This is what I get when I try to play.

    I link my elements like this,

     if (!gst_element_link((GstElement*)Access2Player->StreamSource,Access2Player->Demuxer))
                    {
                            printf("ERROR:   Can not link Source and demuxer\n");
                    }
     else if(!gst_element_link_many(Access2Player->VideoQueue,Access2Player->VideoDecoder,Access2Player->VideoConvert, Access2Player->VideoSink, NULL))
                    {
                            printf("ERROR:   Can not link elements to the video pipeline\n");
                    }
    else if(!gst_element_link_many(Access2Player->AudioQueue, Access2Player->AudioDecoder, Access2Player->AudioSink, NULL))
                    {
                            printf("ERROR:   Can not link elements to the audio pipeline\n");
                    }
              else

                    {
                            printf("GSTREAMER PC ELEMENTS LINKED SUCCESSFULY\n");
                    }

     


    I use the same elements, which I used for the FILESRC pipeline. I also happened to see some posts on some forums stating that FILESRC doesn't directly link with qtdemux.

    These are my elements,

    Access2Player->PipeLine = (GstPipeline*)gst_pipeline_new("VideoPlayerPipeline");
    Access2Player->StreamSource = (GstAppSrc*)gst_element_factory_make("appsrc", "StreamSource");

    Access2Player->Demuxer = gst_element_factory_make ("qtdemux","Demuxer");
    Access2Player->AudioDecoder      = gst_element_factory_make("faad","AudioDecoder");
    Access2Player->AudioQueue   = gst_element_factory_make("queue","AudioQueue");

    Access2Player->AudioSink    = gst_element_factory_make("alsasink","AudoSink");
    Access2Player->VideoConvert    = gst_element_factory_make("ducatih264dec","VideoConvert");
    Access2Player->VideoDecoder      = gst_element_factory_make("h264parse","VideoDecoder");

    Access2Player->VideoQueue   = gst_element_factory_make("queue","VideoQueue");
    Access2Player->VideoSink    = gst_element_factory_make("kmssink", "VideoSink");
    g_object_set (Access2Player->VideoSink, "connector", 16, NULL);

     


    Kindly help me,

    Shylesh S.

  • Hello,

    You need to set the caps of your appsrc and also you need to parse it (assuming you are using h264) so you’ll need h264parse element after appsrc.

    Shylesh :
    "I use the same elements, which I used for the FILESRC pipeline. I also happened to see some posts on some forums stating that FILESRC doesn't directly link with qtdemux."

    In your first post you mention you get it working with filesrc with qtdemux linked ??

    Cheers,
    --Prabhakar Lad
  • Prabhakar,

    Yes, With FILESRC qtdemux got linked and the Video plays properly.

    Okay,

    I will try with the caps.

    Thanks,

    Shylesh S.

  • Hello Prabhakar,

    I have tried linking the h264parse element with the appsrc element. I see some positive signs.

    Now, I don't get any error like INTERNAL DATA FLOW error. My GST Loop keeps running. Buffer Injection succeeds. But, the Dynamic Pad linking doesn't get succeeded. I have also set caps as,

    caps = gst_caps_new_simple(" video/x-h264",NULL);

    1. Elements get created successfully.

    2. Elements get linked successfully.

    3. GST Loop keeps running.

    4. Buffer Injection happens properly.

    5. Dynamic Pad not created.

     

    Kindly help me,

    Shylesh S.

     

  • Hello,


    You need to set the proper caps, for example look at the following:

    caps = gst_caps_new_simple ("video/x-h264",
        "framerate", GST_TYPE_FRACTION, 30, 1,
        "stream-format", G_TYPE_STRING, "avc",
        "alignment", G_TYPE_STRING, "nal",
        "width", G_TYPE_INT, 1920,
        "height", G_TYPE_INT, 1080,
        NULL);

    For more info also read this link,

    Cheers,

    --Prabhakar Lad

  • Hello Prabhakar,

    Now I use this caps:

      caps = gst_caps_new_simple ("video/x-h264",

                   "framerate", GST_TYPE_FRACTION, 30, 1,

                   "stream-format", G_TYPE_STRING, "avc",

                   "alignment", G_TYPE_STRING, "nal",

                   "width", G_TYPE_INT, 1920,

                   "height", G_TYPE_INT, 1080,

                   NULL);

    And find them linking properly with the Appsrc and Parser (h264parse).

    Even then my dynamic pad doesn't get created. But the buffer injection always succeeds.  

    This is how I link them:

    gst_element_link_filtered((GstElement*)Access2Player->StreamSource,Access2Player->VideoParser,caps)


    One more query that I have is,

    When it is said to add h264 parser after the appsrc element, then where should the demuxer be added now? I use qtdemux in my FILESRC Pipeline.

    Kindly help me,

    Shylesh S.

  • Hello,


    First you should have demuxer then parser before the decoder.

    ...... ! qtdemux .....! h264parse ! decoder ....


    BR
    Margarita
  • Hello Margarita,

    That was how I did previously. But, was told to add h264parse just after the appsrc element. On doing this and setting the capabilities, I don't find any errors. The buffer injection succeeds. But I couldn't get my dynamic pad linked.

    Regards,
    Shylesh S.
  • Hello,


    what is your dynamic pad ? How are you linking it ?

    Cheers,

    --Prabhakar Lad

  • Hello Prabhakar,

    This is my Dynamic Pad:

    void DynamicPad(GstElement *element, GstPad *NewSourcePad, gpointer UserData)
     {

    GstCaps       *NewSourcePadCaps;
        GstStructure  *NewSourcePadType;
        gchar         *NewSourcePadName;
        GstPad        *VideoQueueSinkPad;
        GstPad        *AudioQueueSinkPad;

        NewSourcePadCaps = gst_pad_get_current_caps(NewSourcePad);
        NewSourcePadType = gst_caps_get_structure(NewSourcePadCaps, 0);
        NewSourcePadName = (gchar*)gst_structure_get_name(NewSourcePadType);
     
        VideoQueueSinkPad = gst_element_get_static_pad(PlayerInform->VideoQueue, "sink");
     
                    if(g_strrstr(NewSourcePadName, "video") )
                    {
                            VideoQueueSinkPad = gst_element_get_static_pad(PlayerInform->VideoQueue, "sink");
     
                            if((gst_pad_link(NewSourcePad, VideoQueueSinkPad)) == GST_PAD_LINK_OK)
                            {
                                    g_print("The decoder's video pad is linked to video decoder's sink pad\n");
                            }
                            else
                            {
                                    printf("\nCan not link the decoder's video pad to video decoder's sink pad\n");
                            }
                    }
                    else if(g_strrstr(NewSourcePadName, "audio"))
                    {
                            AudioQueueSinkPad = gst_element_get_static_pad(PlayerInform->AudioQueue, "sink");
     
                            if((gst_pad_link(NewSourcePad, AudioQueueSinkPad)) == GST_PAD_LINK_OK)
                            {
                                    g_print("The decoder's audio pad is linked to the audio decoder's sink pad\n");
                            }
                            else
                            {
                                    printf("\nCan not link the decoder's audio pad to the audio decoder's sink pad\n");
                            }
                    }
                    else
                    {
                            printf("Unknown Pad\n");
                    }
    }

    Regards,

    Shylesh S.

  • Hello,

    The pipeline appsrc -> h264parse -> qtdemux seems wrong to me.

    Demuxers are the 1-to-N elements.

    On the output of the element you have audio and elementary video.

    In the input of the qtdemux you have "video/quicktime"(you could try to set it in appsrc caps). It expects "video/quicktime".

    On the demux's output video_%u you should have "video/x-h264" for video.

    h264parser element is for h264 video bitstream parsing not for audio+video that is why it seems wrong to me to be before qtdemux.



    BR
    Margarita
  • Hello Margarita,
    I have also tried using "video/quicktime" by setting it in appsrc caps. I see no sign of the stream playing. I either get General Stream Error or Internal Data Flow Error, based on some element changes.

    Kindly help!
    Regards,
    Shylesh S.
  • Hello,

    Can MP4 files can ever be played using APPSRC?

    I get my .mpg file playing in APPSRC, which has its filesrc pipeline as

    gst-launch-1.0 filesrc location=sample.mpg ! tsdemux name=dmux dmux. ! queue ! h264parse ! ducatih264dec ! kmssink connector=16 dmux. ! queue ! faad ! alsasink


    My Filesrc pipeline for .mp4 file is,

    gst-launch-1.0 filesrc location=sample.mp4 ! qtdemux name=dmux dmux. ! queue ! h264parse ! ducatih264dec ! kmssink connector=16 dmux. ! queue ! faad ! alsasink


    I see that DEMUXER is the only change between 2 pipelines. But .mp4 files doesn't work with APPSRC.

    1134.gst_test_mp44.c

    This is my file in which I have implemented .mp4 playing using APPSRC. It doesn't work properly. But, the same works for .mpg files. Kindly help.

    Best Regards,

    Shylesh S.

  • Hello,

    At last I have found something convincing.

    I tried printing the debug messages using,

      gst_message_parse_error (Message, &error, &debug);
                                    g_printerr ("ERROR from element : %s\n", error->message);
                                    g_printerr ("Debugging info: %s\n", (debug) ? debug : "none");
                                    g_error_free (error);
                                    g_free (debug);
                                    break;


    For which, I get

    root@dra7xx-evm:/opt/work# ./armmp4

    GSTREAMER PC ELEMENTS LINKED SUCCESSFULY

    Video thread created

    going to add pad

    g sig conn succ

    [20900.566618] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1

    loop starting..

    ERROR from element : GStreamer encountered a general stream error.

    Debugging info: qtdemux.c(5055): gst_qtdemux_chain (): /GstPipeline:VideoPlayerPipeline/GstQTDemux:Demuxer:

    no 'moov' atom within the first 10 MB

    ERROR from element : Internal data flow error.

    Debugging info: gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:VideoPlayerPipeline/GstAppSrc:StreamSource:

    streaming task paused, reason error (-5)

    ERROR from element : This file contains no playable streams.

    Debugging info: qtdemux.c(573): gst_qtdemux_post_no_playable_stream_error (): /GstPipeline:VideoPlayerPipeline/GstQTDemux:Demuxer:

    no known streams found


    I got to understand something about atoms and 'moov' atom. It seems like the atom will be present somewhere near the end of the stream. So, I thought of playing an MP4 file that has its size lesser than 10MB. And, when I tried doing this.... I got my dynamic pads perfectly linking and the video plays without any problem.


    But, when I try to play a file of size 10.4 MB, the same debug messages are printed. But this is not a constrain in the case of FILESRC playing.

    I could browse that the 'moov' atom is a metadata and the position of it can be shifted.

    Some one kindly help in resolving this issue. Any type of MP4 file must work with APPSRC.


    Thanks in Advance,

    Regards,

    Shylesh S.

  • Hello,

    Shylesh S said:
    no 'moov' atom within the first 10 MB

    It seems that this is known issue.

    Could you check qtdemux.h file:

      guint64 seek_offset;
     
       gboolean upstream_seekable;
    -  gboolean upstream_size;
    +  gint64 upstream_size;
     };
     
     struct _GstQTDemuxClass {
    ....

    BR
    Margarita