Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Candidat au Club
    Fixer des arguments en C dans fonction main, comment ?
    bonjour à tous,
    Je souhaiterai positionner des arguments fixes pour un programme (ffmpeg) dans sa fonction main.
    Malgré mes essais, mon niveau de C est nul, je n'y suis pas parvenu. Je vous donne ici cette fonction.
    Je souhaite entrée:
    -i rtsp://localhost/live
    en sortie:
    -f flv rtmp://remotehost/live

    Si vous pouvez m'aider ... D'avance merci:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
     
    int main(int argc, char **argv)
    {
        int i, ret;
        BenchmarkTimeStamps ti;
     
        init_dynload();
     
        register_exit(ffmpeg_cleanup);
     
        setvbuf(stderr,NULL,_IONBF,0);
     
     
        av_log_set_flags(AV_LOG_SKIP_REPEATED);
        parse_loglevel(argc, argv, options);
     
     
        if(argc>1 && !strcmp(argv[1], "-d")){
            run_as_daemon=1;
            av_log_set_callback(log_callback_null);
            argc--;
            argv++;
        }
     
     
     
    #if CONFIG_AVDEVICE
        avdevice_register_all();
    #endif
        avformat_network_init();
     
        show_banner(argc, argv, options);
     
        /* parse options and open all input/output files */
        ret = ffmpeg_parse_options(argc, argv);
        if (ret < 0)
            exit_program(1);
     
        if (nb_output_files <= 0 && nb_input_files == 0) {
            show_usage();
            av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
            exit_program(1);
        }
     
        /* file converter / grab */
        if (nb_output_files <= 0) {
            av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
            exit_program(1);
        }
     
        for (i = 0; i < nb_output_files; i++) {
            if (strcmp(output_files[i]->ctx->oformat->name, "rtp"))
                want_sdp = 0;
        }
     
       /* current_time = ti = get_benchmark_time_stamps();*/
        if (transcode() < 0)
            exit_program(1);
        if (do_benchmark) {
            int64_t utime, stime, rtime;
            current_time = get_benchmark_time_stamps();
            utime = current_time.user_usec - ti.user_usec;
            stime = current_time.sys_usec  - ti.sys_usec;
            rtime = current_time.real_usec - ti.real_usec;
            av_log(NULL, AV_LOG_INFO,
                   "bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n",
                   utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
        }
     
        av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n",
               decode_error_stat[0], decode_error_stat[1]);
        if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1])
            exit_program(69);
     
        exit_program(received_nb_signals ? 255 : main_return_code);
        return main_return_code;
    }

  2. #2
    Expert éminent sénior
    Bonjour
    Citation Envoyé par netlink1987 Voir le message
    Je souhaiterai positionner des arguments fixes pour un programme (ffmpeg) dans sa fonction main.
    Si j'ai bien compris, tu souhaiterais modifier argc et argv pour que ici ffmpeg_parse_options(argc, argv), la fonction reçoive un argv contenant les arguments passés à ton programme plus des trucs à toi.

    Désolé, ce n'est pas possible. argc et argv sont des variables gérées par l'OS et tu n'as pas le droit de les modifier. Encore que si tu modifies un argv[x] déjà existant par un autre ayant la même taille ou plus petit ça pourrait le faire (bien que je n'ai jamais essayé) mais agrandir argv pour lui mettre des trucs en plus non connus de l'OS là non.

    En revanche, rien ne t'interdit de créer tes propres argc et argv copiés à partir des originaux mais contenant en plus tes trucs à toi. Bon c'est pas évident car il te faut le construire "en live" mais c'est faisable

    Exemple
    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    int myArgc;
    char **myArgv;
     
    // Allocation myArgv pour contenir tout argv plus mes trucs à moi (par exemple "-i" et "rtsp://localhost/live" donc 2 trucs)
    myArgc=argc + 2;
    myArgv=malloc(myArgc * sizeof(char *));
     
    // Remplissage myArgv avec d'abord mes trucs en plus qui seront en premier (ne pas oublier aussi le nom du programme qui est dans argv[0])
    myArgv[0]=argv[0];
    myArgv[1]="-i";
    myArgv[2]="rtsp://localhost/live";
     
    // Remplissage du reste de myArgv avec le contenu de argv. Ne pas oublier argv[argc] qui vaut NULL.
    for (i=3; i <= myArgc; i++) myArgv[i]=argv[i-2];
     
    // Ok, maintenant on utilise mon argv
    ffmpeg_parse_options(myArgc, myArgv);
     
    ...
    // Ne pas oublier de libérer myArgv quand on n'en a plus besoin
    free(myArgv);
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  3. #3
    Candidat au Club
    C'est bien cela, ou presque ...
    Bonsoir,

    Merci beaucoup pour ton aide précieuse, cela fonctionne et ton analyse est exacte .

    En revanche je voulais aller un peu plus loin dans le découpage des arguments (il connait rien et en plus il
    est exigeant ! )

    J'ai modifié le source pour découper la chaîne 'rstp://localhost/live' en 'rtsp://localhost/' et remplacer 'live' par autre chose
    donné en argument mais sans succès, car si je donne argv[x] en argument, un espace sépare chaque chaîne de caractères.

    Peut être faut il définit des variables et concaténer cette chaîne ?

    Quoi qu'il en soit, merci encore.

  4. #4
    Expert éminent
    Citation Envoyé par netlink1987 Voir le message
    J'ai modifié le source pour découper la chaîne 'rstp://localhost/live' en 'rtsp://localhost/' et remplacer 'live' par autre chose
    donné en argument mais sans succès, car si je donne argv[x] en argument, un espace sépare chaque chaîne de caractères.

    Peut être faut il définit des variables et concaténer cette chaîne ?
    En réalité, c'est un problème plus complexe parce qu'on parle d'1 URL et 1 URL a différentes parties (protocole, identifiant, mot de passe, domaine, port, chemin, paramètres, fragment, ...)

    RFC 1738, lien officiel avec les règles syntaxiques/ lexicales pour parser 1 URL.

    Alors, certes, si tu maîtrises ton URL et que tu n'as que "protocole, domaine, chemin" tu peux y aller avec sscanf ... mais parser une URL n'est pas simple et c'est casse-bonbon

    Moi , je regardais la bibliothèque cURL (<- lien officiel) et notamment les fonctions curl_url_get et curl_url_set (<- liens officiels)
    Après c'est vrai que cela crée une dépendance au projet (et je ne sais pas si cURL est une bibliothèque petite, moyenne ou grosse )

  5. #5
    Expert éminent sénior
    Citation Envoyé par netlink1987 Voir le message
    En revanche je voulais aller un peu plus loin dans le découpage des arguments (il connait rien et en plus il est exigeant ! )
    Ben oui quoi. C'est pas que t'es exigeant, c'est surtout que le C est super bas niveau. Rien que le terme "concaténer des chaines" que tu emploies après, autant dans d'autres langages c'est implicite (x="toto"+"titi" en Python par exemple), autant en C ben faut savoir déjà comment il gère les chaines car tu dois alors refaire cette gestion à sa place. Là dans mon exemple j'ai écrit des trucs comme myArgv[1]="-i" mais rien que ça ça fait appel à des notions de pointeurs (en fait je copie une adresse dans une autre) et si tu utilisais la même instruction dans un autre contexte ça ne fonctionnerait pas. Tiens exemple
    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *toto="Hello";			// Ca marche
    char *titi; titi="Hello";		// Ca marche
    char tutu[100]="Hello";			// Ca marche
    char tata[100]; tata="Hello"; 		// Ca marche pas !!!

    Donc arrivé à un certain point, il faut quand-même en passer par la case "tuto+apprentissage+vous gagnez 20000€" (enfin non, ça c'est la case "départ", me suis trompé de jeu)...

    Citation Envoyé par foetus Voir le message
    et je ne sais pas si cURL est une bibliothèque petite, moyenne ou grosse
    Bah, c'est un peu comme ma t..b
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  6. #6
    Candidat au Club
    Aller hop, retour au cours de C ......
    Bon, je vais bosser un peu hein ? Je vais ressortir les vieux bouquins !

    Merci à vous pour ces conseils.


    Citation Envoyé par Sve@r Voir le message
    Ben oui quoi. C'est pas que t'es exigeant, c'est surtout que le C est super bas niveau. Rien que le terme "concaténer des chaines" que tu emploies après, autant dans d'autres langages c'est implicite (x="toto"+"titi" en Python par exemple), autant en C ben faut savoir déjà comment il gère les chaines car tu dois alors refaire cette gestion à sa place. Là dans mon exemple j'ai écrit des trucs comme myArgv[1]="-i" mais rien que ça ça fait appel à des notions de pointeurs (en fait je copie une adresse dans une autre) et si tu utilisais la même instruction dans un autre contexte ça ne fonctionnerait pas.


    Bah, c'est un peu comme ma t..b

  7. #7
    Expert éminent sénior
    Citation Envoyé par netlink1987 Voir le message
    Bon, je vais bosser un peu hein ? Je vais ressortir les vieux bouquins !
    Ok, je veux bien te donner encore un coup de pouce...
    Citation Envoyé par netlink1987 Voir le message
    J'ai modifié le source pour découper la chaîne 'rstp://localhost/live' en 'rtsp://localhost/' et remplacer 'live' par autre chose
    donné en argument mais sans succès, car si je donne argv[x] en argument, un espace sépare chaque chaîne de caractères.

    Peut être faut il définit des variables et concaténer cette chaîne ?
    Voici comment concaténer les différents arguments de ton programme à la chaine "rtsp://localhost/" et afficher le résultat

    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char url[100];
     
    for (i=1; i < argc; i++) {
    	sprintf(url, "rtsp://localhost/%s", argv[i]);			// Ici danger, si l'argument est super long, on dépasse 100 taille définie au départ. Et le C ne checke pas ce genre de cas. Mais à un moment donné tant pis. En C il faut savoir faire la part entre bugs potentiels, criticité dudit bug dans le programme et coût en temps et nb de lignes pour d'en protéger
    	printf("url=[%s]\n", url);
    }
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  8. #8
    Candidat au Club
    même pas eu besoin d'ouvrir mon vieux bouquin, ça marche tt seul !
    Mais c'est que ça marche !

    c cool merci !

    Bon, je ne vous embête plus, je vais essayer d'avancer seul et je vous soumets la chose ds quelques jours .....

    Bonne soirée !

  9. #9
    Membre habitué
    La STL dispose tout de même du minimum vital (split, recherche, concaténation...)
    Regarde du côté de <string.h>

  10. #10
    Expert éminent sénior
    Salut,
    Citation Envoyé par wistiti1234 Voir le message
    La STL dispose tout de même du minimum vital (split, recherche, concaténation...)
    Regarde du côté de <string.h>
    Sauf qu'en C, au mieux, on parlera de SL (Standard Library) ou de la libC, car STL, c'est un terme spécifique au C++ qui correspond d'ailleurs à une partie seulement de la bibliothèque proposée par le standard, vu qu'elle correspond spécifiquement aux fonctionnalités développées de manière générique (Standard Templated Library)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog