2016-04-01 18 views
0

Ich versuche, ein Video mit FFmpeg zu kodieren, aber ich habe ein Problem über fps. So bauen ich den Code Probe alsVideo mit FFmpeg kodieren fps falsch gewesen

AVCodec *codec; 
AVCodecContext *c = NULL; 
int i, ret, x, y, got_output; 
FILE *f; 
AVFrame *frame; 
AVPacket pkt; 
uint8_t endcode[] = { 0, 0, 1, 0xb7 }; 

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

/* find the mpeg1 video encoder */ 
codec = avcodec_find_encoder((AVCodecID)codec_id); 
if (!codec) { 
    fprintf(stderr, "Codec not found\n"); 
    exit(1); 
} 

c = avcodec_alloc_context3(codec); 
if (!c) { 
    fprintf(stderr, "Could not allocate video codec context\n"); 
    exit(1); 
} 

/* put sample parameters */ 
c->bit_rate = 400000; 
/* resolution must be a multiple of two */ 
c->width = 352; 
c->height = 288; 
/* frames per second */ 
c->time_base.num = 1; 
c->time_base.den = 5; //changed 

/* emit one intra frame every ten frames 
* check frame pict_type before passing frame 
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I 
* then gop_size is ignored and the output of encoder 
* will always be I frame irrespective to gop_size 
*/ 
c->gop_size = 10; 
c->max_b_frames = 1; 
c->pix_fmt = AV_PIX_FMT_YUV420P; 

if (codec_id == AV_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); 
} 

frame = av_frame_alloc(); 
if (!frame) { 
    fprintf(stderr, "Could not allocate video frame\n"); 
    exit(1); 
} 
frame->format = c->pix_fmt; 
frame->width = c->width; 
frame->height = c->height; 

/* 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 */ 
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height, 
    c->pix_fmt, 32); 
if (ret < 0) { 
    fprintf(stderr, "Could not allocate raw picture buffer\n"); 
    exit(1); 
} 

/* encode 5 second of video */ 
for (i = 0; i < 25; i++) { 
    av_init_packet(&pkt); 
    pkt.data = NULL; // packet data will be allocated by the encoder 
    pkt.size = 0; 

    fflush(stdout); 
    /* prepare a dummy image */ 
    /* Y */ 
    for (y = 0; y < c->height; y++) { 
     for (x = 0; x < c->width; x++) { 
      frame->data[0][y * frame->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++) { 
      frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2; 
      frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5; 
     } 
    } 

    frame->pts = i; 

    /* encode the image */ 
    ret = avcodec_encode_video2(c, &pkt, frame, &got_output); 
    if (ret < 0) { 
     fprintf(stderr, "Error encoding frame\n"); 
     exit(1); 
    } 

    if (got_output) { 
     printf("Write frame %3d (size=%5d)\n", i, pkt.size); 
     fwrite(pkt.data, 1, pkt.size, f); 
     av_free_packet(&pkt); 
    } 
} 

/* get the delayed frames */ 
for (got_output = 1; got_output; i++) { 
    fflush(stdout); 

    ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); 
    if (ret < 0) { 
     fprintf(stderr, "Error encoding frame\n"); 
     exit(1); 
    } 

    if (got_output) { 
     printf("Write frame %3d (size=%5d)\n", i, pkt.size); 
     fwrite(pkt.data, 1, pkt.size, f); 
     av_free_packet(&pkt); 
    } 
} 

/* add sequence end code to have a real mpeg file */ 
fwrite(endcode, 1, sizeof(endcode), f); 
fclose(f); 

avcodec_close(c); 
av_free(c); 
av_freep(&frame->data[0]); 
av_frame_free(&frame); 
printf("\n"); 

folgt und ich änderte die folgenden Teile aus dem ursprünglichen

c->time_base.num = 1; 
c->time_base.den = 5; 

nach diesen Änderungen, erwarte ich ein Video aus 5 Sekunden und 5 fps werden. Aber wenn ich die Ausgangsvideodatei spiele, endet das Video in 1 2 Sekunden. Der ffprob-Ausgang des Ausgangsvideos ist wie folgt.

bearbeiten: ffprobe Ausgabe hinzugefügt als Text

ffprobe version 2.0.1 Copyright (c) 2007-2013 the FFmpeg developers 
    built on Sep 26 2013 02:00:03 with gcc 4.8.1 (GCC) 
    configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib 
    libavutil  52. 38.100/52. 38.100 
    libavcodec  55. 18.102/55. 18.102 
    libavformat 55. 12.100/55. 12.100 
    libavdevice 55. 3.100/55. 3.100 
    libavfilter  3. 79.101/3. 79.101 
    libswscale  2. 3.100/2. 3.100 
    libswresample 0. 17.102/0. 17.102 
    libpostproc 52. 3.100/52. 3.100 
Input #0, h264, from 'C:\Users\bhamuryen\Desktop\Dev\Test\ffmpeg_test\ffmpeg_test\test.h264': 
    Duration: N/A, bitrate: N/A 
    Stream #0:0: Video: h264 (High), yuv420p, 352x288, 5 fps, 5 tbr, 1200k tbn, 10 tbc 
[STREAM] 
index=0 
codec_name=h264 
codec_long_name=H.264/AVC/MPEG-4 AVC/MPEG-4 part 10 
profile=High 
codec_type=video 
codec_time_base=1/10 
codec_tag_string=[0][0][0][0] 
codec_tag=0x0000 
width=352 
height=288 
has_b_frames=1 
sample_aspect_ratio=0:1 
display_aspect_ratio=0:1 
pix_fmt=yuv420p 
level=13 
timecode=N/A 
id=N/A 
r_frame_rate=10/2 
avg_frame_rate=5/1 
time_base=1/1200000 
start_pts=N/A 
start_time=N/A 
duration_ts=N/A 
duration=N/A 
bit_rate=N/A 
nb_frames=N/A 
nb_read_frames=N/A 
nb_read_packets=N/A 
DISPOSITION:default=0 
DISPOSITION:dub=0 
DISPOSITION:original=0 
DISPOSITION:comment=0 
DISPOSITION:lyrics=0 
DISPOSITION:karaoke=0 
DISPOSITION:forced=0 
DISPOSITION:hearing_impaired=0 
DISPOSITION:visual_impaired=0 
DISPOSITION:clean_effects=0 
DISPOSITION:attached_pic=0 

Der Ausgang Video-Datei abgespielt mit VLC und VLC-Statistik ist wie folgt.

vlc output

Wie gezeigt, setted i fps 5 aber vlc lesen es wie 10 fps ffprobe auch

Strom # 0 zu uns sagen: 0: Video: h264 (High), yuv420p, 352x288 , 5 fps, 5 TBR, 1200K TBN, 10 TBC

und

codec_time_base = 1/10

ich denke, die wichtige Sache ist codec_time_base = 1/10 und 10 tbc. Was ist falsch in diesem Code? Ich weiß nicht genau den Grund für das Problem. Wie kann ich ein Video erstellen (5 fps -10 fps oder benutzerdefinierte fps) und das erstellte Video korrekt wiedergeben?

Danke für Ihre Hilfe.

+2

Veröffentlichen Sie keine Bilder von Text! – Olaf

+0

Ich habe die ffprob Ausgabe als Text und und auf Ihre Lösung warten. –

+0

Du hättest das Bild dann auch entfernen sollen! Und das C++ - Tag nicht erneut hinzugefügt. C ist nicht C++ ist nicht C. Das sieht aus wie C. Wenn ich Fehler habe und Sie als C++ kompilieren (schlechte Idee), zögern Sie nicht, ** zu C++ zu ändern. – Olaf

Antwort

0

Nicht sicher, was mit Ihrem Code los ist, aber ich hatte ein ähnliches Problem. Es stellte sich heraus, dass ich

c->time_base.num = 1; 
c->time_base.den = 10; 

was bedeutet, 10 Bilder pro Sekunde eingestellt hatte, aber meine Timer war nicht in der Lage mit dieser Geschwindigkeit Schritt zu halten. Ich hatte einen 100 ms-Timer, aber er lief mit einer langsameren Rate und nur ein Bild alle 150 ms oder so anstelle von 100 ms zu kodieren.