예제 #1
0
void
MediaRecorder::BeginRecordingThread(void *data)
{
    nsresult rv;
    MediaRecorder *mr = static_cast<MediaRecorder*>(data);
    
    /* Get ready for video! */
    if (mr->params->video) {
        mr->SetupTheoraBOS();
        rv = mr->MakePipe(
            getter_AddRefs(mr->vState->vPipeIn),
            getter_AddRefs(mr->vState->vPipeOut)
        );
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not create video pipe"
            ));
            return;
        }
    }

    /* Get ready for audio! */
    if (mr->params->audio) {
        mr->SetupVorbisBOS();
        rv = mr->MakePipe(
            getter_AddRefs(mr->aState->aPipeIn),
            getter_AddRefs(mr->aState->aPipeOut)
        );
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not create audio pipe"
            ));
            return;
        }
    }
    
    if (mr->params->video) {
        mr->v_rec = PR_TRUE;
        mr->v_stp = PR_FALSE;
        mr->SetupTheoraHeaders();
        mr->vState->backend->StartRecording(mr->vState->vPipeOut);
    }

    if (mr->params->audio) {
        mr->SetupVorbisHeaders();
        rv = mr->aState->backend->Start(mr->aState->aPipeOut);
        if (NS_FAILED(rv)) {
            /* FIXME: Stop and clean up video! */
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not start audio recording"
            ));
            return;
        }
        mr->a_rec = PR_TRUE;
        mr->a_stp = PR_FALSE;
    }
    
    /* Start off encoder after notifying observer */
    NS_DispatchToMainThread(new MediaCallback(
        mr->observer, "record-began", ""
    ));
    mr->Encode();
}
예제 #2
0
/*
 * Start recording (called in a thread)
 */
void
MediaRecorder::Record(void *data)
{   
    nsresult rv;
    MediaRecorder *mr = static_cast<MediaRecorder*>(data);
    Properties *params = mr->params;
    
    if (mr->a_rec || mr->v_rec) {
        NS_DispatchToMainThread(new MediaCallback(
            mr->observer, "error", "recording already in progress"
        ));
        return;
    }

    /* Setup backends */
    #ifdef RAINBOW_Mac
    mr->aState->backend = new AudioSourceMac(params->chan, params->rate);
    mr->vState->backend = new VideoSourceMac(params->width, params->height);
    #endif
    #ifdef RAINBOW_Win
    mr->aState->backend = new AudioSourceWin(params->chan, params->rate);
    mr->vState->backend = new VideoSourceWin(params->width, params->height);
    #endif
    #ifdef RAINBOW_Nix
    mr->aState->backend = new AudioSourceNix(params->chan, params->rate);
    mr->vState->backend = new VideoSourceNix(params->width, params->height);
    #endif
 
    /* Is the given canvas source or destination? */
    if (params->canvas) {
        mr->vState->backend = new VideoSourceCanvas(params->width, params->height);
    }
       
    /* Update parameters. What we asked for were just hints,
     * may not end up the same */
    params->fps_n = mr->vState->backend->GetFPSN();
    params->fps_d = mr->vState->backend->GetFPSD();
    params->rate = mr->aState->backend->GetRate();
    params->chan = mr->aState->backend->GetChannels();

    /* FIXME: device detection TBD */
    if (params->audio && (mr->aState == nsnull)) {
        NS_DispatchToMainThread(new MediaCallback(
            mr->observer, "error", "audio requested but no devices found"
        ));
        return;
    }
    if (params->video && (mr->vState == nsnull)) {
        NS_DispatchToMainThread(new MediaCallback(
            mr->observer, "error", "video requested but no devices found"
        ));
        return;
    }

    /* Get ready for video! */
    if (params->video) {
        mr->SetupTheoraBOS();
        rv = mr->MakePipe(
            getter_AddRefs(mr->vState->vPipeIn),
            getter_AddRefs(mr->vState->vPipeOut)
        );
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not create video pipe"
            ));
            return;
        }
    }

    /* Get ready for audio! */
    if (params->audio) {
        mr->SetupVorbisBOS();
        rv = mr->MakePipe(
            getter_AddRefs(mr->aState->aPipeIn),
            getter_AddRefs(mr->aState->aPipeOut)
        );
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not create audio pipe"
            ));
            return;
        }
    }

    /* Let's DO this. */
    if (params->video) {
        mr->SetupTheoraHeaders();
        rv = mr->vState->backend->Start(mr->vState->vPipeOut, mr->canvas);
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not start video recording"
            ));
            return;
        }
        mr->v_rec = PR_TRUE;
        mr->v_stp = PR_FALSE;
    }
    if (params->audio) {
        mr->SetupVorbisHeaders();
        rv = mr->aState->backend->Start(mr->aState->aPipeOut);
        if (NS_FAILED(rv)) {
            /* FIXME: Stop and clean up video! */
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not start audio recording"
            ));
            return;
        }
        mr->a_rec = PR_TRUE;
        mr->a_stp = PR_FALSE;
    }

    /* Start off encoder after notifying observer */
    NS_DispatchToMainThread(new MediaCallback(
        mr->observer, "started", ""
    ));
    mr->Encode();
    return;
}