J'essaye d'écrire un programme qui utilise libx264 pour coder les images vidéo. J'ai enveloppé ce code dans une petite classe (voir ci-dessous). J'ai des cadres qui sont au format YUV420. libx264 encode les cadres et je les sauvegarde dans un fichier. Je peux lire le fichier dans VLC, tous les cadres sont là, mais il est lu à plusieurs centaines de fois la fréquence d'image réelle. Actuellement, je capture des images à 2,5 FPS, mais elles sont lues comme si elles avaient été enregistrées à 250 images/seconde ou plus. J'ai essayé de changer le taux de trame sans aucune chance.La lecture de l'encodeur libx264 est trop rapide
J'ai aussi essayé de mettre
_param.b_vfr_input = 1
puis définissez les bases de temps appropriée, mais qui cause mon programme de tomber en panne. Des idées? Mon code d'encodage est montré ci-dessous. J'ai également inclus la sortie de ffprobe -show_frames
Wrapper Classe:
x264wrapper::x264wrapper(int width, int height, int fps, int timeBaseNum, int timeBaseDen, int vfr)
{
x264_param_default_preset(&_param, "veryfast", "zerolatency");
_param.i_threads = 1;
_param.i_width = width;
_param.i_height = height;
_param.i_fps_num = fps;
_param.i_fps_den = 1;
// Intra refres:
_param.i_keyint_max = fps;
_param.b_intra_refresh = 1;
//Rate control:
_param.rc.i_rc_method = X264_RC_CRF;
//_param.rc.i_rc_method = X264_RC_CQP;
_param.rc.f_rf_constant = 25;
_param.rc.f_rf_constant_max = 35;
//For streaming:
_param.b_repeat_headers = 1;
_param.b_annexb = 1;
// misc
_param.b_vfr_input = vfr;
_param.i_timebase_num = timeBaseNum;
_param.i_timebase_den = timeBaseDen;
_param.i_log_level = X264_LOG_DEBUG;
_encoder = x264_encoder_open(&_param);
cout << "Timebase " << _param.i_timebase_num << "/" << _param.i_timebase_den << endl;
cout << "fps " << _param.i_fps_num << "/" << _param.i_fps_den << endl;
_ticks_per_frame = (int64_t)_param.i_timebase_den * _param.i_fps_den/_param.i_timebase_num/_param.i_fps_num;
cout << "ticks_per_frame " << _ticks_per_frame << endl;
int result = x264_picture_alloc(&_pic_in, X264_CSP_I420, width, height);
if (result != 0)
{
cout << "Failed to allocate picture" << endl;
throw(1);
}
_ofs = new ofstream("output.h264", ofstream::out | ofstream::binary);
_pts = 0;
}
x264wrapper::~x264wrapper(void)
{
_ofs->close();
}
void x264wrapper::encode(uint8_t * buf)
{
x264_nal_t* nals;
int i_nals;
convertFromBalserToX264(buf);
_pts += _ticks_per_frame;
_pic_in.i_pts = _pts;
x264_picture_t pic_out;
int frame_size = x264_encoder_encode(_encoder, &nals, &i_nals, &_pic_in, &pic_out);
if (frame_size >= 0)
{
_ofs->write((char*)nals[0].p_payload, frame_size);
}
else
{
cout << "error: x264_encoder_encode failed" << endl;
}
}
Sortie de ffprobe -show_frames:
[FRAME]
media_type=video
key_frame=1
pkt_pts=N/A
pkt_pts_time=N/A
pkt_dts=N/A
pkt_dts_time=N/A
pkt_duration=48000
pkt_duration_time=0.040000
pkt_pos=0
width=1920
height=1080
pix_fmt=yuv420p
sample_aspect_ratio=N/A
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
reference=0
[/FRAME]
[FRAME]
media_type=video
key_frame=0
pkt_pts=N/A
pkt_pts_time=N/A
pkt_dts=N/A
pkt_dts_time=N/A
pkt_duration=N/A
pkt_duration_time=N/A
pkt_pos=54947
width=1920
height=1080
pix_fmt=yuv420p
sample_aspect_ratio=N/A
pict_type=P
coded_picture_number=1
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
reference=0
[/FRAME]
[FRAME]
media_type=video
key_frame=0
pkt_pts=N/A
pkt_pts_time=N/A
pkt_dts=N/A
pkt_dts_time=N/A
pkt_duration=N/A
pkt_duration_time=N/A
pkt_pos=57899
width=1920
height=1080
pix_fmt=yuv420p
sample_aspect_ratio=N/A
pict_type=P
coded_picture_number=2
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
reference=0
[/FRAME]