diff --git a/src/AVDemuxer.cpp b/src/AVDemuxer.cpp index aae8b7d8..4649728d 100644 --- a/src/AVDemuxer.cpp +++ b/src/AVDemuxer.cpp @@ -454,6 +454,7 @@ bool AVDemuxer::seek(qint64 pos) } //bool seek_bytes = !!(format_context->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", format_context->iformat->name); int ret = av_seek_frame(format_context, -1, upos, seek_flag); + //int ret = avformat_seek_file(format_context, -1, INT64_MIN, upos, upos, seek_flag); //avformat_seek_file() #endif if (ret < 0) { @@ -1147,10 +1148,19 @@ void AVDemuxer::setOptions(const QVariantHash &dict) QMapIterator i(avformat_dict); while (i.hasNext()) { i.next(); - if (i.value().type() == QVariant::Map) + const QVariant::Type vt = i.value().type(); + if (vt == QVariant::Map) continue; - av_dict_set(&mpDict, i.key().toUtf8().constData(), i.value().toByteArray().constData(), 0); + const QByteArray key(i.key().toLower().toUtf8()); + av_dict_set(&mpDict, key.constData(), i.value().toByteArray().constData(), 0); // toByteArray: bool is "true" "false" qDebug("avformat option: %s=>%s", i.key().toUtf8().constData(), i.value().toByteArray().constData()); + if (!format_context) + continue; + if (vt == QVariant::Int || vt == QVariant::UInt || vt == QVariant::Bool) { + av_opt_set_int(format_context, key.constData(), i.value().toInt(), 0); + } else if (vt == QVariant::LongLong || vt == QVariant::ULongLong) { + av_opt_set_int(format_context, key.constData(), i.value().toLongLong(), 0); + } } return; } @@ -1161,10 +1171,19 @@ void AVDemuxer::setOptions(const QVariantHash &dict) QHashIterator i(avformat_dict); while (i.hasNext()) { i.next(); - if (i.value().type() == QVariant::Hash) + const QVariant::Type vt = i.value().type(); + if (vt == QVariant::Hash) continue; - av_dict_set(&mpDict, i.key().toUtf8().constData(), i.value().toByteArray().constData(), 0); + const QByteArray key(i.key().toLower().toUtf8()); + av_dict_set(&mpDict, key.constData(), i.value().toByteArray().constData(), 0); // toByteArray: bool is "true" "false" qDebug("avformat option: %s=>%s", i.key().toUtf8().constData(), i.value().toByteArray().constData()); + if (!format_context) + continue; + if (vt == QVariant::Int || vt == QVariant::UInt || vt == QVariant::Bool) { + av_opt_set_int(format_context, key.constData(), i.value().toInt(), 0); + } else if (vt == QVariant::LongLong || vt == QVariant::ULongLong) { + av_opt_set_int(format_context, key.constData(), i.value().toLongLong(), 0); + } } } diff --git a/src/codec/AVDecoder.cpp b/src/codec/AVDecoder.cpp index d5c0b07d..2e86d3f8 100644 --- a/src/codec/AVDecoder.cpp +++ b/src/codec/AVDecoder.cpp @@ -101,12 +101,13 @@ bool AVDecoder::open() qWarning("Use the max value for lowres supported by the decoder (%d)", codec->max_lowres); d.low_resolution = codec->max_lowres; } + //CODEC_FLAG_EMU_EDGE: deprecated in ffmpeg >=? & libav>=10. always set by ffmpeg d.codec_ctx->lowres = d.low_resolution; if (d.codec_ctx->lowres) { d.codec_ctx->flags |= CODEC_FLAG_EMU_EDGE; } if (d.fast) { - d.codec_ctx->flags2 |= CODEC_FLAG2_FAST; + d.codec_ctx->flags2 |= CODEC_FLAG2_FAST; // TODO: } else { //d.codec_ctx->flags2 &= ~CODEC_FLAG2_FAST; //ffplay has no this } @@ -271,7 +272,7 @@ bool AVDecoder::prepare() qWarning("call this after AVCodecContext is set!"); return false; } - qDebug("Decoding threads count: %d", d.threads); + qDebug("Decoding threads count: %d", d.threads); //TODO: remove return true; } @@ -308,17 +309,30 @@ void AVDecoder::setOptions(const QVariantHash &dict) if (opt.type() == QVariant::Hash) { QVariantHash avcodec_dict = opt.toHash(); // workaround for VideoDecoderFFmpeg. now it does not call av_opt_set_xxx, so set here in dict - if (dict.contains("FFmpeg")) - avcodec_dict.unite(dict.value("FFmpeg").toHash()); + // TODO: wrong if opt is empty + //if (dict.contains("FFmpeg")) + // avcodec_dict.unite(dict.value("FFmpeg").toHash()); QHashIterator i(avcodec_dict); while (i.hasNext()) { i.next(); + const QByteArray key(i.key().toLower().toUtf8()); switch (i.value().type()) { case QVariant::Hash: // for example "vaapi": {...} continue; case QVariant::Bool: + case QVariant::Int: { // QVariant.toByteArray(): "true" or "false", can not recognized by avcodec - av_dict_set(&d.dict, i.key().toLower().toUtf8().constData(), QByteArray::number(i.value().toBool()), 0); + av_dict_set(&d.dict, key.constData(), QByteArray::number(i.value().toInt()).constData(), 0); + if (d.codec_ctx) + av_opt_set_int(d.codec_ctx, key.constData(), i.value().toInt(), 0); + } + break; + case QVariant::ULongLong: + case QVariant::LongLong: { + av_dict_set(&d.dict, key.constData(), QByteArray::number(i.value().toLongLong()).constData(), 0); + if (d.codec_ctx) + av_opt_set_int(d.codec_ctx, key.constData(), i.value().toLongLong(), 0); + } break; default: // avcodec key and value are in lower case @@ -330,17 +344,30 @@ void AVDecoder::setOptions(const QVariantHash &dict) } else if (opt.type() == QVariant::Map) { QVariantMap avcodec_dict = opt.toMap(); // workaround for VideoDecoderFFmpeg. now it does not call av_opt_set_xxx, so set here in dict - if (dict.contains("FFmpeg")) - avcodec_dict.unite(dict.value("FFmpeg").toMap()); + //if (dict.contains("FFmpeg")) + // avcodec_dict.unite(dict.value("FFmpeg").toMap()); QMapIterator i(avcodec_dict); while (i.hasNext()) { i.next(); + const QByteArray key(i.key().toLower().toUtf8()); switch (i.value().type()) { case QVariant::Map: // for example "vaapi": {...} continue; case QVariant::Bool: + case QVariant::UInt: + case QVariant::Int: { // QVariant.toByteArray(): "true" or "false", can not recognized by avcodec - av_dict_set(&d.dict, i.key().toLower().toUtf8().constData(), QByteArray::number(i.value().toBool()), 0); + av_dict_set(&d.dict, key.constData(), QByteArray::number(i.value().toInt()), 0); + if (d.codec_ctx) + av_opt_set_int(d.codec_ctx, key.constData(), i.value().toInt(), 0); + } + break; + case QVariant::ULongLong: + case QVariant::LongLong: { + av_dict_set(&d.dict, key.constData(), QByteArray::number(i.value().toLongLong()).constData(), 0); + if (d.codec_ctx) + av_opt_set_int(d.codec_ctx, key.constData(), i.value().toLongLong(), 0); + } break; default: // avcodec key and value are in lower case