412{
414
415 QTemporaryFile tempFile;
416 QString tempFilePath;
417 if (tempFile.open()) {
418 tempFilePath = tempFile.fileName();
419 tempFile.close();
420 } else {
421 warnFile <<
"Failed to open temporary file:" << tempFile.errorString();
422
423 }
424
425 Context ctx(&outErrorMessage);
428
429
430 {
431 QJniObject outputPath = QJniObject::fromString(
settings().outputFile);
432 if (ctx.checkObject(QStringLiteral("outputPath"), outputPath)) {
434 }
435
436 QJniObject tempPath = QJniObject::fromString(tempFilePath);
437 if (ctx.checkObject(QStringLiteral("tempPath"), tempPath)) {
439 }
440
441 QJniObject encoderName = QJniObject::fromString(format->getEncoderPreference(
settings().formatPreferences));
442 ctx.checkException(QStringLiteral("encoderName"));
443
444 ctx.setEncoder(QJniObject("org/krita/android/VideoEncoder",
445 "(IIIFLjava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V",
446 jint(format->formatId()),
447 jint(outputWidth),
448 jint(outputHeight),
450 outputPath.object<jstring>(),
451 tempPath.object<jstring>(),
452 encoderName.object<jstring>(),
453 jint(format->getBitratePreference(
settings().formatPreferences))));
454 if (ctx.checkObject(QStringLiteral("encoder"), ctx.encoder())) {
456 }
457 }
458
461 }
462
463
464 {
465 QJniObject activity = QJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative",
466 "activity",
467 "()Landroid/app/Activity;");
468 if (ctx.checkObject(QStringLiteral("activity"), activity)) {
470 }
471
472 int startResult =
473 int(ctx.encoder().callMethod<jint>("start", "(Landroid/content/Context;)I", activity.object<jobject>()));
474 if (ctx.checkResult(QStringLiteral("start"), startResult)) {
476 }
477 }
478
479
480 Frame frame;
484 }
485
486
487 QImage inputImage;
488 AVPixelFormat inputPixelFormat;
489 if (frame.readImage(inputImage)) {
490 switch (inputImage.format()) {
491 case QImage::Format_RGB32:
492 inputPixelFormat = AV_PIX_FMT_BGR0;
493 break;
494 case QImage::Format_ARGB32:
495 inputPixelFormat = AV_PIX_FMT_BGRA;
496 break;
497 default:
498
499
500 inputPixelFormat = AV_PIX_FMT_BGRA;
501 inputImage = inputImage.convertToFormat(QImage::Format_ARGB32);
502 if (inputImage.isNull()) {
503 warnFile <<
"Frame conversion from" << inputImage.format() <<
"failed";
504 continue;
505 }
506 break;
507 }
508 } else {
509 continue;
510 }
511
512 int instances = frame.instances();
513 for (int i = 0; i < instances; ++i) {
514
517 return prepareResult;
518 }
519
520
521 EncoderImage encoderImage;
524 }
525
526
527
528
529
530 uint8_t *dstBuffers[4] = {nullptr, nullptr, nullptr, nullptr};
531 int dstLinesizes[4] = {0, 0, 0, 0};
532 AVPixelFormat outputPixelFormat;
533 if (encoderImage.pixelStrideU == 1 && encoderImage.pixelStrideV == 1) {
534
535 outputPixelFormat = AV_PIX_FMT_YUV420P;
536 dstBuffers[0] = encoderImage.bufferY;
537 dstBuffers[1] = encoderImage.bufferU;
538 dstBuffers[2] = encoderImage.bufferV;
539 dstLinesizes[0] = encoderImage.rowStrideY;
540 dstLinesizes[1] = encoderImage.rowStrideU;
541 dstLinesizes[2] = encoderImage.rowStrideV;
542
543 } else if (encoderImage.pixelStrideU == 2 && encoderImage.pixelStrideV == 2
544 && encoderImage.bufferU + 1 == encoderImage.bufferV) {
545
546 outputPixelFormat = AV_PIX_FMT_NV12;
547 dstBuffers[0] = encoderImage.bufferY;
548 dstBuffers[1] = encoderImage.bufferU;
549 dstLinesizes[0] = encoderImage.rowStrideY;
550 dstLinesizes[1] = encoderImage.rowStrideU;
551
552 } else if (encoderImage.pixelStrideU == 2 && encoderImage.pixelStrideV == 2
553 && encoderImage.bufferV + 1 == encoderImage.bufferU) {
554
555 outputPixelFormat = AV_PIX_FMT_NV21;
556 dstBuffers[0] = encoderImage.bufferY;
557 dstBuffers[1] = encoderImage.bufferV;
558 dstLinesizes[0] = encoderImage.rowStrideY;
559 dstLinesizes[1] = encoderImage.rowStrideV;
560
561 } else {
562 ctx.setInternalErrorMessage(QStringLiteral("unknown buffer format u%1/%2 v%3/%4")
563 .arg(quintptr(encoderImage.bufferU), 0, 16)
564 .arg(encoderImage.pixelStrideU)
565 .arg(quintptr(encoderImage.bufferV), 0, 16)
566 .arg(encoderImage.pixelStrideV));
568 }
569
570 SwsContext *swsContext = ctx.getSwsContextFor(inputImage.width(),
571 inputImage.height(),
572 inputPixelFormat,
573 outputWidth,
574 outputHeight,
575 outputPixelFormat,
576 SWS_FAST_BILINEAR);
577 if (!swsContext) {
578 ctx.setInternalErrorMessage(QStringLiteral("sws_getCachedContext"));
580 }
581
582 if (instances == 1) {
583
584 const uint8_t *srcBuffers[] = {inputImage.bits(), nullptr, nullptr, nullptr};
585 const int srcLinesizes[] = {inputImage.bytesPerLine(), 0, 0, 0};
586 sws_scale(swsContext, srcBuffers, srcLinesizes, 0, inputImage.height(), dstBuffers, dstLinesizes);
587
588 } else {
589
590
591 if (i == 0 || ctx.imageFormat() != outputPixelFormat) {
592 if (ctx.imageFormat() != outputPixelFormat) {
593 if (!ctx.allocateImage(outputWidth, outputHeight, outputPixelFormat)) {
594 warnFile <<
"Encoder changed pixel format from" << int(ctx.imageFormat()) <<
"to"
595 << int(outputPixelFormat);
597 }
598 }
599
600 const uint8_t *srcBuffers[] = {inputImage.bits(), nullptr, nullptr, nullptr};
601 const int srcLinesizes[] = {inputImage.bytesPerLine(), 0, 0, 0};
602 sws_scale(swsContext,
603 srcBuffers,
604 srcLinesizes,
605 0,
606 inputImage.height(),
607 ctx.imageBuffers(),
608 ctx.imageLinesizes());
609 }
610
611 av_image_copy2(dstBuffers,
612 dstLinesizes,
613 ctx.imageBuffers(),
614 ctx.imageLinesizes(),
615 outputPixelFormat,
616 outputWidth,
617 outputHeight);
618 }
619
620 int commitResult = int(ctx.encoder().callMethod<jint>("commit", "()I"));
621 if (ctx.checkResult(QStringLiteral("commit"), commitResult)) {
623 }
624 }
625 }
626
629 }
630
631
632 {
633
636 return prepareResult;
637 }
638
639 int finishResult = int(ctx.encoder().callMethod<jint>("finish", "()I"));
640 if (ctx.checkResult(QStringLiteral("finish"), finishResult)) {
642 }
643 }
644
645
646 while (true) {
647 int drainResult =
drain(ctx, 1000000LL);
649 break;
654 } else {
656 }
657 }
658
659
660 {
661 int closeResult = int(ctx.encoder().callMethod<jint>("close", "()I"));
662 if (ctx.checkResult(QStringLiteral("close"), closeResult)) {
664 }
665
668 }
669
673 }
674 }
675 }
676
678}