Problemen coderen naar .MP4 met ffmpeg

Dus ik ben hier een beetje nieuw bij, ik schrijf een WIN32-app die video op .AVI registreert, en ik was van plan om ffmpeg te gebruiken om te coderen naar .MP4. Op basis van een voorbeeld dat ik vond, kwam ik zo ver. Het compileert en zegt dat het het bestand heeft gecodeerd en geschreven, maar het uitvoerbestand kan niet worden geopend en afgespeeld. Ik heb geprobeerd om MPEG1-codering te gebruiken zoals het originele voorbeeld gebruikte, maar het geeft me slechts een paar seconden vreemde kleuren.

Mis ik iets dat moet worden gedaan met het bestand?

Iedereen met ervaring in coderen/ffmpeg, een aantal tips, advies of hulp zou me enorm dankbaar maken. Bij voorbaat dank!

int _tmain(int argc, _TCHAR* argv[])
{

    AVFormatContext *pFormatCtx;
    int codec_id = CODEC_ID_MPEG4;
    char filename [] ="C:\\wav\\test2.flv";
// Open video file
     AVCodec *codec;
     AVCodecContext *c= NULL;
     int i, out_size, x, y, outbuf_size;
    FILE *f;
     AVFrame *picture;
    uint8_t *outbuf;
     int had_output=0;

    av_register_all();
   printf("Encode video file %s\n", filename);

    codec = avcodec_find_encoder(CODEC_ID_H264);
    if (!codec) {
         fprintf(stderr, "codec not found\n");
        exit(1);
    }

    c = avcodec_alloc_context3(codec);
    picture= avcodec_alloc_frame();

   /* put sample parameters */
   c->bit_rate = 40000;
   //c->bit_rate_tolerance=30;
     /* resolution must be a multiple of two */
    c->width = 352;
    c->height = 288;
    /* frames per second */

    c->time_base.den=  25;
    c->time_base.num= 1;
     c->gop_size = 10; /* emit one intra frame every ten frames */
   c->max_b_frames=1;
     c->pix_fmt = PIX_FMT_YUV420P;

    if(codec_id == CODEC_ID_H264)
        av_opt_set(c->priv_data, "preset", "slow", 0);
/* open it */
    if (avcodec_open2(c, codec, NULL) < 0) {
        fprintf(stderr, "could not open codec\n");
       exit(1);
    }


     f = fopen(filename, "wb");
     if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
         exit(1);
     }

    /* alloc image and output buffer */
    outbuf_size = 100000 + 12*c->width*c->height;
     outbuf = (uint8_t*)malloc(outbuf_size); //CHANGED

     /* the image can be allocated by any means and av_image_alloc() is
      * just the most convenient way if av_malloc() is to be used */
    av_image_alloc(picture->data, picture->linesize,
                   c->width, c->height, c->pix_fmt, 1);

     /* encode 1 second of video */
     for(i=0;i<25;i++) {
         fflush(stdout);
         /* prepare a dummy image */
        /* Y */
         for(y=0;yheight;y++) {
            for(x=0;xwidth;x++) {
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
            }
         }

        /* Cb and Cr */
        for(y=0;yheight/2;y++) {
            for(x=0;xwidth/2;x++) {
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
            }
        }

         /* encode the image */
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
         had_output |= out_size;
        printf("encoding frame %3d (size=%5d)\n", i, out_size);
        fwrite(outbuf, 1, out_size, f);
     }

     /* get the delayed frames */
     for(; out_size || !had_output; i++) {
         fflush(stdout);

        out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
        had_output |= out_size;
         printf("write frame %3d (size=%5d)\n", i, out_size);
       fwrite(outbuf, 1, out_size, f);
     }

     /* add sequence end code to have a real mpeg file */
     outbuf[0] = 0x00;
     outbuf[1] = 0x00;
     outbuf[2] = 0x01;
   outbuf[3] = 0xb7;
     fwrite(outbuf, 1, 4, f);
     fclose(f);
        fclose(p);
    free(outbuf);

     avcodec_close(c);
     av_free(c);
     av_free(picture->data[0]);
    av_free(picture);
     printf("\n");

    return 0;
}
1
raadpleeg deze link stackoverflow.com/a/43464269/6180077 voor mp4-containercodering video met FFMPEG - c ++
toegevoegd de auteur Abdullah Farweez, de bron

1 antwoord

U schrijft geen .MP4 , .flv noch AVI bestand. Je schrijft onbewerkte H.264-videostream zonder enige container. De meeste spelers zullen het niet kunnen spelen, maar het werkt prima met ffplay en mplayer.

Het lijkt te werken zoals bedoeld. Het codeert voor 25 frames met vreemde kleurovergangen. Hoewel, als gevolg van lage bitrate, het kan lijken op wat afval.

Het enige wat u hoeft te doen, is om deze stream in een container te plaatsen met behulp van libavformat . En zorg voor een aantal echte videoframes om te coderen.

3
toegevoegd
Je decodeert geen video. De video wordt on the fly gegenereerd (zie /* maak een dummy image */) en schrijf naar "C: \\ wav \\ test2.flv" .
toegevoegd de auteur Piotr Praszmo, de bron
U moet de AVI decoderen en coderen als MP4. Mogelijk moet u de video- en audiostreams ook opnieuw coderen, maar niet noodzakelijkerwijs.
toegevoegd de auteur Piotr Praszmo, de bron
Oke bedankt, dus ik moet een container maken. Maar echte videoframes? Het bestand dat ik open, is een echte video of mis ik iets? Weet u toevallig of er goede monsters zijn, speciaal met het maken van containers enzovoort.
toegevoegd de auteur Erik Swansson, de bron
Oh ik begrijp het, wat een reus mist. Bedankt :)
toegevoegd de auteur Erik Swansson, de bron
Gewoon een vraag, stel dat ik een .AVI-bestand open. Ik wil het in een .MP4-bestand veranderen. Ik maak de container ervoor, moet ik de .AVI decoderen voordat ik hem codeer naar MP4. Of open ik gewoon de .AVI, codeer hem en schrijf de frames naar mijn container?
toegevoegd de auteur Erik Swansson, de bron