3 votes

Videomixer échoue sur les sources plutôt que sur Videotestsrc

Je veux lire deux fichiers vidéo locaux différents en même temps dans une seule et même installation. fenêtre. Le code ci-dessous sans démux et décodeur fonctionne bien.

    static void play_video(){

    GMainLoop *loop;
    GstElement *pipeline,*videomixer;
    GstElement *src,*sink,*filter,*csp,*videobox;
    GstElement *src1,*filter1,*csp1,*videobox1;
    GstElement *srcb,*filterb,*cspb,*videoboxb;
    GstCaps *filtercaps,*filtercaps1,*filtercapsb;
    GstPad *pad,*pad1;

    const char pattern = "snow";

    loop = g_main_loop_new(NULL, FALSE);

    pipeline = gst_pipeline_new("my-pipeline");

    src = gst_element_factory_make ("videotestsrc","src");
    src1 = gst_element_factory_make ("videotestsrc","src1");

    g_object_set (G_OBJECT (src), "pattern", 10, NULL);

    filter = gst_element_factory_make("capsfilter","filter");
    filter1 = gst_element_factory_make("capsfilter","filter1");

    csp = gst_element_factory_make("ffmpegcolorspace","csp");
    csp1 = gst_element_factory_make("ffmpegcolorspace","csp1");

    /**/

    videobox=gst_element_factory_make("videobox","videobox");
    g_object_set(videobox,"top",0,"bottom",0,"left",0,"right",0,NULL);
    videobox1=gst_element_factory_make("videobox","videobox1");
    g_object_set(videobox1,"top",-20,"bottom",0,"left",0,"right",0,NULL);

    videomixer=gst_element_factory_make("videomixer","videomixer");

      /**/
      sink = gst_element_factory_make("xvimagesink","sink");
       if(sink == NULL)
       sink = gst_element_factory_make("ximagesink","sink");
       if(sink == NULL)
       g_error("'ximagesink' yaratlamad.");

    gst_bin_add_many(GST_BIN(pipeline),src,filter,videobox,videomixer,csp,sink,
                src1,filter1,videobox1,csp1,NULL);

    gst_element_link_many(src,filter,csp,videobox,videomixer,NULL);
    gst_element_link_many(src1,filter1,csp1,videobox1,videomixer,NULL);

     /*
     videotestsrc pattern="snow" ! video/x-raw-yuv, framerate=1/1, width=350,
height=250 ! \
     textoverlay font-desc="Sans 24" text="CAM2" valign=top halign=left
shaded-background=true ! \
     videobox border-alpha=0 top=-200 left=-450 ! mix. \

    */

     gst_element_link_many(videomixer,sink,NULL);

     filtercaps = gst_caps_new_simple ("video/x-raw-rgb",
          "width", G_TYPE_INT, 1024,
          "height", G_TYPE_INT, 768,
          "framerate", GST_TYPE_FRACTION, 25, 1,
          "bpp", G_TYPE_INT, 16,
          "depth", G_TYPE_INT, 16,
          "endianness", G_TYPE_INT, G_BYTE_ORDER,
          NULL);

     filtercaps1 = gst_caps_new_simple ("video/x-raw-rgb",
          "width", G_TYPE_INT, 200,
          "height", G_TYPE_INT, 500,
          "framerate", GST_TYPE_FRACTION, 25, 1,
          "bpp", G_TYPE_INT, 16,
          "depth", G_TYPE_INT, 16,
          "endianness", G_TYPE_INT, G_BYTE_ORDER,
          NULL);

      g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
      gst_caps_unref (filtercaps);

      g_object_set (G_OBJECT (filter1), "caps", filtercaps1, NULL);
      gst_caps_unref (filtercaps1);

      /*pad = gst_element_get_pad (src, "src");
      pad1 = gst_element_get_pad (src1, "src1");

      //gst_pad_add_buffer_probe (pad, G_CALLBACK (cb_have_data), NULL);
      //gst_pad_add_buffer_probe (pad1, G_CALLBACK (cb_have_data), NULL);
      //gst_object_unref (pad);
      //gst_object_unref (pad1);*/

      /* run */
      gst_element_set_state (pipeline, GST_STATE_PLAYING);

      /* wait until it's up and running or failed */
       if (gst_element_get_state (pipeline, NULL, NULL, -1) ==
       GST_STATE_CHANGE_FAILURE) {
       g_error ("Failed to go into PLAYING state");
      }

      g_print ("Running ...\n");
      g_main_loop_run (loop);

     /* exit */
     gst_element_set_state (pipeline, GST_STATE_NULL);
     gst_object_unref (pipeline);
     }

Le problème, c'est que lorsque je remplace le fichier videotestsrc par filesrc, il n'y a pas d'échec et le fichier seul message d'erreur que j'obtiens est "Could not lookup object NULL on signal destroy de l'objet window". Je ne suis pas un expert de gstreamer et mon opinion est que je suis que j'échoue à configurer le démux et le décodeur.

static void play_video5(){

       GMainLoop *loop;
   GstElement *pipeline,*videomixer;
   GstElement *src,*sink,*filter,*csp,*videobox;
   GstElement *src1,*filter1,*csp1,*videobox1;
   GstElement *srcb,*filterb,*cspb,*videoboxb;
   GstCaps *filtercaps,*filtercaps1,*filtercapsb;
   GstPad *pad,*pad1;

       GstElement *demux,*decoder;

   const char pattern = "snow";

   loop = g_main_loop_new(NULL, FALSE);

   pipeline = gst_pipeline_new("my-pipeline");

       //Source
   src = gst_element_factory_make ("videotestsrc","src");

       src1 = gst_element_factory_make ("filesrc","src1");
       g_object_set (G_OBJECT (src1), "location", "file:///root/yu.mp4", NULL);

       //Demux

       demux = gst_element_factory_make ("mpegdemux", "demux");

       //Decoder
       decoder = gst_element_factory_make ("decodebin", "decoder");
//      decoder = gst_element_factory_make ("ffdec_mpeg4","mpeg4-decoder");

       //Filter
   filter = gst_element_factory_make("capsfilter","filter");
   filter1 = gst_element_factory_make("capsfilter","filter1");

       //Colorspace
   csp = gst_element_factory_make("ffmpegcolorspace","csp");
   csp1 = gst_element_factory_make("ffmpegcolorspace","csp1");

       //Videobox
   videobox=gst_element_factory_make("videobox","videobox");
   g_object_set(videobox,"top",0,"bottom",0,"left",0,"right",0,NULL);
   videobox1=gst_element_factory_make("videobox","videobox1");
   g_object_set(videobox1,"top",-20,"bottom",0,"left",0,"right",0,NULL);

       //videomixer
   videomixer=gst_element_factory_make("videomixer","videomixer");

       //Sink
   sink = gst_element_factory_make("xvimagesink","sink");
   if(sink == NULL)
       sink = gst_element_factory_make("ximagesink","sink");
       if(sink == NULL)
       g_error("'ximagesink' yaratlamad.");

       //Add to Bin
   gst_bin_add_many(GST_BIN(pipeline),src,filter,videobox,videomixer,csp,
                src1,decoder,filter1,videobox1,csp1,sink,NULL);

       //Link Elements
       gst_element_link(src,filter);
       gst_element_link(filter,csp);
       gst_element_link(csp,videobox);
       gst_element_link(videobox, videomixer);

       gst_element_link(src1,decoder);
       gst_element_link(decoder,filter1);
//      gst_element_link(decoder,csp1);
       gst_element_link(filter1,csp1);
       gst_element_link(csp1,videobox1);
       gst_element_link(videobox1, videomixer);

       gst_element_link(videomixer,sink);

       //Cap definition
   filtercaps = gst_caps_new_simple ("video/x-raw-rgb",
          "width", G_TYPE_INT, 1024,
          "height", G_TYPE_INT, 768,
          "framerate", GST_TYPE_FRACTION, 25, 1,
          "bpp", G_TYPE_INT, 16,
          "depth", G_TYPE_INT, 16,
          "endianness", G_TYPE_INT, G_BYTE_ORDER,
          NULL);

   filtercaps1 = gst_caps_new_simple ("video/x-raw-yuv",
          "width", G_TYPE_INT, 640,
          "height", G_TYPE_INT, 480,
          "framerate", GST_TYPE_FRACTION, 25, 1,
          /*"bpp", G_TYPE_INT, 16,
          "depth", G_TYPE_INT, 16,
          "endianness", G_TYPE_INT, G_BYTE_ORDER,*/
          NULL);

       //Cap to Filter
   g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
   gst_caps_unref (filtercaps);

   g_object_set (G_OBJECT (filter1), "caps", filtercaps1, NULL);
   gst_caps_unref (filtercaps1);

   /* run */
   gst_element_set_state (pipeline, GST_STATE_PLAYING);

   /* wait until it's up and running or failed */
   if (gst_element_get_state (pipeline, NULL, NULL, -1) ==
GST_STATE_CHANGE_FAILURE) {
       g_error ("Failed to go into PLAYING state");
   }

   g_print ("Running ...\n");
   g_main_loop_run (loop);

   /* exit */
   gst_element_set_state (pipeline, GST_STATE_NULL);
   gst_object_unref (pipeline);
}

Toute idée ou correction est la bienvenue.

1voto

ensonic Points 1717

Plusieurs problèmes :

  • filesrc ne prend pas les uris, mais les chemins de fichiers.
  • /* attendre jusqu'à ce qu'il fonctionne ou échoue */ + le code ci-dessous n'est pas nécessaire, il vaut mieux écouter le bus pour les messages d'erreur et d'avertissement.
  • "Could not lookup object NULL on signal destroy of object window" n'a rien à voir avec gstreamer
  • toute l'affaire videobox n'est pas nécessaire puisque les pads de videomixer ont des propriétés xpos, ypos et zorder.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X