I encode a video stream using ffmeg. QT Creator Shell. OC Windows 7. C ++ language. Compiler MinGW. H264 codec.
There is a function to which I give a frame to the input, and I must return the encoded byte array. Inside this function, there is a hangup when calling avcodec_encode_video2, but not on the first call, but on arbitrary. That is, on some (random) coding of the frame hangs (from 100 to 10000).
QByteArray VideoEncoder::createFrameVideoFromImage(QImage picture) { //ΡΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΠΏΡΡΡΠΎΠΉ ΠΊΠ°Π΄Ρ ΠΈ Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠΎΠ΄ Π½Π΅Π³ΠΎ ΠΏΠ°ΠΌΡΡΡ... AVFrame* frame_source = av_frame_alloc(); //ΠΠ°ΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π² ΡΡΠΎΡ ΠΊΠ°Π΄Ρ Π±ΠΈΡΡ ΡΠΈΡΡΠ½ΠΊΠ°... avpicture_fill((AVPicture*)frame_source, picture.bits(), AV_PIX_FMT_RGB24, this->width_frame, this->height_frame); //Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΡΡΡΠΎΠΉ ΠΊΠ°Π΄Ρ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡΡΡ ΠΊΠ°Π΄Ρ Π² YUV AVFrame* frame_dst = av_frame_alloc(); //ΠΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠΎΠ΄ Π½Π΅Π³ΠΎ Π½ΡΠΆΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΠ°ΠΌΡΡΠΈ avpicture_fill((AVPicture*)frame_dst, (uint8_t*)this->inbuffer, AV_PIX_FMT_YUV420P, this->width_frame, this->height_frame); //ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ°Π΄ΡΠ° Π² RGB Π² ΠΊΠ°Π΄Ρ YUV sws_scale(this->convert_rgb_yuv, frame_source->data, frame_source->linesize, 0, this->ctx_codec_in->height, frame_dst->data, frame_dst->linesize); // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ°ΠΊΠ΅Ρ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΠΈΡΠ°Π½ Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Π΄Ρ AVPacket packet; av_init_packet(&packet); packet.data = NULL; packet.size = 0; packet.pts = packet.dts = AV_NOPTS_VALUE; // ΠΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ°Π΄ΡΠ° Π² Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Π΄Ρ... int nOutputSize = 0; if (avcodec_encode_video2(this->ctx_codec_in, &packet, frame_dst, &nOutputSize) < 0) { qDebug() << "VideoEncoder error"; } this->traffic += packet.size; //ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠΉ Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Π΄Ρ Π² ΠΌΠ°ΡΡΠΈΠ² Π±Π°ΠΉΡ QByteArray data_frame = QByteArray((char*)packet.data, packet.size); //ΠΡΠΈΡΡΠΊΠ° ΠΏΠ°ΠΌΡΡΠΈ av_frame_free(&frame_source); av_frame_free(&frame_dst); av_free_packet(&packet); return data_frame; }
Who can help? Thank you in advance!
picture
gets intoframe_dst
? - Cerboavpicture_fill
puts thepicture
in theframe_source
, then sws_scale puts the frame in theframe_dst
of theframe_sourse
. - Ivan Chvanovsws_getContext()
call - Yaroslavthis->convert_rgb_yuv = sws_getContext(this->ctx_codec_in->width, this->ctx_codec_in->height, AV_PIX_FMT_RGB24, this->ctx_codec_in->width, this->ctx_codec_in->height, this->ctx_codec_in->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
- Ivan Chvanov