bool QVideoEncoder::encodeImage(const QImage &image, int frameIndex, QString* errorString/*=0*/) { if (!isOpen()) { if (errorString) *errorString = "Stream is not opened"; return false; } // SWS conversion if (!convertImage_sws(image, errorString)) { return false; } AVPacket pkt = { 0 }; av_init_packet(&pkt); // encode the image int got_packet = 0; { //compute correct timestamp based on the input frame index //int timestamp = ((m_ff->codecContext->time_base.num * 90000) / m_ff->codecContext->time_base.den) * frameIndex; m_ff->frame->pts = frameIndex/*timestamp*/; int ret = avcodec_encode_video2(m_ff->codecContext, &pkt, m_ff->frame, &got_packet); if (ret < 0) { char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0}; av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, ret); if (errorString) *errorString = QString("Error encoding video frame: %1").arg(errorStr); return false; } } if (got_packet) { int ret = write_frame(m_ff, &pkt); if (ret < 0) { char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0}; av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, ret); if (errorString) *errorString = QString("Error while writing video frame: %1").arg(errorStr); return false; } } av_packet_unref(&pkt); return true; }
/** \brief Encode one frame - internal function custompts: true if a custom presentation time stamp is used pts: presentation time stamp in milliseconds **/ int QVideoEncoder::encodeImage_p(const QImage &img,bool custompts, unsigned pts) { if(!isOk()) return -1; //convertImage(img); // Custom conversion routine convertImage_sws(img); // SWS conversion if(custompts) // Handle custom pts pCodecCtx->coded_frame->pts = pts; // Set the time stamp int out_size = ffmpeg::avcodec_encode_video(pCodecCtx,outbuf,outbuf_size,ppicture); //printf("Frame size: %d\n",out_size); if(custompts) // Handle custom pts (must set it again for the rest of the processing) pCodecCtx->coded_frame->pts = pts; // Set the time stamp if (out_size > 0) { av_init_packet(&pkt); //if (pCodecCtx->coded_frame->pts != AV_NOPTS_VALUE) if (pCodecCtx->coded_frame->pts != (0x8000000000000000LL)) pkt.pts= av_rescale_q(pCodecCtx->coded_frame->pts, pCodecCtx->time_base, pVideoStream->time_base); if(pCodecCtx->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY; //printf("c %d. pts %d. codedframepts: %ld pkt.pts: %ld\n",custompts,pts,pCodecCtx->coded_frame->pts,pkt.pts); pkt.stream_index= pVideoStream->index; pkt.data= outbuf; pkt.size= out_size; int ret = av_interleaved_write_frame(pFormatCtx, &pkt); //printf("Wrote %d\n",ret); if(ret<0) return -1; } return out_size; }