简体   繁体   English

使用ffmpeg编码到.MP4的问题

[英]Problems encoding to .MP4 using ffmpeg

So I'm kind of new to this, I'm writing a WIN32 app that records video to .AVI, then I planned to use ffmpeg to encode to .MP4. 所以我对此有点新鲜,我正在编写一个将视频录制到.AVI的WIN32应用程序,然后我计划使用ffmpeg编码为.MP4​​。 Based on a sample I found, I got this far. 根据我发现的样本,我得到了这个。 It compiles and says that it encoded and wrote the file but the output file can't be opened and played. 它编译并说它编码并编写了文件但输出文件无法打开和播放。 I tried using MPEG1 encoding like the original sample was using but it only gives me weird colors for a few seconds. 我尝试使用MPEG1编码,就像原始样本一样,但它只给我几秒钟的奇怪颜色。

Am I missing something that should be done with the file? 我错过了应该用文件完成的事情吗?

Anyone with experience in encoding/ffmpeg, some pointers, advice or help would make me outmost grateful. 任何有编码/ ffmpeg经验的人,一些指示,建议或帮助都会让我感激不尽。 Thanks in advance! 提前致谢!

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;y<c->height;y++) {
            for(x=0;x<c->width;x++) {
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
            }
         }

        /* Cb and Cr */
        for(y=0;y<c->height/2;y++) {
            for(x=0;x<c->width/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;
}

You are not writing .MP4 , .flv nor AVI file. 你不是在写.MP4.flvAVI文件。 You are writing raw H.264 video stream without any container. 您正在编写没有任何容器的原始H.264视频流。 Most players won't be able to play it, but it works fine with ffplay and mplayer. 大多数玩家都无法玩它,但它可以与ffplay和mplayer一起使用。

It seems to be working as intended. 它似乎按预期工作。 It encodes 25 frames of weird color gradients. 它编码25帧奇怪的色彩渐变。 Though, due to low bitrate, it might look like some garbage. 虽然,由于比特率低,它可能看起来像一些垃圾。

All you need to do, is to put this stream into some container using libavformat . 您需要做的就是使用libavformat将此流放入某个容器中。 And, provide some real video frames to encode. 并且,提供一些真实的视频帧进行编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM