5 #pragma warning(disable : 4996)
10 #include "libavcodec/avcodec.h"
11 #include "libavformat/avformat.h"
12 #include "libavformat/avio.h"
13 #include "libavutil/avstring.h"
14 #include "libavutil/error.h"
15 #include "libavutil/frame.h"
16 #include "libavutil/imgutils.h"
17 #include "libavutil/mathematics.h"
18 #include "libavutil/opt.h"
19 #include "libavutil/rational.h"
20 #include "libswscale/swscale.h"
23 #if LIBAVCODEC_VERSION_MAJOR < 59
24 #define cloudViewer_ff_const59
26 #define cloudViewer_ff_const59 const
89 int ret = av_frame_get_buffer(
m_ff->
frame, 32);
91 fprintf(stderr,
"Could not allocate frame data.\n");
105 #if LIBAVCODEC_VERSION_MAJOR < 59
107 std::vector<OutputFormat> &formats,
108 bool ignoreIfNoFileExtension ) {
116 AVOutputFormat *
format = av_oformat_next(prev);
120 if (
format->video_codec != AV_CODEC_ID_NONE &&
121 (!ignoreIfNoFileExtension ||
129 formats.push_back(f);
136 }
catch (
const std::bad_alloc &) {
145 std::vector<OutputFormat> &formats,
146 bool ignoreIfNoFileExtension ) {
149 void *ofmt_opaque =
nullptr;
152 av_muxer_iterate(&ofmt_opaque);
156 if (
format->video_codec != AV_CODEC_ID_NONE &&
157 (!ignoreIfNoFileExtension ||
161 f.shortName =
format->name;
162 f.longName =
format->long_name;
163 f.extensions =
format->extensions;
165 formats.push_back(f);
171 }
catch (
const std::bad_alloc &) {
187 errors <<
"Invalid video size";
192 if (!formatShortName.isEmpty()) {
194 av_guess_format(qPrintable(formatShortName),
nullptr,
nullptr);
196 errors <<
"Could not find output format from short name: " +
202 avformat_alloc_output_context2(
204 outputFormat ? qPrintable(
m_filename) :
nullptr);
207 errors <<
"Could not deduce output format from file extension: "
213 errors <<
"Codec not found";
217 errors <<
"Failed to initialize the output context with the "
218 "specified output format: " +
230 errors <<
"Could not load the codec";
251 if (codec_id == AV_CODEC_ID_H264) {
253 }
else if (codec_id == AV_CODEC_ID_MPEG1VIDEO) {
268 errors <<
"Failed to allocate the output stream";
282 errors <<
"Could not open the codec";
288 errors <<
"Could not init the internal frame";
293 AVIO_FLAG_WRITE) < 0) {
294 errors << QString(
"Could not open '%1'").arg(
m_filename);
301 errors << QString(
"Could not write header for '%1'").arg(
m_filename);
339 #if LIBAVCODEC_VERSION_MAJOR >= 58
340 AVPacket *pkt = av_packet_alloc();
346 av_packet_free(&pkt);
350 av_packet_free(&pkt);
353 memset(&pkt, 0,
sizeof(AVPacket));
354 av_init_packet(&pkt);
360 av_packet_unref(&pkt);
367 #if LIBAVCODEC_VERSION_MAJOR >= 59
383 #if LIBAVFORMAT_VERSION_MAJOR >= 59
396 QString *errorString ) {
398 if (errorString) *errorString =
"Stream is not opened";
416 char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0};
417 av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, ret);
420 QString(
"Error encoding video frame: %1").arg(errorStr);
425 #if LIBAVCODEC_VERSION_MAJOR >= 58
426 AVPacket *pkt = av_packet_alloc();
429 *errorString =
"Failed to allocate packet";
433 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
434 av_packet_free(&pkt);
436 }
else if (ret < 0) {
437 char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0};
438 av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, ret);
440 *errorString = QString(
"Error receiving video frame: %1")
442 av_packet_free(&pkt);
448 char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0};
449 av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, wRet);
452 QString(
"Error while writing video frame: %1")
454 av_packet_free(&pkt);
457 av_packet_free(&pkt);
460 memset(&pkt, 0,
sizeof(AVPacket));
461 av_init_packet(&pkt);
463 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
465 }
else if (ret < 0) {
466 char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0};
467 av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, ret);
469 *errorString = QString(
"Error receiving video frame: %1")
476 char errorStr[AV_ERROR_MAX_STRING_SIZE] = {0};
477 av_make_error_string(errorStr, AV_ERROR_MAX_STRING_SIZE, wRet);
480 QString(
"Error while writing video frame: %1")
484 av_packet_unref(&pkt);
493 QString *errorString ) {
496 if (errorString) *errorString =
"Wrong image size";
501 if (
format != QImage::Format_RGB32 &&
format != QImage::Format_ARGB32 &&
502 format != QImage::Format_ARGB32_Premultiplied) {
503 if (errorString) *errorString =
"Wrong image format";
510 AV_PIX_FMT_YUV420P, SWS_BICUBIC,
511 nullptr,
nullptr,
nullptr);
515 *errorString =
"[SWS] Cannot initialize the conversion context";
521 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
522 if (num_bytes !=
static_cast<int>(
image.sizeInBytes())) {
524 if (num_bytes !=
image.byteCount()) {
526 if (errorString) *errorString =
"[SWS] Number of bytes mismatch";
530 const uint8_t *srcSlice[3] = {
531 static_cast<const uint8_t *
>(
image.constBits()), 0, 0};
532 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
533 int srcStride[3] = {
static_cast<int>(
image.bytesPerLine()), 0, 0};
535 int srcStride[3] = {
image.bytesPerLine(), 0, 0};
std::shared_ptr< core::Tensor > image
filament::Texture::InternalFormat format
#define cloudViewer_ff_const59
static int write_frame(FFmpegStuffEnc *ff, AVPacket *pkt)
virtual bool encodeImage(const QImage &image, int frameIndex, QString *errorString=nullptr)
Adds an image to the stream.
bool isSizeValid()
Returns whether the image size is valid.
virtual bool close()
Closes the file.
bool convertImage_sws(const QImage &image, QString *errorString=nullptr)
Convert the QImage to the internal YUV format.
bool open(QString formatShortName, QStringList &errors)
Creates an (empty) video/anmiation file.
bool isOpen() const
Returns whether the file is opened or not.
static bool GetSupportedOutputFormats(std::vector< OutputFormat > &formats, bool ignoreIfNoFileExtension=true)
Returns the list of supported output formats.
FFmpegStuffEnc * m_ff
FFmpeg variables.
QVideoEncoder(QString filename, int width, int height, unsigned bitrate, int gop=12, int fps=25)
Default constructor.
AVFormatContext * formatContext
AVCodecContext * codecContext