Exemplo n.º 1
0
Arquivo: xml.cpp Projeto: kzbb/OpenDCP
void MainWindow::startDcp()
{
    QString     path;
    QString     filename;
    QFileInfo   source;
    QFileInfo   destination;
    QMessageBox msgBox;
    QString     DCP_FAIL_MSG;

    asset_list_t reelList[MAX_REELS];

    opendcp_t *xmlContext = opendcp_create();

    DCP_FAIL_MSG = tr("DCP Creation Failed");

    // process options
    xmlContext->log_level = 0;

    if (ui->digitalSignatureCheckBox->checkState()) {
        xmlContext->xml_signature.sign = 1;
        xmlContext->xml_signature.use_external = 0;
    }

    dcp_log_init(xmlContext->log_level, ".log");
    strcpy(xmlContext->xml.title, ui->cplTitleEdit->text().toStdString().c_str());
    strcpy(xmlContext->xml.annotation, ui->cplAnnotationEdit->text().toStdString().c_str());
    strcpy(xmlContext->xml.issuer, ui->cplIssuerEdit->text().toStdString().c_str());
    strcpy(xmlContext->xml.kind, ui->cplKindComboBox->currentText().toStdString().c_str());
    strcpy(xmlContext->xml.rating, ui->cplRatingComboBox->currentText().toStdString().c_str());

    // check picture track is supplied
    if (ui->reelPictureEdit->text().isEmpty()) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                             tr("An MXF picture track is required."));
        goto Done;
    }

    // check durations
    if ((!ui->reelSoundEdit->text().isEmpty() && ui->reelPictureDurationSpinBox->value() != ui->reelSoundDurationSpinBox->value()) ||
        (!ui->reelSubtitleEdit->text().isEmpty() && ui->reelPictureDurationSpinBox->value() != ui->reelSubtitleDurationSpinBox->value())) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                              tr("The duration of all MXF tracks must be the same."));
        goto Done;
    }

    // copy assets
    reelList->asset_count = 0;
    if (!ui->reelPictureEdit->text().isEmpty()) {
        strcpy(reelList[0].asset_list[0].filename, ui->reelPictureEdit->text().toStdString().c_str());
        reelList->asset_count++;
    }
    if (!ui->reelSoundEdit->text().isEmpty()) {
        strcpy(reelList[0].asset_list[1].filename, ui->reelSoundEdit->text().toStdString().c_str());
        reelList->asset_count++;
    }
    if (!ui->reelSubtitleEdit->text().isEmpty()) {
        strcpy(reelList[0].asset_list[2].filename, ui->reelSubtitleEdit->text().toStdString().c_str());
        reelList->asset_count++;
    }

    // add pkl to the DCP (only one PKL currently support)
    add_pkl(xmlContext);

    // add cpl to the DCP/PKL (only one CPL currently support)
    add_cpl(xmlContext, &xmlContext->pkl[0]);

    if (add_reel(xmlContext, &xmlContext->pkl[0].cpl[0],reelList[0]) != OPENDCP_NO_ERROR) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                              tr("Could not add reel to CPL."));
        goto Done;
    }

    // adjust durations
    xmlContext->pkl[0].cpl[0].reel[0].asset[0].duration = ui->reelPictureDurationSpinBox->value();
    xmlContext->pkl[0].cpl[0].reel[0].asset[0].entry_point = ui->reelPictureOffsetSpinBox->value();
    xmlContext->pkl[0].cpl[0].reel[0].asset[1].duration = ui->reelSoundDurationSpinBox->value();
    xmlContext->pkl[0].cpl[0].reel[0].asset[1].entry_point = ui->reelSoundOffsetSpinBox->value();
    xmlContext->pkl[0].cpl[0].reel[0].asset[2].duration = ui->reelSubtitleDurationSpinBox->value();
    xmlContext->pkl[0].cpl[0].reel[0].asset[2].entry_point = ui->reelSubtitleOffsetSpinBox->value();

    if (validate_reel(xmlContext,&xmlContext->pkl[0].cpl[0],0) != OPENDCP_NO_ERROR) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                              tr("Could not valiate reel."));
        goto Done;
    }

    // set filenames
    path = QFileDialog::getExistingDirectory(this, tr("Choose destination folder"),QString::null);

    if (path.isEmpty()) {
        goto Done;
    }

    filename = path + "/" + xmlContext->pkl[0].cpl[0].uuid + "_cpl.xml";
    strcpy(xmlContext->pkl[0].cpl[0].filename,filename.toStdString().c_str());
    filename = path + "/" + xmlContext->pkl[0].uuid + "_pkl.xml";
    strcpy(xmlContext->pkl[0].filename,filename.toStdString().c_str());
    if (xmlContext->ns == XML_NS_SMPTE) {
        filename = path + "/" + "ASSETMAP.xml";
        strcpy(xmlContext->assetmap.filename,filename.toStdString().c_str());
        filename = path + "/" + "VOLINDEX.xml";
        strcpy(xmlContext->volindex.filename,filename.toStdString().c_str());
    } else {
        filename = path + "/" + "ASSETMAP";
        strcpy(xmlContext->assetmap.filename,filename.toStdString().c_str());
        filename = path + "/" + "VOLINDEX";
        strcpy(xmlContext->volindex.filename,filename.toStdString().c_str());
    }

    // write XML Files
    if (write_cpl(xmlContext,&xmlContext->pkl[0].cpl[0]) != OPENDCP_NO_ERROR) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                              tr("Failed to create composition playlist."));
        goto Done;
    }
    if (write_pkl(xmlContext,&xmlContext->pkl[0]) != OPENDCP_NO_ERROR) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                              tr("Failed to create packaging list."));
        goto Done;
    }
    if (write_volumeindex(xmlContext) != OPENDCP_NO_ERROR) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                              tr("Failed to create volume index."));
        goto Done;
    }
    if (write_assetmap(xmlContext) != OPENDCP_NO_ERROR) {
        QMessageBox::critical(this, DCP_FAIL_MSG,
                              tr("Failed to create assetmap."));
        goto Done;
    }

    // copy the picture mxf files
    source.setFile(xmlContext->pkl[0].cpl[0].reel[0].asset[0].filename);
    destination.setFile(path + "/" + source.fileName());

    if (!ui->reelPictureEdit->text().isEmpty() && source.absoluteFilePath() != destination.absoluteFilePath()) {
        if (destination.isFile()) {
            if (QMessageBox::question(this,tr("Move MXF File"),tr("The destination picture MXF already exists, do you want to replace?"),
                                      QMessageBox::No,QMessageBox::Yes) == QMessageBox::Yes) {
                QFile::remove(destination.absoluteFilePath());
            }
        }
        if (ui->rbMoveMxf->isChecked()) {
            QFile::rename(source.absoluteFilePath(), destination.absoluteFilePath());
        } else {
            //QMessageBox* msgBox = new QMessageBox( this );
            //msgBox->setWindowTitle("File Copy");
            //msgBox->setText("Copying picture file...");
            //msgBox->open();
            fileCopy(source.absoluteFilePath(), destination.absoluteFilePath());
            //msgBox->close();;
        }
    }

    // copy the sound mxf files
    source.setFile(xmlContext->pkl[0].cpl[0].reel[0].asset[1].filename);
    destination.setFile(path + "/" + source.fileName());
    if (!ui->reelSoundEdit->text().isEmpty() && source.absoluteFilePath() != destination.absoluteFilePath()) {
        if (destination.isFile()) {
            if (QMessageBox::question(this,tr("Move MXF File"),tr("The destination sound MXF already exists, do you want to replace?"),
                                      QMessageBox::No,QMessageBox::Yes) == QMessageBox::Yes) {
                QFile::remove(destination.absoluteFilePath());
            }
        }
        if (ui->rbMoveMxf->isChecked()) {
            QFile::rename(source.absoluteFilePath(), destination.absoluteFilePath());
        } else {
            QMessageBox* msgBox = new QMessageBox( this );
            //msgBox->setAttribute( QWidget::WA_DeleteOnClose );
            msgBox->setWindowTitle("File Copy");
            msgBox->setText("Copying sound file...");
            msgBox->open();
            QFile::copy(source.absoluteFilePath(), destination.absoluteFilePath());
            msgBox->close();
        }
    }

    // copy the subtitle mxf files
    source.setFile(xmlContext->pkl[0].cpl[0].reel[0].asset[2].filename);
    destination.setFile(path + "/" + source.fileName());
    if (!ui->reelSubtitleEdit->text().isEmpty() && source.absoluteFilePath() != destination.absoluteFilePath()) {
        if (destination.isFile()) {
            if (QMessageBox::question(this,tr("Move MXF File"),tr("The destination subtitle MXF already exists, do you want to replace?"),
                                      QMessageBox::No,QMessageBox::Yes) == QMessageBox::Yes) {
                QFile::remove(destination.absoluteFilePath());
            }
        }
        if (ui->rbMoveMxf->isChecked()) {
            QFile::rename(source.absoluteFilePath(), destination.absoluteFilePath());
        } else {
            QMessageBox* msgBox = new QMessageBox( this );
            msgBox->setWindowTitle("File Copy");
            msgBox->setText("Copying subtitle file...");
            msgBox->open();
            QFile::copy(source.absoluteFilePath(), destination.absoluteFilePath());
            msgBox->close();;
        }
    }

    msgBox.setText("DCP Created successfully");
    msgBox.exec();


Done:
    opendcp_delete(xmlContext);

    return;
}
Exemplo n.º 2
0
int main (int argc, char **argv) {
    int c,j;
    int reel_count=0;
    int height = 0;
    int width  = 0;
    char buffer[80];
    opendcp_t *opendcp;
    asset_list_t reel_list[MAX_REELS];

    if ( argc <= 1 ) {
        dcp_usage();
    }

    opendcp = create_opendcp();

    /* parse options */
    while (1)
    {
        static struct option long_options[] =
        {
            {"annotation",     required_argument, 0, 'a'},
            {"base",           required_argument, 0, 'b'},
            {"digest",         no_argument,       0, 'd'},
            {"duration",       required_argument, 0, 'n'},
            {"entry",          required_argument, 0, 'e'},
            {"help",           no_argument,       0, 'h'},
            {"issuer",         required_argument, 0, 'i'},
            {"kind",           required_argument, 0, 'k'},
            {"log_level",      required_argument, 0, 'l'},
            {"rating",         required_argument, 0, 'm'},
            {"reel",           required_argument, 0, 'r'},
            {"title",          required_argument, 0, 't'},
            {"root",           required_argument, 0, '1'},
            {"ca",             required_argument, 0, '2'},
            {"signer",         required_argument, 0, '3'},
            {"privatekey",     required_argument, 0, 'p'},
            {"sign",           no_argument,       0, 's'},
            {"height",         required_argument, 0, 'y'},
            {"width",          required_argument, 0, 'x'},
            {"version",        no_argument,       0, 'v'},
            {0, 0, 0, 0}
        };

        /* getopt_long stores the option index here. */
        int option_index = 0;
     
        c = getopt_long (argc, argv, "a:b:e:svdhi:k:r:l:m:n:t:x:y:p:1:2:3:",
                         long_options, &option_index);

        /* Detect the end of the options. */
        if (c == -1)
            break;
     
        switch (c)
        {
            case 0:
                /* If this option set a flag, do nothing else now. */
                if (long_options[option_index].flag != 0)
                   break;
            break;

            case 'a':
               sprintf(opendcp->xml.annotation,"%.128s",optarg);
            break;

            case 'b':
               sprintf(opendcp->xml.basename,"%.80s",optarg);
            break;

            case 'd':
               opendcp->xml.digest_flag = 1;
            break;

            case 'e':
               opendcp->entry_point = atoi(optarg);
            break;

            case 'h':
               dcp_usage();
            break;
     
            case 'i':
               sprintf(opendcp->xml.issuer,"%.80s",optarg);
            break;

            case 'k':
               sprintf(opendcp->xml.kind,"%.15s",optarg);
            break;

            case 'l':
               opendcp->log_level = atoi(optarg);
            break;

            case 'm':
               if ( !strcmp(optarg,"G")
                    || !strcmp(optarg,"PG")
                    || !strcmp(optarg,"PG-13")
                    || !strcmp(optarg,"R")
                    || !strcmp(optarg,"NC-17") ) {
                   sprintf(opendcp->xml.rating,"%.5s",optarg);
               } else {
                   sprintf(buffer,"Invalid rating %s\n",optarg);
                   dcp_fatal(opendcp,buffer);
               }
            break;

            case 'n':
               opendcp->duration = atoi(optarg);
            break;
     
            case 'r':
               j = 0;
               optind--;
               while ( optind<argc && strncmp("-",argv[optind],1) != 0) {
				   sprintf(reel_list[reel_count].asset_list[j++].filename,"%s",argv[optind++]);
               }
               reel_list[reel_count++].asset_count = j--;
            break;

#ifdef XMLSEC
            case 's':
                opendcp->xml_signature.sign = 1;

            break;
#endif

            case 't':
               sprintf(opendcp->xml.title,"%.80s",optarg);
            break;

            case 'x':
               width = atoi(optarg);
            break;

            case 'y':
               height = atoi(optarg);
            break;

            case '1':
               opendcp->xml_signature.root = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case '2':
               opendcp->xml_signature.ca = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case '3':
               opendcp->xml_signature.signer = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case 'p':
               opendcp->xml_signature.private_key = optarg;
               opendcp->xml_signature.use_external = 1;
            break;

            case 'v':
               version();
            break;

            default:
               dcp_usage();
        }
    }

    /* set log level */
    dcp_set_log_level(opendcp->log_level);

    if (opendcp->log_level > 0) {
        printf("\nOpenDCP XML %s %s\n\n",OPENDCP_VERSION,OPENDCP_COPYRIGHT);
    }

    if (reel_count < 1) {
        dcp_fatal(opendcp,"No reels supplied");
    }

    /* check cert files */
    if (opendcp->xml_signature.sign && opendcp->xml_signature.use_external == 1) {
        FILE *tp;
        if (opendcp->xml_signature.root) {
            tp = fopen(opendcp->xml_signature.root,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read root certificate");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but root certificate file not specified");
        }
        if (opendcp->xml_signature.ca) {
            tp = fopen(opendcp->xml_signature.ca,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read ca certificate");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but ca certificate file not specified");
        }
        if (opendcp->xml_signature.signer) {
            tp = fopen(opendcp->xml_signature.signer,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read signer certificate");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but signer certificate file not specified");
        }
        if (opendcp->xml_signature.private_key) {
            tp = fopen(opendcp->xml_signature.private_key,"rb");
            if (tp) {
                fclose(tp);
            } else {
                dcp_fatal(opendcp,"Could not read private key file");
            }
        } else {
            dcp_fatal(opendcp,"XML digital signature certifcates enabled, but private key file not specified");
        }
    }
  
    /* set aspect ratio override */
    if (width || height) {
        if (!height) {
            dcp_fatal(opendcp,"You must specify height, if you specify width");
        }

        if (!width) {
            dcp_fatal(opendcp,"You must specify widht, if you specify height");
        }

        sprintf(opendcp->xml.aspect_ratio,"%d %d",width,height);
    }

    /* add pkl to the DCP (only one PKL currently support) */
    add_pkl(opendcp);

    /* add cpl to the DCP/PKL (only one CPL currently support) */
    add_cpl(opendcp, &opendcp->pkl[0]);

    /* Add and validate reels */
    for (c = 0;c<reel_count;c++) {
        if (add_reel(opendcp, &opendcp->pkl[0].cpl[0], reel_list[c]) != DCP_SUCCESS) {
            sprintf(buffer,"Could not add reel %d to DCP\n",c+1); 
            dcp_fatal(opendcp,buffer);
        }
       if (validate_reel(opendcp, &opendcp->pkl[0].cpl[0], c) != DCP_SUCCESS) {
            sprintf(buffer,"Could validate reel %d\n",c+1); 
            dcp_fatal(opendcp,buffer);
       }
    }

    /* set ASSETMAP/VOLINDEX path */
    if (opendcp->ns == XML_NS_SMPTE) {
        sprintf(opendcp->assetmap.filename,"%s","ASSETMAP.xml");
        sprintf(opendcp->volindex.filename,"%s","VOLINDEX.xml");
    } else {
        sprintf(opendcp->assetmap.filename,"%s","ASSETMAP");
        sprintf(opendcp->volindex.filename,"%s","VOLINDEX");
    }

    /* Write XML Files */
    if (write_cpl(opendcp, &opendcp->pkl[0].cpl[0]) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing composition playlist failed");
    if (write_pkl(opendcp, &opendcp->pkl[0]) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing packing list failed");
    if (write_volumeindex(opendcp) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing volume index failed");
    if (write_assetmap(opendcp) != DCP_SUCCESS)
        dcp_fatal(opendcp,"Writing asset map failed");

    dcp_log(LOG_INFO,"DCP Complete");

    if (opendcp->log_level > 0) {
        printf("\n");
    }

    delete_opendcp(opendcp);

    exit(0);
}