apply ffmpeg options on context if not null

This commit is contained in:
wang-bin
2014-11-26 18:12:11 +08:00
parent 458995ac81
commit 8ff18daa95
2 changed files with 58 additions and 12 deletions
+23 -4
View File
@@ -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<QString, QVariant> 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<QString, QVariant> 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);
}
}
}
+35 -8
View File
@@ -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<QString, QVariant> 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<QString, QVariant> 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