示例#1
0
文件: xml.cpp 项目: 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;
}
示例#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;
    reel_list_t reel_list[MAX_REELS];

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

    opendcp = opendcp_create();

    /* 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->dcp.annotation,"%.128s",optarg);
            break;

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

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

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

            case 'h':
               dcp_usage();
            break;

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

            case 'k':
               sprintf(opendcp->dcp.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->dcp.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->dcp.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",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->dcp.aspect_ratio,"%d %d",width,height);
    }

    /* add pkl to the DCP (only one PKL currently support) */
    pkl_t pkl;
    create_pkl(opendcp->dcp, &pkl);
    add_pkl_to_dcp(&opendcp->dcp, pkl);

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

    /* set the callbacks (optional) for the digest generator */
    if (opendcp->log_level>0 && opendcp->log_level<3) {
        opendcp->dcp.sha1_update.callback = sha1_update_done_cb;
    }

    /* Add and validate reels */
    for (c = 0; c<reel_count; c++) {
        int a;
        reel_t reel;
        create_reel(opendcp->dcp, &reel);

        for (a = 0; a < reel_list[c].asset_count; a++) {
            val   = 0;
            asset_t asset;
            add_asset(opendcp, &asset, reel_list[c].asset_list[a].filename);
            sprintf(progress_string, "%-.25s %.25s", asset.filename, "Digest Calculation");
            total = atoi(asset.size) / read_size;
            if (opendcp->log_level>0 && opendcp->log_level<3) {
                printf("\n");
                progress_bar();
            }
            calculate_digest(opendcp, asset.filename, asset.digest);
            add_asset_to_reel(opendcp, &reel, asset);
        }

        if (validate_reel(opendcp, &reel, c) == OPENDCP_NO_ERROR) {
            add_reel_to_cpl(&opendcp->dcp.pkl[0].cpl[0], reel);
        } else {
            sprintf(buffer,"Could not validate reel %d\n",c+1);
            dcp_fatal(opendcp,buffer);
        }
    }

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

    /* Write CPL File */
    if (opendcp->log_level>0 && opendcp->log_level<3) {
        printf("\n");
        sprintf(progress_string, "%-.50s", opendcp->dcp.pkl[0].cpl[0].filename);
        progress_bar();
    }
    if (write_cpl(opendcp, &opendcp->dcp.pkl[0].cpl[0]) != OPENDCP_NO_ERROR)
        dcp_fatal(opendcp,"Writing composition playlist failed");

    /* Write PKL File */
    if (opendcp->log_level>0 && opendcp->log_level<3) {
        printf("\n");
        sprintf(progress_string, "%-.50s", opendcp->dcp.pkl[0].filename);
        progress_bar();
    }
    if (write_pkl(opendcp, &opendcp->dcp.pkl[0]) != OPENDCP_NO_ERROR)
        dcp_fatal(opendcp,"Writing packing list failed");

    if (opendcp->log_level>0 && opendcp->log_level<3) {
        printf("\n");
        sprintf(progress_string, "%-.50s", opendcp->dcp.assetmap.filename);
        progress_bar();
    }
    if (write_volumeindex(opendcp) != OPENDCP_NO_ERROR)
        dcp_fatal(opendcp,"Writing volume index failed");

    if (opendcp->log_level>0 && opendcp->log_level<3) {
        printf("\n");
        sprintf(progress_string, "%-.50s", opendcp->dcp.volindex.filename);
        progress_bar();
    }
    if (write_assetmap(opendcp) != OPENDCP_NO_ERROR)
        dcp_fatal(opendcp,"Writing asset map failed");

    dcp_log(LOG_INFO,"DCP Complete");

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

    opendcp_delete(opendcp);

    exit(0);
}