Gecko:MediaRecorder: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
<p>Reference spec: <br>
=Reference spec:=
https://dvcs.w3.org/hg/dap/raw-file/tip/media-stream-capture/RecordingProposal.html <br>
https://dvcs.w3.org/hg/dap/raw-file/tip/media-stream-capture/RecordingProposal.html <br>
bugs: <br>
bugs: <br>
Line 14: Line 14:
[[File:MediaRecorder Arch.jpg|400px ]]
[[File:MediaRecorder Arch.jpg|400px ]]


<p>API Draft(incomplete 2013/01/29) </p>
=API Draft(incomplete 2013/01/29)=
<code>
<code>
  class MediaSegmentAdapter {  
  class MediaSegmentAdapter {  
Line 171: Line 171:
  class MediaWriter;  
  class MediaWriter;  
</code>
</code>
== Current version note ==
MediaWriter is still under construction

Revision as of 11:02, 29 January 2013

Reference spec:

https://dvcs.w3.org/hg/dap/raw-file/tip/media-stream-capture/RecordingProposal.html
bugs:
bug 803414 Audio Recording - Web API & Implementation
bug 834165 Implement BlobEvent
bug 825110 [meta] Porting WebRTC video_module for B2G
bug 825112 [meta] Porting WebRTC audio_module for B2G
media encoder
audio encoder
video encoder
media writer
ogg writer

MediaRecorder Arch.jpg

API Draft(incomplete 2013/01/29)

class MediaSegmentAdapter { 
public:
    /* AppendSegment may run on MediaStreamGraph thread to avoid race condition */
    void AppendSegment(MediaSegment) = 0;
    void SetBufferLength(size_t);
    size_t GetBufferLength();

    MediaSegment DequeueSegment();
 
protected:
    Queue<MediaSegment> mBuffer;
}
class VideoAdapter : MediaSegmentAdapter {
public:
    /* This version deep copy/color convert the input buffer into a local buffer */
    void AppendSegment(MediaSegment);
}

class GrallocAdapter : MediaSegmentAdapter {
public: 
    /* This version |do not| copy frame data, but queue the GraphicBuffer directly
       which can be used with SurfaceMediaSource or other SurfaceFlinger compatible 
       mechanism for hardware supported video encoding */
    void AppendSegment(MediaSegment);
}
class AudioAdapter : MediaSegmentAdapter {
public: 
    /* Copy/resample the data into local buffer */
    void AppendSegment(MediaSegment);
}
class MediaEncoder : MediaStreamListener {
public:
    /* Callback functions for MediaStream */
    void NotifyConsumption(MediaStreamGraph, Consumption);
    void NotifyPull(MediaStreamGraph, StreamTime);
    void NotifyBlockingChanged(MediaStreamGraph, Blocking);
    void NotifyHasCurrentData(MediaStreamGraph, bool);
    void NotifyOutput(MediaStreamGraph);
    void NotifyFinished(MediaStreamGraph);
    /* Queue the MediaSegment into correspond adapters */
    /* XXX: Is it possible to determine Audio related paramenters from this callback? 
            Or we have to query them from MediaStream directly? */
    /* AppendSegment into Adapter need block MediaStreamGraph thread to avoid race condition
       and we should schedule one encoding loop if any track updated */
    void NotifyQueuedTrackChanges(MediaStreamGraph, TrackID, TrackRate, TrackTicks, uint32_t, MediaSegment);
 
    /* Callback functions to JS */
    void SetDataAvailableCallback()
    void SetErrorCallback()
    void SetMuteTrackCallback()
    void SetPauseCallback()
    void SetPhotoCallback()
    void SetRecordingCallback()
    void SetResumeCallback()
    void SetStopCallback()
    void SetUnmuteTrackCallback()
    void SetWarningCallback()

    /* Option query functions */
    Vector<String> GetSupportMIMEType()
    Pair<int, int> GetSupportWidth() 
    Pair<int, int> GetSupportHeight()

    /* Set requested encoder */
    void SetMIMEType();
    void SetVideoWidth();
    void SetVideoHeight();

    /* JS control functions */
    void MuteTrack(TrackID)
    void Pause()
    void Record()
    void RequestData --?
        - Cause encoder flush data & callback?
    void Resume()
    void SetOptions()
    void Stop()
    void TakePhoto --?
    void UnmuteTrack
 
    /* initial internal state and codecs */
    void Init()
 
    /* create MediaEncoder for given MediaStream */
    MediaEncoder(MediaStream);
 
private: 
    void QueueVideoSegments();
    void QueueAudioSegments();
    void SelectCodec();
    void ConfigCodec();
    void SetVideoQueueSize();
    void SetAudioQueueSize();
 
    /* data member */
    MediaSegmentAdapter mVideoSegments;
    MediaSegmentAdapter mAudioSegments;
    MediaCodec mVideoCodec;
    MediaCodec mAudioCodec;
    MediaWriter mWriter;
    Thread mEncoderThread;
}
/* base class for general codecs */
class MediaCodec {
public:
    enum EncoderStatus {
        ENCODE,
        COLLECT,
    }
 
    void Init() = 0;
 
    /* Mimic android::CameraParameter to collect backend codec related params in general class */
    void GetParams() = 0;
    void SetParams() = 0;
 
    /* blocking call, may buffering data and real encode until enough data collected */
    EncoderStatus Encode(MediaBuffer in, void* out, size_t length) = 0;
    void Flush() = 0;
}
class AudioCodec : public MediaCodec {
public:
    /* AudioCodec may need collect enough buffers to be encode, return COLLECT as needed */
    EncoderStatus Encode(MediaBuffer in, void* out, size_t length) = 0;
 
private:
    bool IsDataEnough();
    void* mLocalBuffer[MIN_FRAMES];
}
class VideoCodec : public MediaCodec {
public: 
    EncoderStatus Encode(MediaBuffer in, void* out, size_t length) = 0;
}
class OpusCodec : public AudioCodec {
    // Use libopus to encode audio
private:
    // libopus ctx, etc...
}
class TheoraCodec : public VideoCodec {
    // Use libtheora to encode video
private:
    // libtheora encoder is not blocking, thus we have to loop until frame complete
}
// XXX:
class MediaWriter; 

Current version note

MediaWriter is still under construction