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.
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.
Veröffentlichen Sie keine Bilder von Text! – Olaf
Ich habe die ffprob Ausgabe als Text und und auf Ihre Lösung warten. –
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