Comment utiliser les x264 API C pour coder RBG images en H264 cadres? J'ai déjà créé une séquence de JBR images, comment puis-je maintenant de transformer cette séquence dans une séquence de H264 cadres? En particulier, comment puis-je encoder cette séquence d'images RVB en une séquence de H264 cadre constitué d'une seule initiale H264 image-clé suivi par dépendante H264 cadres?
Réponses
Trop de publicités?Tout d'abord: vérifiez le x264.h de fichier, il contient plus ou moins la référence pour chaque fonction et de la structure. Le x264.c fichier que vous pouvez trouver dans le téléchargement contient un exemple de mise en œuvre. La plupart des gens disent pour vous de base sur celle-ci, mais je la trouve assez complexe pour les débutants, il est bon comme un exemple à tomber en arrière sur cependant.
Tout d'abord vous mettre en place certains paramètres, le type x264_param_t, un bon site décrivant les paramètres est http://mewiki.project357.com/wiki/X264_Settings . Jetez aussi un oeil à l' x264_param_default_preset
fonction qui permet de cibler certaines fonctionnalités sans avoir besoin de comprendre tous les (parfois assez complexe) des paramètres. Également utiliser x264_param_apply_profile
par la suite (vous aurez probablement envie de la "ligne de base" profil)
Ceci est un exemple de configuration de mon code:
x264_param_t param;
x264_param_default_preset(¶m, "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.f_rf_constant = 25;
param.rc.f_rf_constant_max = 35;
//For streaming:
param.b_repeat_headers = 1;
param.b_annexb = 1;
x264_param_apply_profile(¶m, "baseline");
Après cela, vous pouvez initialiser le codeur comme suit
x264_t* encoder = x264_encoder_open(¶m);
x264_picture_t pic_in, pic_out;
x264_picture_alloc(&pic_in, X264_CSP_I420, w, h)
X264 attend YUV420P de données (je suppose que certains d'autres aussi, mais c'est la commune). Vous pouvez utiliser libswscale (à partir de ffmpeg) pour convertir les images au bon format. L'initialisation c'est comme cela (je suppose que les données RVB avec 24bpp).
struct SwsContext* convertCtx = sws_getContext(in_w, in_h, PIX_FMT_RGB24, out_w, out_h, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);
l'encodage est aussi simple que cela, alors, pour chaque image faire:
//data is a pointer to you RGB structure
int srcstride = w*3; //RGB stride is just 3*width
sws_scale(convertCtx, &data, &srcstride, 0, h, pic_in.img.plane, pic_in.img.stride);
x264_nal_t* nals;
int i_nals;
int frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out);
if (frame_size >= 0)
{
// OK
}
J'espère que cela vous va ;), j'ai passé un long moment sur moi-même pour commencer. X264 est une incroyablement forte, mais parfois complexe morceau de logiciel.
edit: Lorsque vous utilisez d'autres paramètres, il sera retardé images, ce n'est pas le cas avec mes paramètres (surtout à cause de la nolatency option). Si c'est le cas, frame_size parfois être égal à zéro et vous devrez appeler x264_encoder_encode
aussi longtemps que la fonction x264_encoder_delayed_frames
n'est pas 0. Mais pour cette fonctionnalité, vous devriez jeter un coup d'oeil plus profond dans x264.c et x264.h .
J'ai téléchargé un exemple qui génère premières images yuv et puis encode à l'aide de x264. Code complet peut être trouvé ici: https://gist.github.com/roxlu/6453908