Closed
Bug 879669
Opened 11 years ago
Closed 11 years ago
Support Video Encoder module in MediaEncoder framework
Categories
(Core :: Audio/Video: Recording, defect)
Tracking
()
People
(Reporter: u459114, Assigned: rlin)
References
(Blocks 1 open bug)
Details
(Keywords: dev-doc-needed, Whiteboard: [ft:multimedia-platform])
Attachments
(4 files, 71 obsolete files)
1.58 KB,
patch
|
Details | Diff | Splinter Review | |
20.07 KB,
patch
|
Details | Diff | Splinter Review | |
2.29 KB,
patch
|
Details | Diff | Splinter Review | |
9.54 KB,
patch
|
Details | Diff | Splinter Review |
Implement video encoding path in MediaEncoding framework.
Two use cases for Video Encoding module
1. Video recording
With getUserMedia and MediaRecorder API, user is able to do video recording thing without mozCamera.
2. WebRTC encoding path
Redirect video encoding path in GIPS into MediaEncoding framework to take advantage of HW OMX component(Bug 879668)
Summary: Implement Video path in MediaEncoder/ MediaWriter → [MediaEncoder] Implement Video path in MediaEncoder/ MediaWriter
Blocks: MediaEncoder
Blocks: b2g-multimedia
Updated•11 years ago
|
No longer blocks: b2g-multimedia
Assignee | ||
Updated•11 years ago
|
Assignee | ||
Comment 2•11 years ago
|
||
Let it as meta bug
Assignee: slin → nobody
Summary: [MediaEncoder] Implement Video path in MediaEncoder/ MediaWriter → [Meta] Implement Video path in MediaEncoder
Assignee | ||
Updated•11 years ago
|
Alias: VideoEncoder
Comment 3•11 years ago
|
||
It's a wip patch: basic videoTrackEncoder implementaion that I extract from bug 881840.
Hi Randy:
As we discussed before, the interface |GetEncodedTrack(nsTArray<uint8_t>* aOutput, int &aOutputDuration) and GetHeader(nsTArray<uint8_t>* aOutput) | can not be applied for various encoder.
Maybe we should re-design(or add) the interface for various video/audio mimetype on this bug.
Assignee | ||
Updated•11 years ago
|
Alias: VideoEncoder
Summary: [Meta] Implement Video path in MediaEncoder → Support Video Encoder module in MediaEncoder framewrok
Next blocker for encoding path, we need this bug be fixed so that all developers works on concrete video encoder, VP8/ OmxVideo, and container writer, such as MP4Writer/ WebMWriter, be capable to construct their module without patch need.
We need a prototype for discussion first.
Flags: needinfo?(rlin)
For this bug,
1. Track and writer creator need to be more generic.
2. No source buffer copy for both SW and HW track encoder path
3. If we can have a buffer arena for encoded buffer management, to prevent encoded buffer allocation, it would be great.
Assignee | ||
Updated•11 years ago
|
Assignee: nobody → rlin
Flags: needinfo?(rlin)
Comment 6•11 years ago
|
||
Regarding the initial video track encoder parameters, I would like to add "trackRate" so that we can calculate the play time for encoded frame.
virtual nsresult Init(int aWidth, int aHeight, int aFrameRate, uint64_t aTacckRate) = 0;
^^^^^^^^^^^^^^^^^^^
In track encoder/ writer factory function
Only "B2G + JB(ANDROID_VERSION >= 18)" uses MediaCodec, which means we create OmxVideoTrackEncoder/ OmxAudioTrackEncoder in recording path
On all the other platforms, we use VP8 + Vorbis.
(In reply to Benjamin Chen [:bechen] from comment #6)
> Regarding the initial video track encoder parameters, I would like to add
> "trackRate" so that we can calculate the play time for encoded frame.
> virtual nsresult Init(int aWidth, int aHeight, int aFrameRate, uint64_t
> aTacckRate) = 0;
What exactly track rate means?
Updated•11 years ago
|
Whiteboard: [ft:media-recording]
Comment 9•11 years ago
|
||
(In reply to C.J. Ku[:CJKu] from comment #8)
> (In reply to Benjamin Chen [:bechen] from comment #6)
> > Regarding the initial video track encoder parameters, I would like to add
> > "trackRate" so that we can calculate the play time for encoded frame.
> > virtual nsresult Init(int aWidth, int aHeight, int aFrameRate, uint64_t
> > aTacckRate) = 0;
> What exactly track rate means?
I think the track rate is the reciprocal of minimal time unit.
ex: track rate:90000; a video frame duration is 2. That means the frame should be played for 2/90000 seconds.
Assignee | ||
Comment 10•11 years ago
|
||
Does this parameter only required for vp8?
Where can we get this parameter? from media stream?
Updated•11 years ago
|
Updated•11 years ago
|
Target Milestone: --- → 1.3 Sprint 4 - 11/8
Assignee | ||
Comment 11•11 years ago
|
||
WIP for supporting video encoder, some source code come from bechen's WIP patch.
ToDO:
1. EOS handle
2. Build Flag define
3. Avoid Buffer copy
Attachment #811898 -
Attachment is obsolete: true
Comment 12•11 years ago
|
||
Need to clean up more.
Comment 13•11 years ago
|
||
The previous one was empty lol.
Attachment #824629 -
Attachment is obsolete: true
Assignee | ||
Comment 14•11 years ago
|
||
Muxer needs to aware the the existence of A/V track during the init step.
Assignee | ||
Comment 15•11 years ago
|
||
Comment on attachment 825083 [details] [diff] [review]
[WIP] VideoTrackEncoder and some refactor in AudioTrackEncoder
Review of attachment 825083 [details] [diff] [review]:
-----------------------------------------------------------------
two small change require
::: content/media/encoder/TrackEncoder.cpp
@@ +155,5 @@
> + while (!iter.IsEnded()) {
> + VideoChunk chunk = *iter;
> + if (!chunk.IsNull()) {
> + gfxIntSize size = chunk.mFrame.GetIntrinsicSize();
> + nsresult rv = Init(size.width, size.height);
nsresult rv = Init(size.width, size.height, aTrackRate);
::: content/media/encoder/TrackEncoder.h
@@ +230,5 @@
> + int mFrameHeight;
> +
> + ReentrantMonitor mReentrantMonitor;
> +
> + nsAutoPtr<VideoSegment> mRawSegment;
Those members should be protected..
Assignee | ||
Comment 16•11 years ago
|
||
Remove the VideoTrackEncoder changed by slin.
Add TestWriter.h. for testing.
Attachment #823905 -
Attachment is obsolete: true
Reporter | ||
Comment 17•11 years ago
|
||
Comment on attachment 825730 [details] [diff] [review]
WIP3
Review of attachment 825730 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +73,5 @@
> LOG("NotifyRemoved in [MediaEncoder].");
> mAudioEncoder->NotifyRemoved(aGraph);
> }
>
> +static const char* gSupportedmimeType[4] = {
static const char* gSupportedmimeType[]
@@ +121,3 @@
>
> encoder = new MediaEncoder(writer.forget(), audioEncoder.forget(),
> + videoEncoder.forget(), aMIMEType, isAudioOnly);
I don't understand why we need isAudioOnly here.
For audio only recording, videoEncoder should contain nullptr, why MediaEncoder does not use this value(videoEncoder) to tell whether it is audio only recording or video/audio recording.
@@ +218,5 @@
> + LOG("ERROR! Fail to write encoded track to the media container.");
> + mState = ENCODE_DONE;
> + break;
> + }
> + }
189 ~ 204/ 205 ~ 222 are duplicate. Have another member function
For exp: bool WriteEncodedTrack(TrackEncoder &trackEncoder);
Change code here to
if (!WriteEncodedTrack(mAudioEncoder) || !WriteEncodedTrack(mVideoEncoder))
{
mState = ENCODE_DONE;
break;
}
Comment 18•11 years ago
|
||
Things that implemented in this patch:
- Appending video frames from MediaStreamGraph.
- Deal with muted video chunks.
TODO:
- Documentation.
- Test in real world.
Attachment #825083 -
Attachment is obsolete: true
Comment 19•11 years ago
|
||
This is actually Randy's patch.
Comment 20•11 years ago
|
||
This is actually Randy's patch too.
Comment 21•11 years ago
|
||
Update milestone to sprint 5 after discussing the implementation status with engineer
Target Milestone: 1.3 Sprint 4 - 11/8 → 1.3 Sprint 5 - 11/22
Comment 22•11 years ago
|
||
FWIW - Let's make sure we're enhancing the existing mochitests to test the video encoder path as well. There's quite a lot of payoff you'll get if you do the work to make the tests work across audio & video encoding, as we'll be able expand to multiple audio/video codecs with existing tests easily.
Comment 23•11 years ago
|
||
http://dxr.mozilla.org/mozilla-central/source/content/media/encoder/ContainerWriter.h#l45
Would it be better not to use smart potiner as parameter?
Reporter | ||
Comment 24•11 years ago
|
||
Comment on attachment 826670 [details] [diff] [review]
[WIP] Part1: VideoTrackEncoder and some refactor in AudioTrackEncoder
Review of attachment 826670 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +156,5 @@
> + // Check and initialize parameters for codec encoder.
> + if (!mInitialized) {
> + VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(video));
> + while (!iter.IsEnded()) {
> + VideoChunk chunk = *iter;
Are you sure you want deep copy here? Why not just use reference. Audio path has the same problem
Assignee | ||
Comment 25•11 years ago
|
||
[WIP] Part3: A fake test of video track encoder.
The dummy muxer can write data into file system. (separate video/audio)
Assignee | ||
Comment 26•11 years ago
|
||
This is a testing patch, this would write A/V encoded data directly into file system.
Attachment #825730 -
Attachment is obsolete: true
Attachment #826672 -
Attachment is obsolete: true
Comment 27•11 years ago
|
||
Attachment #826670 -
Attachment is obsolete: true
Assignee | ||
Comment 29•11 years ago
|
||
Attachment #827928 -
Attachment is obsolete: true
Comment 30•11 years ago
|
||
Comment on attachment 827940 [details] [diff] [review]
[WIP] Part1: VideoTrackEncoder and some refactor in AudioTrackEncoder
Review of attachment 827940 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +210,5 @@
> + mLastFrameSerial = image->GetSerial();
> + mRawSegment->AppendFrame(image.forget(), chunk.mDuration,
> + chunk.mFrame.GetIntrinsicSize());
> + }
> +
We should append all images into mRawSegment, or the timestamp/duration is not correct in mRawSegment.
And add a function in VideoSegment to merge the same videoChunk in mRawSegment before encoding.
Comment 31•11 years ago
|
||
Major change:
In |AppendVideoSegment()|, use |mLastFrame| to hold the last different in-coming frame, and use |mLastFrameDuration| to accumulate duration of duplicated frames.
Attachment #827940 -
Attachment is obsolete: true
Comment 32•11 years ago
|
||
Comment 33•11 years ago
|
||
Comment 34•11 years ago
|
||
Comment on attachment 829851 [details] [diff] [review]
[WIP] Small fix of part 2
Review of attachment 829851 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +245,5 @@
> }
>
> + // TODO: Should use writer->IsWritingComplete();
> + mState = (mAudioEncoder->IsEncodingComplete() ||
> + mVideoEncoder->IsEncodingComplete()) ? ENCODE_DONE : ENCODE_TRACK;
Randy: Maybe we should let the ContainerWriter decide when encoding is complete?
Assignee | ||
Comment 35•11 years ago
|
||
hmm. it should be. Let writer to decide this encoder session should be ended.
Reporter | ||
Comment 36•11 years ago
|
||
Comment on attachment 829851 [details] [diff] [review]
[WIP] Small fix of part 2
Review of attachment 829851 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +250,3 @@
> break;
> }
>
Suggest moving codes in this case statement into another member function.
Reporter | ||
Comment 37•11 years ago
|
||
Comment on attachment 829851 [details] [diff] [review]
[WIP] Small fix of part 2
Review of attachment 829851 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +250,3 @@
> break;
> }
>
Codes in video path and audio path are similar.
Please try to use member function or template to prevent redundant code.
Comment 38•11 years ago
|
||
Merge the same video chunk in VideoSegment.
Comment 39•11 years ago
|
||
Comment on attachment 830096 [details] [diff] [review]
[WIP] MergeSameVideoChunk.patch
Review of attachment 830096 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/VP8TrackEncoder.cpp
@@ +377,5 @@
> }
> #endif
> mSourceSegment->AppendFrom(mRawSegment);
> printf("mSourceSegment GetDuration %lld\n",mSourceSegment->GetDuration());
> + mSourceSegment->MergeSameVideoChunk();
TrackEncoder sends raw frame to mRawSegment in every cycle, are you queuing the mSourceSegment here? How do you know the merge is complete and can be sent to encoder?
Updated•11 years ago
|
Flags: needinfo?(bechen)
Comment 40•11 years ago
|
||
Attachment #829850 -
Attachment is obsolete: true
Comment 41•11 years ago
|
||
(In reply to Shelly Lin [:shelly] from comment #39)
> Comment on attachment 830096 [details] [diff] [review]
> [WIP] MergeSameVideoChunk.patch
>
> Review of attachment 830096 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: content/media/encoder/VP8TrackEncoder.cpp
> @@ +377,5 @@
> > }
> > #endif
> > mSourceSegment->AppendFrom(mRawSegment);
> > printf("mSourceSegment GetDuration %lld\n",mSourceSegment->GetDuration());
> > + mSourceSegment->MergeSameVideoChunk();
>
> TrackEncoder sends raw frame to mRawSegment in every cycle, are you queuing
> the mSourceSegment here? How do you know the merge is complete and can be
> sent to encoder?
Yes, VP8TrackEncoder has a local queue mSourceSegment. So the merge function can be called in mSourceSegment.
Or if we don't have a local queue in XXXTrackEncoder, the function need to be protected by a lock.
Flags: needinfo?(bechen)
Comment 42•11 years ago
|
||
Comment 43•11 years ago
|
||
Comment on attachment 830570 [details] [diff] [review]
[WIP] Part1: VideoTrackEncoder and some refactor in AudioTrackEncoder
Review of attachment 830570 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +220,5 @@
> +
> + nsRefPtr<layers::Image> lastImg = mLastChunk->mFrame.GetImage();
> + mRawSegment->AppendFrame(lastImg.forget(), mLastChunk->GetDuration(),
> + mLastChunk->mFrame.GetIntrinsicSize());
> + mLastChunk->mDuration = chunk.GetDuration();
Let me explain a bit more on this, of how it "Merges" duplicate chunks:
mLastChunk holds the image pointer of last in-coming frame (ln227, mLastChunk->mFrame.TakeFrom(&chunk.mFrame);), and check whether the frame in this iteration is the same as the one we hold in mLastChunk.
If this current chunk is a duplicate of mLastChunk (can be combined with mLastChunk), we sum the mLastChunk->mDuration with the duration of this chunk. Else, if this current chunk is a different one, which means mLastChunk has done accumulating its duration from the past duplicate chunks, we append mLastChunk to mRawSegment.
Assignee | ||
Comment 44•11 years ago
|
||
Attachment #826671 -
Attachment is obsolete: true
Attachment #829851 -
Attachment is obsolete: true
Comment 45•11 years ago
|
||
With implementation of appending black frames if chunks are null.
Attachment #830570 -
Attachment is obsolete: true
Attachment #830598 -
Attachment is obsolete: true
Comment 46•11 years ago
|
||
Notify the wait of monitor when mRawSegment has appended some duration of chunks.
Attachment #830690 -
Attachment is obsolete: true
Assignee | ||
Comment 47•11 years ago
|
||
(In reply to Shelly Lin [:shelly] from comment #45)
> Created attachment 830690 [details] [diff] [review]
> [WIP] Part1: VideoTrackEncoder (m-c changeset 154451)
>
> With implementation of appending black frames if chunks are null.
From the gUM Spec
http://dev.w3.org/2011/webrtc/editor/getusermedia.html
The black frame may generate from media stream.
4. MediaStream API
The output of a MediaStream object must correspond to the tracks in its input. Muted audio tracks must be replaced with silence. Muted video tracks must be replaced with blackness.
Comment 48•11 years ago
|
||
Comment on attachment 830746 [details] [diff] [review]
[WIP] Part1: VideoTrackEncoder (m-c changeset 154451)
Review of attachment 830746 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +211,5 @@
> + mLastChunk->mFrame.SetForceBlack(chunk.mFrame.GetForceBlack());
> + mLastChunk->mDuration = chunk.GetDuration();
> + } else {
> + if (mLastChunk->CanCombineWithFollowing(chunk)) {
> + mLastChunk->mDuration += chunk.GetDuration();
The mLastChunk always queues one video chunk . So if there is a video chunk with long duration after merge, the track encoder and container writer won't output any data during this period.
Maybe we should compare the mLastChunk's duration with |GetPacketDuration| and then append it to mRawSegment (also reset the mFirstFrameTaken)
@@ +231,5 @@
> + }
> +
> + if (mRawSegment->GetDuration() > 0) {
> + mReentrantMonitor.NotifyAll();
> + }
Here we can call |GetPacketDuration| implement by VP8/OMX TrackEncder to notify the other thread.
Comment 49•11 years ago
|
||
Comment on attachment 830746 [details] [diff] [review]
[WIP] Part1: VideoTrackEncoder (m-c changeset 154451)
Review of attachment 830746 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +268,5 @@
> +VideoTrackEncoder::CreateMutedFrame(nsTArray<uint8_t>* aOutputBuffer)
> +{
> + // Supports YUV420 image format only, for now.
> + int yPlaneLen = mFrameWidth *mFrameHeight;
> + int cbcrPlaneLen = yPlaneLen/2;
The cbcrPlaneLen is not correct?
It should be "cbcrPlaneLen = ((mFrameWidth+1)/2) * ((mFrameHeight+1)/2) * 2"
Another question for the black screen, only the member |mForceBlack| in class VideoFrame is set to TRUE. So the VP8/OMX track encoder needs to check the member and call
CreateMutedFrame before encoding. Can we do this in VideoTrackEncoder (replace the video chunk to black)?
Comment 50•11 years ago
|
||
(In reply to Benjamin Chen [:bechen] from comment #48)
> Comment on attachment 830746 [details] [diff] [review]
> [WIP] Part1: VideoTrackEncoder (m-c changeset 154451)
>
> Review of attachment 830746 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: content/media/encoder/TrackEncoder.cpp
> @@ +211,5 @@
> > + mLastChunk->mFrame.SetForceBlack(chunk.mFrame.GetForceBlack());
> > + mLastChunk->mDuration = chunk.GetDuration();
> > + } else {
> > + if (mLastChunk->CanCombineWithFollowing(chunk)) {
> > + mLastChunk->mDuration += chunk.GetDuration();
>
> The mLastChunk always queues one video chunk . So if there is a video chunk
> with long duration after merge, the track encoder and container writer won't
> output any data during this period.
> Maybe we should compare the mLastChunk's duration with |GetPacketDuration|
> and then append it to mRawSegment (also reset the mFirstFrameTaken)
>
> @@ +231,5 @@
> > + }
> > +
> > + if (mRawSegment->GetDuration() > 0) {
> > + mReentrantMonitor.NotifyAll();
> > + }
>
> Here we can call |GetPacketDuration| implement by VP8/OMX TrackEncder to
> notify the other thread.
Yeah, that's better. As about the muted chunks, I think I'll use |GetPacketDuration| be the max duration of duplicated frames.
Comment 51•11 years ago
|
||
(In reply to Benjamin Chen [:bechen] from comment #49)
> Comment on attachment 830746 [details] [diff] [review]
> [WIP] Part1: VideoTrackEncoder (m-c changeset 154451)
>
> Review of attachment 830746 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: content/media/encoder/TrackEncoder.cpp
> @@ +268,5 @@
> > +VideoTrackEncoder::CreateMutedFrame(nsTArray<uint8_t>* aOutputBuffer)
> > +{
> > + // Supports YUV420 image format only, for now.
> > + int yPlaneLen = mFrameWidth *mFrameHeight;
> > + int cbcrPlaneLen = yPlaneLen/2;
>
> The cbcrPlaneLen is not correct?
> It should be "cbcrPlaneLen = ((mFrameWidth+1)/2) * ((mFrameHeight+1)/2) * 2"
>
Do we need to consider the odd size resolution?
> Another question for the black screen, only the member |mForceBlack| in
> class VideoFrame is set to TRUE. So the VP8/OMX track encoder needs to check
> the member and call
> CreateMutedFrame before encoding. Can we do this in VideoTrackEncoder
> (replace the video chunk to black)?
I'm not sure what you mean....but what's the problem of calling |CreateMutedFrame| before encoding?
Assignee | ||
Comment 52•11 years ago
|
||
Comment on attachment 830746 [details] [diff] [review]
[WIP] Part1: VideoTrackEncoder (m-c changeset 154451)
Review of attachment 830746 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +268,5 @@
> +VideoTrackEncoder::CreateMutedFrame(nsTArray<uint8_t>* aOutputBuffer)
> +{
> + // Supports YUV420 image format only, for now.
> + int yPlaneLen = mFrameWidth *mFrameHeight;
> + int cbcrPlaneLen = yPlaneLen/2;
use ceil... Could we assign the black memory pointer to encoder to avoid the memset operation?
::: content/media/encoder/TrackEncoder.h
@@ +77,5 @@
> + */
> + virtual void NotifyEndOfStream() = 0;
> +
> + bool mInitialized;
> + bool mDoneEncoding;
mEncodingDone?
@@ +81,5 @@
> + bool mDoneEncoding;
> +
> + /**
> + * The total duration of null chunks we have received from MediaStreamGraph
> + * before initializing the audio track encoder.
remove audio
Comment 53•11 years ago
|
||
Hi Robert, this patch is mainly for the implementation of VideoTrackEncoder. I also moved some common methods from AudioTrackEncoder to TrackEncoder, fixed some comments here and there just because I got confused by my previous code.
Attachment #830746 -
Attachment is obsolete: true
Attachment #8333664 -
Flags: review?(roc)
Comment 54•11 years ago
|
||
(In reply to Randy Lin [:rlin] from comment #52)
> Comment on attachment 830746 [details] [diff] [review]
> [WIP] Part1: VideoTrackEncoder (m-c changeset 154451)
>
> Review of attachment 830746 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: content/media/encoder/TrackEncoder.cpp
> @@ +268,5 @@
> > +VideoTrackEncoder::CreateMutedFrame(nsTArray<uint8_t>* aOutputBuffer)
> > +{
> > + // Supports YUV420 image format only, for now.
> > + int yPlaneLen = mFrameWidth *mFrameHeight;
> > + int cbcrPlaneLen = yPlaneLen/2;
>
> use ceil... Could we assign the black memory pointer to encoder to avoid the
> memset operation?
Just saw your comments after I post the new patch....
If we want to deal with odd size resolution, maybe we should do it at where we assign mFrameWidth/mFrameHeight? instead of fixing the mathematical operation here and there.
>
> ::: content/media/encoder/TrackEncoder.h
> @@ +77,5 @@
> > + */
> > + virtual void NotifyEndOfStream() = 0;
> > +
> > + bool mInitialized;
> > + bool mDoneEncoding;
>
> mEncodingDone?
>
I'll change it to mEncodingComplete just to match it with function |IsEncodingComplete()|.
> @@ +81,5 @@
> > + bool mDoneEncoding;
> > +
> > + /**
> > + * The total duration of null chunks we have received from MediaStreamGraph
> > + * before initializing the audio track encoder.
>
> remove audio
Comment 55•11 years ago
|
||
Robert, please find my original comment in comment 53, this patch includes some nit fixes per Randy's comment.
Attachment #8333664 -
Attachment is obsolete: true
Attachment #8333664 -
Flags: review?(roc)
Attachment #8333669 -
Flags: review?(roc)
Comment 56•11 years ago
|
||
(In reply to Shelly Lin [:shelly] from comment #54)
> If we want to deal with odd size resolution, maybe we should do it at where
> we assign mFrameWidth/mFrameHeight? instead of fixing the mathematical
> operation here and there.
We should not assume video resolutions are even.
Assignee | ||
Comment 57•11 years ago
|
||
Attachment #830663 -
Attachment is obsolete: true
Comment on attachment 8333669 [details] [diff] [review]
Part1: VideoTrackEncoder and some refactor in AudioTrackEncoder
Review of attachment 8333669 [details] [diff] [review]:
-----------------------------------------------------------------
Please submit separate patches for the refactoring vs the new code.
Attachment #8333669 -
Flags: review?(roc) → review-
Comment 59•11 years ago
|
||
Attachment #8333669 -
Attachment is obsolete: true
Comment 60•11 years ago
|
||
Attachment #8335006 -
Flags: review?(roc)
Comment 61•11 years ago
|
||
Comment on attachment 8335006 [details] [diff] [review]
Part1: Refactor of TrackEncoder
Review of attachment 8335006 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/EncodedFrameContainer.h
@@ +5,5 @@
>
> #ifndef EncodedFrameContainer_H_
> #define EncodedFrameContainer_H_
>
> +#include "nsAutoPtr.h"
I added this because the compiler is complaining about it when I include this header file in another header file that isn't using any nsAutoPtr.
Comment 62•11 years ago
|
||
Attachment #8335014 -
Flags: review?(roc)
Comment on attachment 8335006 [details] [diff] [review]
Part1: Refactor of TrackEncoder
Review of attachment 8335006 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.h
@@ +69,5 @@
> virtual nsresult GetEncodedTrack(EncodedFrameContainer& aData) = 0;
> +
> + bool IsEncodingComplete() { return mEncodingComplete; }
> +
> + protected:
Don't indent this line.
@@ +77,5 @@
> + */
> + virtual void NotifyEndOfStream() = 0;
> +
> + bool mInitialized;
> + bool mEncodingComplete;
Put these with the other bools below, and document them!
@@ +156,5 @@
> /**
> * Notifies the audio encoder that we have reached the end of source stream,
> * and wakes up mReentrantMonitor if encoder is waiting for more track data.
> */
> + void NotifyEndOfStream() MOZ_OVERRIDE;
Should be declared "virtual"
@@ +177,4 @@
>
> /**
> + * A ReentrantMonitor to protect the pushing and pulling of mRawSegment, and
> + * some other flags.
Better say which flags :-)
Attachment #8335006 -
Flags: review?(roc) → review-
Comment on attachment 8335014 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8335014 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +202,5 @@
> + // Append all video segments from MediaStreamGraph, including null an
> + // non-null frames.
> + VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(aSegment));
> + while (!iter.IsEnded()) {
> + VideoChunk chunk = *iter;
Why are we doing all this? Can't we just append aSegment to mRawSegment directly?
::: content/media/encoder/TrackEncoder.h
@@ +195,5 @@
> + : TrackEncoder()
> + , mFrameWidth(0)
> + , mFrameHeight(0)
> + , mTrackRate(0)
> + , mLastChunk(new VideoChunk())
Initialize it to null instead of an empty video chunk
@@ +232,5 @@
> + nsresult AppendVideoSegment(const VideoSegment& aSegment);
> +
> + // Tells the video track encoder that we've reached the end of source stream,
> + // and wakes up mReentrantMonitor if encoder is waiting for more track data.
> + void NotifyEndOfStream() MOZ_OVERRIDE;
declare this as virtual.
@@ +251,5 @@
> + // segment.
> + bool mFirstFrameTaken;
> +
> + // A ReentrantMonitor to protect the pushing and pulling of mRawSegment, and
> + // some other flags.
Say which flags :-)
Attachment #8335014 -
Flags: review?(roc) → review-
Comment on attachment 8335006 [details] [diff] [review]
Part1: Refactor of TrackEncoder
Review of attachment 8335006 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.h
@@ +177,4 @@
>
> /**
> + * A ReentrantMonitor to protect the pushing and pulling of mRawSegment, and
> + * some other flags.
Actually, if we're protecting flags in the superclass, I think we should probably put the monitor in the superclass.
Assignee | ||
Comment 66•11 years ago
|
||
Hi roc,
1. Do we need to support video only recording? Right now I just query the video/audio track number from mediaStream and choose the suitable mimeType according platform (for ex, desktop would be video/webm, b2g would be video/mp4), and pass the ContentHint/MimeType to encoder via MediaEncoder::CreateEncoder(aMimeType, aContentHinet) Is this design OK for this?
For the mimeType constant like video/mpv have not define in nsMimeType.h, can I add it?
Flags: needinfo?(roc)
Assignee | ||
Comment 67•11 years ago
|
||
Replace video/mpv to video/m4v for video only mp4.
As we discussed F2F, we should default to video/mp4 for anything with a video track in B2G, and video/webm for anything with a video track on desktop.
Assignee | ||
Comment 69•11 years ago
|
||
Thanks, I will register the cb to media stream track's change and choose the proper of video mimeType.
Flags: needinfo?(roc)
Comment 70•11 years ago
|
||
Attachment #8335006 -
Attachment is obsolete: true
Attachment #8335557 -
Flags: review?(roc)
Comment 71•11 years ago
|
||
Attachment #8335557 -
Attachment is obsolete: true
Attachment #8335557 -
Flags: review?(roc)
Attachment #8335560 -
Flags: review?(roc)
Comment 72•11 years ago
|
||
Comment on attachment 8335014 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8335014 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +202,5 @@
> + // Append all video segments from MediaStreamGraph, including null an
> + // non-null frames.
> + VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(aSegment));
> + while (!iter.IsEnded()) {
> + VideoChunk chunk = *iter;
Because aSegment is giving us duplicate images, we don't wanna send duplicate frames to the track encoder, making the encoder too busy on unnecessary frames.
However, we still need the durations from those duplicate images. mLastChunk is suppose to accumulate the duration.
Comment on attachment 8335014 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8335014 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +202,5 @@
> + // Append all video segments from MediaStreamGraph, including null an
> + // non-null frames.
> + VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(aSegment));
> + while (!iter.IsEnded()) {
> + VideoChunk chunk = *iter;
You can probably just call mRawSegment->AppendFrom(&chunk) here.
Comment on attachment 8335560 [details] [diff] [review]
Part1: Refactor of TrackEncoder
Review of attachment 8335560 [details] [diff] [review]:
-----------------------------------------------------------------
r+ with those fixed.
::: content/media/encoder/TrackEncoder.h
@@ +102,5 @@
> +
> + /**
> + * True if the track encoder has encoded all source data.
> + */
> + bool mEncodingComplete;
Put this boolean flag below with the other flags for better packing of fields.
@@ +106,5 @@
> + bool mEncodingComplete;
> +
> + /**
> + * A ReentrantMonitor to protect the pushing and pulling of mRawSegment, and
> + * flags such as mInitialized, mEndOfStream, mCanceled.
Add to this comment, to explain that subclasses add their own fields which are protected by mReentrantMonitor.
Attachment #8335560 -
Flags: review?(roc) → review+
Comment 75•11 years ago
|
||
- Added comment to the patch description.
- Nit fix.
Attachment #8335560 -
Attachment is obsolete: true
Attachment #8336404 -
Flags: review?(roc)
Comment 76•11 years ago
|
||
Attachment #8336404 -
Attachment is obsolete: true
Attachment #8336404 -
Flags: review?(roc)
Attachment #8336408 -
Flags: review?(roc)
Attachment #8336408 -
Flags: review?(roc) → review+
Comment 77•11 years ago
|
||
Attachment #8335014 -
Attachment is obsolete: true
Attachment #8336424 -
Flags: review?(roc)
Assignee | ||
Comment 78•11 years ago
|
||
1. Get track information through TracksAvailableCallback.
2. because the error handle has been backout -.-..., this version is based on current mc version.
Attachment #8334440 -
Attachment is obsolete: true
Attachment #8336427 -
Flags: feedback?(roc)
Assignee | ||
Updated•11 years ago
|
Attachment #8336427 -
Attachment description: part2:MediaEncoder Change v2 → part3:MediaEncoder Change v2
Comment on attachment 8336424 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8336424 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +195,5 @@
> + // Append this many null data to our queued segment if there is a completely
> + // muted duration before receiving the first non-null video chunk.
> + if (mNullDuration > 0) {
> + mRawSegment->AppendNullData(mNullDuration);
> + mCurrentFrameTimeStamp += TimeDuration::FromMicroseconds(mNullDuration);
mNullDuration isn't in microseconds, it's in MediaTime which is 2^-20 seconds.
Also, make mCurrentFrameTimeStamp a MediaTime too so we don't have rounding issues here.
Also, call it mTotalFrameDuration.
@@ +209,5 @@
> + if (!mLastChunk || !mLastChunk->CanCombineWithFollowing(chunk)) {
> + nsRefPtr<layers::Image> image = chunk.mFrame.GetImage();
> + mRawSegment->AppendFrame(image.forget(), chunk.GetDuration(),
> + chunk.mFrame.GetIntrinsicSize());
> + mRawSegment->GetLastChunk()->mTimeStamp = mCurrentFrameTimeStamp;
Why are you doing this line? mTimeStamp is only for latency calculations, which aren't relevant here I think.
@@ +213,5 @@
> + mRawSegment->GetLastChunk()->mTimeStamp = mCurrentFrameTimeStamp;
> + }
> +
> + mCurrentFrameTimeStamp += TimeDuration::FromMicroseconds(chunk.GetDuration());
> + mLastChunk = &chunk;
I don't think you want to take the address here. "chunk" is going out of scope so this will be a dangling pointer. You probably should make mLastChunk a VideoFrame, and use TakeFrom to take it from 'chunk' here.
Attachment #8336424 -
Flags: review?(roc) → review-
Assignee | ||
Comment 80•11 years ago
|
||
Add build flags to decide which encoding format can be chosen.
Attachment #8336427 -
Attachment is obsolete: true
Attachment #8336427 -
Flags: feedback?(roc)
Attachment #8336505 -
Flags: feedback?(roc)
Comment 81•11 years ago
|
||
Comment on attachment 8336424 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8336424 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +209,5 @@
> + if (!mLastChunk || !mLastChunk->CanCombineWithFollowing(chunk)) {
> + nsRefPtr<layers::Image> image = chunk.mFrame.GetImage();
> + mRawSegment->AppendFrame(image.forget(), chunk.GetDuration(),
> + chunk.mFrame.GetIntrinsicSize());
> + mRawSegment->GetLastChunk()->mTimeStamp = mCurrentFrameTimeStamp;
I don't know what mTimeStamp stands for in each source chunk.
I'm trying to store the timestamp of this frame so that the OmxTrackEncoder can pull it out and send it to stagefright encoder.
@@ +258,5 @@
> + aOutputBuffer->SetLength(frameLen);
> + // Fill Y plane.
> + memset(aOutputBuffer->Elements(), 0x10, yPlaneLen);
> + // Fill Cb/Cr planes.
> + memset(aOutputBuffer->Elements() + yPlaneLen, 0x80, cbcrPlaneLen);
Is it better if I use |nsAutoArrayPtr<uint8_t> buffer| inside the function and return buffer.forget() here?
Comment 82•11 years ago
|
||
(In reply to Shelly Lin [:shelly] from comment #81)
> Comment on attachment 8336424 [details] [diff] [review]
> Part2: Add VideoTrackEncoder
>
> Review of attachment 8336424 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: content/media/encoder/TrackEncoder.cpp
> @@ +209,5 @@
> > + if (!mLastChunk || !mLastChunk->CanCombineWithFollowing(chunk)) {
> > + nsRefPtr<layers::Image> image = chunk.mFrame.GetImage();
> > + mRawSegment->AppendFrame(image.forget(), chunk.GetDuration(),
> > + chunk.mFrame.GetIntrinsicSize());
> > + mRawSegment->GetLastChunk()->mTimeStamp = mCurrentFrameTimeStamp;
>
> I don't know what mTimeStamp stands for in each source chunk.
>
> I'm trying to store the timestamp of this frame so that the OmxTrackEncoder
> can pull it out and send it to stagefright encoder.
>
I think you don't need to store the timestamp here because there is |mDuration| for each VideoChunk.
OmxTrackEncoder can calculate timestamp by mDuration and TrackRate if all VideoChunks are not missing in MediaStreamGraph.
Or if you really need the timestamp, you can pass/use the |TrackTicks aTrackOffset| in NotifyQueuedTrackChanges.
Comment on attachment 8336424 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8336424 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +258,5 @@
> + aOutputBuffer->SetLength(frameLen);
> + // Fill Y plane.
> + memset(aOutputBuffer->Elements(), 0x10, yPlaneLen);
> + // Fill Cb/Cr planes.
> + memset(aOutputBuffer->Elements() + yPlaneLen, 0x80, cbcrPlaneLen);
It depends on how it's going to be used. Can you return an already_AddRefed<Image>?
Comment 84•11 years ago
|
||
Attachment #8336424 -
Attachment is obsolete: true
Attachment #8336612 -
Flags: review?(roc)
Comment 85•11 years ago
|
||
Comment on attachment 8336612 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8336612 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +239,5 @@
> + mReentrantMonitor.NotifyAll();
> +}
> +
> +void
> +VideoTrackEncoder::CreateMutedFrame(nsTArray<uint8_t>* aOutputBuffer)
As we discussed, using nsTArray<uint8_t> as output is good enough, but we'll see how it goes once we get to OmxTrackEncoder.
Comment on attachment 8336612 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8336612 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +175,5 @@
> + }
> + }
> +
> + if (mInitialized) {
> + AppendVideoSegment(video);
Hmm. Does this mean if 'video' contains a null chunk followed by a real chunk, we'll add the duration of the null chunk to mNullDuration *and* append both chunks in AppendVideoSegment? I think so. We need to avoid that.
::: content/media/encoder/TrackEncoder.h
@@ +274,5 @@
> + */
> + TrackRate mTrackRate;
> +
> + /**
> + * The total duration of frames in TrackTicks, keeps track in its subclasses.
"The total duration of frames in encoded video in TrackTicks, kept track of in subclasses."
Attachment #8336612 -
Flags: review?(roc) → review-
Comment 87•11 years ago
|
||
Comment on attachment 8336612 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8336612 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.cpp
@@ +175,5 @@
> + }
> + }
> +
> + if (mInitialized) {
> + AppendVideoSegment(video);
Why do we need to avoid that? Shouldn't we want to keep the muted video? (If there's any before a real chunk.)
::: content/media/encoder/TrackEncoder.h
@@ +274,5 @@
> + */
> + TrackRate mTrackRate;
> +
> + /**
> + * The total duration of frames in TrackTicks, keeps track in its subclasses.
Thanks for correcting :)
Updated•11 years ago
|
Target Milestone: 1.3 Sprint 5 - 11/22 → 1.3 Sprint 6 - 12/6
Assignee | ||
Updated•11 years ago
|
Attachment #8336505 -
Flags: feedback?(roc) → review?(roc)
(In reply to Shelly Lin [:shelly] from comment #87)
> Why do we need to avoid that? Shouldn't we want to keep the muted video? (If
> there's any before a real chunk.)
The null data will be appended twice. Once here: " mRawSegment->AppendNullData(mNullDuration);" and once in "mRawSegment->AppendFrame(image.forget(), chunk.GetDuration(),
chunk.mFrame.GetIntrinsicSize());"
Comment on attachment 8336505 [details] [diff] [review]
part3:MediaEncoder Change v3
Review of attachment 8336505 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/DOMMediaStream.cpp
@@ +325,5 @@
> DOMMediaStream::CheckTracksAvailable()
> {
> + if (mTrackTypesAvailable == 0) {
> + return;
> + }
Put this change in its own patch.
::: content/media/MediaRecorder.cpp
@@ +302,5 @@
> + mRecorder->mStream->OnTracksAvailable(tracksAvailableCallback);
> + // if there is no tracks, keep waiting
> + uint8_t trackType = mRecorder->mStream->GetHintContents();
> + if (!mRecorder->mStream->GetHintContents()) {
> + mReentrantMonitor.Wait();
You can't call Wait; we're on the main thread.
Instead, put the rest of this method in its own method that is called by TracksAvailableCallback, so it runs as soon as the tracks are available.
@@ +316,5 @@
> +#endif
> + }
> + if (mimeType.IsEmpty()) {
> + mimeType = NS_LITERAL_STRING(AUDIO_OGG);
> + }
Put the code to select the right default MIME type in its own patch.
Assignee | ||
Comment 90•11 years ago
|
||
Attachment #8336505 -
Attachment is obsolete: true
Attachment #8336505 -
Flags: review?(roc)
Attachment #8336993 -
Flags: review?(roc)
Assignee | ||
Comment 91•11 years ago
|
||
Attachment #8336997 -
Flags: review?(roc)
Assignee | ||
Comment 92•11 years ago
|
||
Attachment #8336999 -
Flags: review?(roc)
Comment on attachment 8336993 [details] [diff] [review]
part 3-1 mediastream change v1
Review of attachment 8336993 [details] [diff] [review]:
-----------------------------------------------------------------
Please add a comment to DOMMediaStream.h explaining that when the expected tracks mask is 0, the callback will fire as soon as there are any tracks.
Attachment #8336993 -
Flags: review?(roc) → review+
Comment on attachment 8336997 [details] [diff] [review]
part 3-2 mediarecorder change v1
Review of attachment 8336997 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/MediaRecorder.cpp
@@ +283,3 @@
> }
>
> + void AfterSetupStreams(uint8_t aTrackType)
call it aTrackTypes
@@ +289,5 @@
> + #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 && defined(MOZ_OMX_ENCODER)
> + mimeType = NS_LITERAL_STRING(VIDEO_MP4);
> + #endif
> + #if defined(MOZ_VP8_ENCODER) && defined(MOZ_VORBIS_ENCODER)
> + mimeType = NS_LITERAL_STRING(VIDEO_WEBM);
Shouldn't there be an #else here?
@@ +297,5 @@
> + mimeType = NS_LITERAL_STRING(AUDIO_OGG);
> + }
> + // Allocate encoder and bind with union stream.
> + mEncoder = MediaEncoder::CreateEncoder(mimeType, aTrackType);
> +
The way the type is chosen is a little confusing. The default choices made here may choose an encoder that's actually disabled by MediaDecoder::IsOggEnabled etc. Also, I don't see how the MIME type specified by the author is being respected.
I think it would be simpler if we don't do any MIME type selection here, just pass the MIME type specified by the author (if any) into CreateEncoder and do all MIME type decisions there.
Attachment #8336997 -
Flags: review?(roc) → review-
Assignee | ||
Comment 95•11 years ago
|
||
This API don't allow UA to set mimeType, So pass the mimeType as "" to encoder and let the encoder to decide proper mimeTpye by platform.
Attachment #8336997 -
Attachment is obsolete: true
Attachment #8337468 -
Flags: review?(roc)
Assignee | ||
Comment 96•11 years ago
|
||
Add commnet in content/media/DOMMediaStream.h
Attachment #8336993 -
Attachment is obsolete: true
Attachment #8337469 -
Flags: review?(roc)
Comment on attachment 8337469 [details] [diff] [review]
part 3-1 mediastream change v2
Review of attachment 8337469 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/DOMMediaStream.h
@@ +164,4 @@
> // We only care about track additions, we'll fire the notification even if
> // some of the tracks have been removed.
> // Takes ownership of aCallback.
> + // Run aCallback if track types have been added
This isn't enough. Use this:
// If GetExpectedTracks() returns 0, the callback will be fired as soon as there are any tracks.
Attachment #8337469 -
Flags: review?(roc) → review+
Comment on attachment 8337468 [details] [diff] [review]
part 3-2 mediarecorder change v2
Review of attachment 8337468 [details] [diff] [review]:
-----------------------------------------------------------------
In the commit message:
"framework"
"Start recording only after tracks have been added"
::: content/media/MediaRecorder.cpp
@@ +121,5 @@
> + {
> + mSession->AfterSetupStreams(aStream->GetHintContents());
> + }
> + private:
> + Session *mSession;
I think you should make this an nsRefPtr<Session> to ensure it doesn't get destroyed while we're waiting for tracks.
@@ +280,5 @@
> + TracksAvailableCallback* tracksAvailableCallback = new TracksAvailableCallback(mRecorder->mSession);
> + mRecorder->mStream->OnTracksAvailable(tracksAvailableCallback);
> + }
> +
> + void AfterSetupStreams(uint8_t aTrackTypes)
Call this AfterTracksAdded
@@ +306,5 @@
> + // shutdown notification and stop Read Thread.
> + nsContentUtils::RegisterShutdownObserver(this);
> +
> + mReadThread->Dispatch(new ExtractRunnable(this), NS_DISPATCH_NORMAL);
> +
Remove blank line
Attachment #8337468 -
Flags: review?(roc) → review-
Comment on attachment 8336999 [details] [diff] [review]
part 3-3 mediaencoder change v1
Review of attachment 8336999 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +6,5 @@
> #include "MediaDecoder.h"
> #include "nsIPrincipal.h"
> +#include "nsMimeTypes.h"
> +
> +#define WEBM_ENCODER defined(MOZ_VP8_ENCODER) && defined(MOZ_VORBIS_ENCODER)
I think you should write
#if defined(MOZ_VP8_ENCODER) && defined(MOZ_VORBIS_ENCODER)
#define WEBM_ENCODER
#endif
@@ +68,3 @@
>
> } else {
> // Type video is not supported for now.
Remove this comment
@@ +86,4 @@
>
> /* static */
> already_AddRefed<MediaEncoder>
> +MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint8_t aContentHinet)
aTrackTypes
@@ +119,5 @@
> + writer = new WebMWriter(aContentHinet); //TEST
> +#endif
> + } else {
> + NS_ASSERTION(false, "Can't support this mimeType");
> + return nullptr;
The code that handles an empty MIME type has disappeared :-). It should be here. Probably the best way to write this is probably
if (Ogg enabled and (Ogg MIME type or (no MIME type and no video track))) {
... generate Ogg and use Ogg MIME type ...
} else if (OMX enabled and (MP4 MIME type or no MIME type)) {
... generate MP4 and use MP4 MIME type ...
} else if (WebM enabled and (WebM MIME type or no MIME type)) {
... generate WebM and use WebM MIME type ...
}
::: content/media/encoder/MediaEncoder.h
@@ +123,4 @@
> }
>
> private:
> + template<class T> nsresult WrtieEncodedDataToMuxer(T aEncoder);
WriteEncodedDataToMuxer
Attachment #8336999 -
Flags: review?(roc) → review-
Comment 100•11 years ago
|
||
(Delete some deprecated attachments.)
Hi Roc, thanks for pointing out the problem in previous comment! I guess the |AppendAudioSegment| was skipping the null chunks before. Anyway, now that I think we don't need |mNullDuration| anymore, but need a flag to prevent re-setting EOS to codec-encoder in TrackEncdoer.
Attachment #828541 -
Attachment is obsolete: true
Attachment #829852 -
Attachment is obsolete: true
Attachment #830096 -
Attachment is obsolete: true
Attachment #8334910 -
Attachment is obsolete: true
Attachment #8336408 -
Attachment is obsolete: true
Attachment #8337515 -
Flags: review?(roc)
Attachment #8337515 -
Flags: review?(roc) → review+
Comment 101•11 years ago
|
||
Update comment in |AudioTrackEncoder::NotifyEndOfStream()|.
Attachment #8337515 -
Attachment is obsolete: true
Attachment #8337555 -
Flags: review?(roc)
Comment 102•11 years ago
|
||
Implementation of VideoTrackEncoder.
Attachment #8337556 -
Flags: review?(roc)
Assignee | ||
Comment 103•11 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #98)
> Comment on attachment 8337468 [details] [diff] [review]
> part 3-2 mediarecorder change v2
>
> Review of attachment 8337468 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> In the commit message:
> "framework"
> "Start recording only after tracks have been added"
>
> ::: content/media/MediaRecorder.cpp
> @@ +121,5 @@
> > + {
> > + mSession->AfterSetupStreams(aStream->GetHintContents());
> > + }
> > + private:
> > + Session *mSession;
>
> I think you should make this an nsRefPtr<Session> to ensure it doesn't get
> destroyed while we're waiting for tracks.
oh...OK. I will modify this part at this patch...It seems not easy to change :(
> @@ +280,5 @@
> > + TracksAvailableCallback* tracksAvailableCallback = new TracksAvailableCallback(mRecorder->mSession);
> > + mRecorder->mStream->OnTracksAvailable(tracksAvailableCallback);
> > + }
> > +
> > + void AfterSetupStreams(uint8_t aTrackTypes)
>
> Call this AfterTracksAdded
>
> @@ +306,5 @@
> > + // shutdown notification and stop Read Thread.
> > + nsContentUtils::RegisterShutdownObserver(this);
> > +
> > + mReadThread->Dispatch(new ExtractRunnable(this), NS_DISPATCH_NORMAL);
> > +
>
> Remove blank line
Attachment #8337555 -
Flags: review?(roc) → review+
Comment on attachment 8337556 [details] [diff] [review]
Part2: Add VideoTrackEncoder
Review of attachment 8337556 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/TrackEncoder.h
@@ +287,5 @@
> +
> + /**
> + * A segment queue of audio track data, protected by mReentrantMonitor.
> + */
> + nsAutoPtr<VideoSegment> mRawSegment;
Actually ... this can just be a VideoSegment. It doesn't need to be heap-allocated.
Attachment #8337556 -
Flags: review?(roc) → review+
Comment 105•11 years ago
|
||
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #104)
> Comment on attachment 8337556 [details] [diff] [review]
> Part2: Add VideoTrackEncoder
>
> Review of attachment 8337556 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: content/media/encoder/TrackEncoder.h
> @@ +287,5 @@
> > +
> > + /**
> > + * A segment queue of audio track data, protected by mReentrantMonitor.
> > + */
> > + nsAutoPtr<VideoSegment> mRawSegment;
>
> Actually ... this can just be a VideoSegment. It doesn't need to be
> heap-allocated.
Yeah, I thought so too, thanks!
Comment 106•11 years ago
|
||
Change in this rev:
- Use AudioSegment for mRawSegment in AudioTrackEncoder and AudioSegment for mSourceSegment in OpusTrackEncoder, for the purpose of avoiding head-allocation.
Attachment #8337555 -
Attachment is obsolete: true
Attachment #8337644 -
Flags: review?(roc)
Comment 107•11 years ago
|
||
Removed an extra line of space.
Attachment #8337644 -
Attachment is obsolete: true
Attachment #8337644 -
Flags: review?(roc)
Attachment #8337652 -
Flags: review?(roc)
Comment 108•11 years ago
|
||
Use VideoSegment for mRawSegment in VideoTrackEncoder, to avoid heap-allocation.
Attachment #8337556 -
Attachment is obsolete: true
Attachment #8337653 -
Flags: review?(roc)
Assignee | ||
Comment 109•11 years ago
|
||
Fix nits.
Attachment #8337468 -
Attachment is obsolete: true
Attachment #8337679 -
Flags: review?(roc)
Updated•11 years ago
|
Attachment #8336612 -
Attachment is obsolete: true
Comment 110•11 years ago
|
||
Per discussion offline - this is being moved out of scope for 1.3. We will target this feature for 1.4.
However, we don't block on targeted features, so this is no longer a blocker.
blocking-b2g: 1.3+ → -
Comment 111•11 years ago
|
||
Rebased to the change set of bug 935774.
Attachment #8337652 -
Attachment is obsolete: true
Attachment #8337652 -
Flags: review?(roc)
Attachment #8338320 -
Flags: review?(roc)
Updated•11 years ago
|
Attachment #8337652 -
Attachment is obsolete: false
Comment 112•11 years ago
|
||
Fix compiling error.
Attachment #8337652 -
Attachment is obsolete: true
Attachment #8338320 -
Attachment is obsolete: true
Attachment #8338320 -
Flags: review?(roc)
Attachment #8338354 -
Flags: review?(roc)
Assignee | ||
Comment 113•11 years ago
|
||
Attachment #8336999 -
Attachment is obsolete: true
Assignee | ||
Comment 114•11 years ago
|
||
Fix conflict.
Attachment #8338982 -
Attachment is obsolete: true
Comment 115•11 years ago
|
||
Fix memory leak problem on mochitest.
Attachment #8337653 -
Attachment is obsolete: true
Attachment #8338354 -
Attachment is obsolete: true
Attachment #8337653 -
Flags: review?(roc)
Attachment #8338354 -
Flags: review?(roc)
Attachment #8339191 -
Flags: review?(roc)
Comment 116•11 years ago
|
||
Attachment #8339192 -
Flags: review?(roc)
Comment 117•11 years ago
|
||
Attachment #8339192 -
Attachment is obsolete: true
Attachment #8339192 -
Flags: review?(roc)
Attachment #8339193 -
Flags: review?(roc)
Comment 118•11 years ago
|
||
Assignee | ||
Comment 119•11 years ago
|
||
Let OMX encoder, muxer to reference.
Comment on attachment 8337679 [details] [diff] [review]
part 3-2 mediarecorder change v3
Review of attachment 8337679 [details] [diff] [review]:
-----------------------------------------------------------------
Fix typo in commit message ("framewrok")
Attachment #8337679 -
Flags: review?(roc) → review+
Comment on attachment 8339191 [details] [diff] [review]
Part1: Refactor of TrackEncoder
Review of attachment 8339191 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/OpusTrackEncoder.h
@@ +29,5 @@
> class OpusTrackEncoder : public AudioTrackEncoder
> {
> public:
> OpusTrackEncoder();
> + ~OpusTrackEncoder();
This should still be declared virtual.
Attachment #8339191 -
Flags: review?(roc) → review+
Attachment #8339193 -
Flags: review?(roc) → review+
Comment 122•11 years ago
|
||
Thanks Roc :).
Attachment #8339191 -
Attachment is obsolete: true
Attachment #8340861 -
Flags: review?(roc)
Comment 123•11 years ago
|
||
Comment on attachment 8340861 [details] [diff] [review]
Part1: Refactor of TrackEncoder
Review of attachment 8340861 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/OpusTrackEncoder.cpp
@@ +140,5 @@
> ReentrantMonitorAutoEnter mon(mReentrantMonitor);
> // This version of encoder API only support 1 or 2 channels,
> // So set the mChannels less or equal 2 and
> // let InterleaveTrackData downmix pcm data.
> + mChannels = aChannels > MAX_CHANNELS ? MAX_CHANNELS : aChannels;
Although we will need to support more than two channels eventually, put the #define back instead of writing a magic number 2 here.
Attachment #8340861 -
Flags: review?(roc) → review+
Assignee | ||
Comment 124•11 years ago
|
||
Comment on attachment 8339193 [details] [diff] [review]
Part2: Add VideoTrackEncoder
obsolete those patch and it will land on another bug.
Bug 945135 - [MediaEncoder] Refactor TrackEncoder and add VideoTrackEncoder
Attachment #8339193 -
Attachment is obsolete: true
Assignee | ||
Comment 125•11 years ago
|
||
Comment on attachment 8340861 [details] [diff] [review]
Part1: Refactor of TrackEncoder
obsolete those patch and it will land on another bug.
Bug 945135 - [MediaEncoder] Refactor TrackEncoder and add VideoTrackEncoder
Attachment #8340861 -
Attachment is obsolete: true
Assignee | ||
Comment 126•11 years ago
|
||
Hi Roc,
I found if I registe onTracksAvailable, start after track available, and it would make media recorder become a async function. Should we add a onstart callback and change the whole test case?
Flags: needinfo?(roc)
Yes, I think so.
Flags: needinfo?(roc)
Assignee | ||
Updated•11 years ago
|
Summary: Support Video Encoder module in MediaEncoder framewrok → Support Video Encoder module in MediaEncoder framework
Assignee | ||
Comment 128•11 years ago
|
||
New one for fix some problems on b2g platform.
Attachment #8339000 -
Attachment is obsolete: true
Attachment #8341601 -
Flags: review?(roc)
Comment on attachment 8341601 [details] [diff] [review]
part 3-3 mediaencoder change v3
Review of attachment 8341601 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +89,5 @@
> +#ifdef MOZ_OMX_ENCODER
> + aMIMEType = NS_LITERAL_STRING(VIDEO_MP4);
> +#elif WEBM_ENCODER
> + aMIMEType = NS_LITERAL_STRING(VIDEO_WEBM);
> +#endif
This is going back to the problem you had earlier in the patch history, where here you're not taking account of IsOggEnabled etc. I think you really need to do that. I think the approach in comment #99 is still the right approach.
@@ +251,5 @@
> }
> + LOG(PR_LOG_DEBUG, ("Video encoded TimeStamp = %f", GetEncodeTimeStamp()));
> + bool isAudioCompleted = mAudioEncoder != nullptr ?
> + mAudioEncoder->IsEncodingComplete() : true;
> + bool isVideoCompleted = mVideoEncoder != nullptr ?
Write this as
bool isAudioCompeted = mAudioEncoder && mAudioEncoder->IsEncodingComplete().
Basically, if "true" or "false" appear as one of the values in a ?: operator, something's wrong :-).
@@ +280,5 @@
> }
> }
>
> +template<class T> nsresult
> +MediaEncoder::WrtieEncodedDataToMuxer(T aEncoder)
If aEncoder is a pointer, make it a T*.
@@ +290,5 @@
> + return NS_OK;
> + }
> + EncodedFrameContainer encodedVideoData;
> + nsresult rv = NS_OK;
> + rv = aEncoder->GetEncodedTrack(encodedVideoData);
Just
nsresult rv = aEncoder->GetEncodedTrack(...);
@@ +309,4 @@
> }
> +
> +template<class T> nsresult
> +MediaEncoder::SetEncodedMetadataToMuxer(T aEncoder)
Call this CopyMetadataToMuxer?
::: content/media/encoder/MediaEncoder.h
@@ +132,5 @@
> return mState == ENCODE_ERROR;
> }
>
> private:
> + template<class T> nsresult WrtieEncodedDataToMuxer(T aEncoder);
Fix typo in "Write"
@@ +133,5 @@
> }
>
> private:
> + template<class T> nsresult WrtieEncodedDataToMuxer(T aEncoder);
> + template<class T> nsresult SetEncodedMetadataToMuxer(T aEncoder);
Please document what T is in these templates.
::: content/media/ogg/OggWriter.h
@@ +31,5 @@
>
> // Check metadata type integrity and reject unacceptable track encoder.
> nsresult SetMetadata(TrackMetadataBase* aMetadata) MOZ_OVERRIDE;
>
> + bool IsWritingComplete() { return mIsWritingComplete; };
Shouldn't this be in ContainerWriter?
Attachment #8341601 -
Flags: review?(roc) → review-
Assignee | ||
Comment 130•11 years ago
|
||
Fix nits
1. Remove template (don't need it...)
2. Rename some function
3. add isXXXEnable in CreateEncoder function.
BTW, should we add the preferences for all codecs ?
omx audio/video vp8/vorbis /mp4 muxer, webm muxer.
Attachment #8341601 -
Attachment is obsolete: true
Attachment #8342131 -
Flags: review?(roc)
Comment on attachment 8342131 [details] [diff] [review]
part 3-3 mediaencoder change v4
Review of attachment 8342131 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +34,1 @@
> #endif
Add #undef LOG to the end of the file to help with unified builds.
@@ +90,5 @@
> + aMIMEType = NS_LITERAL_STRING(VIDEO_MP4);
> +#elif WEBM_ENCODER
> + aMIMEType = NS_LITERAL_STRING(VIDEO_WEBM);
> +#endif
> + return;
The first part of my comment in comment #129 still applies. We shouldn't default to a type which is disabled.
Attachment #8342131 -
Flags: review?(roc) → review-
Assignee | ||
Comment 132•11 years ago
|
||
For this part, should we check on both mimeType and create track encoder/writer?
Right now I set check point on create track encoder/writer section.
Assignee | ||
Comment 134•11 years ago
|
||
1. Add undef LOG, (others file add near the header..)
2. for mimeType choose,
The follow would be
1. If client pass "" as mimeType into encoder, then call GetDefaultEncodeMIMEType,
It would return platform supported mimeType based on tracktypes
We still try to enable audio track if the media stream contains video track.
2. create track/writer base on mimeType and build flag and perf enabled.
For WebM/MP4, should we add all of the codec/muxer perf items?
Attachment #8342131 -
Attachment is obsolete: true
Attachment #8342273 -
Flags: review?(roc)
What's wrong with the code structure I suggested in comment #99?
Assignee | ||
Comment 136•11 years ago
|
||
follow by comment 99 suggestion. :-)
Attachment #8342273 -
Attachment is obsolete: true
Attachment #8342273 -
Flags: review?(roc)
Attachment #8342827 -
Flags: review?(roc)
Assignee | ||
Comment 137•11 years ago
|
||
Hi roc,
About the start method, the w3c autohr Jim said the start function would return when the encoder is ready to encoding.
So I think the start should be a synchronize function, is it right?
But when I try to use the OnTracksAvailable to notify the encoder can start to record. I register the callback and I let the function just return without wait, As before I used mutex to wait the media stream ready and then return the function result. But you said we should not block the main thread. So I got confused with the Jim's response.
Flags: needinfo?(roc)
Assignee | ||
Comment 138•11 years ago
|
||
Fix try to record video frame only and notify wrong audio chunk to encoder issue.
Attachment #8342827 -
Attachment is obsolete: true
Attachment #8342827 -
Flags: review?(roc)
Attachment #8344575 -
Flags: review?(roc)
Comment 139•11 years ago
|
||
(In reply to Randy Lin [:rlin] from comment #137)
> Hi roc,
> About the start method, the w3c autohr Jim said the start function would
> return when the encoder is ready to encoding.
> So I think the start should be a synchronize function, is it right?
>
> But when I try to use the OnTracksAvailable to notify the encoder can start
> to record. I register the callback and I let the function just return
> without wait, As before I used mutex to wait the media stream ready and then
> return the function result. But you said we should not block the main
> thread. So I got confused with the Jim's response.
Where did jim say this? Synchronous functions that aren't guaranteed to be fast are a problem from a "jank"/blocking-main-thread point-of-view. People who work on Chrome tend to forget this, due to their multi-process architecture and UI split from content processes.
I don't believe start() is supposed to be synchronous. If it was, there wouldn't need to be an onstart event.
Flags: needinfo?(roc)
Comment on attachment 8344575 [details] [diff] [review]
part 3-3 mediaencoder change v4 .3
Review of attachment 8344575 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/encoder/MediaEncoder.cpp
@@ +7,5 @@
> #include "nsIPrincipal.h"
> +#include "nsMimeTypes.h"
> +#include "prlog.h"
> +
> +#define WEBM_ENCODER defined(MOZ_VP8_ENCODER) && defined(MOZ_VORBIS_ENCODER) && defined(MOZ_WEBM)
For consistency, WEBM_ENCODER should be either defined or undefined, instead of always being defined to 0 or 1.
@@ +102,3 @@
> }
> +#if WEBM_ENCODER
> + else if (MediaDecoder::IsWebMEnabled() && (mimeType.Equals(NS_LITERAL_STRING(VIDEO_WEBM)) ||
Use EqualsLiteral. But shouldn't you be checking aMIMEType instead of mimeType?
@@ +102,4 @@
> }
> +#if WEBM_ENCODER
> + else if (MediaDecoder::IsWebMEnabled() && (mimeType.Equals(NS_LITERAL_STRING(VIDEO_WEBM)) ||
> + aTrackTypes & ContainerWriter::HAS_VIDEO)) {
Fix line breaking. You should have parentheses around the & subexpression.
@@ +114,5 @@
> }
> +#endif //WEBM_ENCODER
> +#if MOZ_OMX_ENCODER
> + else if (mimeType.Equals(NS_LITERAL_STRING(VIDEO_MP4)) ||
> + aTrackTypes & ContainerWriter::HAS_VIDEO)) {
() around & subexpression
@@ +129,5 @@
> +#ifdef MOZ_OGG
> + else if (MediaDecoder::IsOggEnabled() && (mimeType.Equals(NS_LITERAL_STRING(AUDIO_OGG)) ||
> + aTrackTypes & ContainerWriter::HAS_AUDIO)) {
> + writer = new OggWriter();
> + if (MediaDecoder::IsOpusEnabled()) {
We should check IsOpusEnabled in the if condition above, instead of IsOggEnabled. (Actually we should probably check both.) No point in creating an empty OggWriter.
@@ +147,2 @@
> encoder = new MediaEncoder(writer.forget(), audioEncoder.forget(),
> + videoEncoder.forget(), mimeType);
Need to set mimeType to the correct type in each case. Right now I think you're not setting it anywhere?
Attachment #8344575 -
Flags: review?(roc) → review-
Assignee | ||
Comment 142•11 years ago
|
||
I start a discuss in media-capture called
"Re: Expect behavior of calling stop before receiving the onstart event on MediaRecorder API?"
And some people start to discuss this behavior.
On the w3c spec, this sentence make me confuse.
==>
https://dvcs.w3.org/hg/dap/raw-file/tip/media-stream-capture/MediaRecorder.html
start method:
If the state is not "inactive", raise a DOM InvalidState error and terminate these steps. Otherwise:
Set state to 'recording' and wait until media becomes available from stream.
Assignee | ||
Comment 143•11 years ago
|
||
Thanks roc's detail view..
Fix nits and mimeType issue :| , also let the build flag to be the same style.
Attachment #8344575 -
Attachment is obsolete: true
Attachment #8345164 -
Flags: review?(roc)
Updated•11 years ago
|
Whiteboard: [ft:media-recording] → [ft:multimedia-platform]
Comment on attachment 8345164 [details] [diff] [review]
part 3-3 mediaencoder change v4 .4
Review of attachment 8345164 [details] [diff] [review]:
-----------------------------------------------------------------
r+ with those fixed.
::: content/media/encoder/MediaEncoder.cpp
@@ +100,3 @@
> }
> +#ifdef MOZ_WEBM_ENCODER
> + else if (MediaDecoder::IsWebMEnabled() &&
Remove "else" since there's a return in the previous if block.
@@ +100,5 @@
> }
> +#ifdef MOZ_WEBM_ENCODER
> + else if (MediaDecoder::IsWebMEnabled() &&
> + (aMIMEType.EqualsLiteral(VIDEO_WEBM) ||
> + (aTrackTypes & ContainerWriter::HAS_VIDEO))) {
Indent this last line one space so the two subexpressions of || are aligned
@@ +114,5 @@
> + }
> +#endif //MOZ_WEBM_ENCODER
> +#ifdef MOZ_OMX_ENCODER
> + else if (aMIMEType.EqualsLiteral(VIDEO_MP4) ||
> + (aTrackTypes & ContainerWriter::HAS_VIDEO))) {
Same here.
You probably want to put the OMX case above the WEBM case so if we support both, there is no MIME type provided, and there is a video track, we default to OMX.
@@ +130,4 @@
> #ifdef MOZ_OGG
> + else if (MediaDecoder::IsOggEnabled() && MediaDecoder::IsOpusEnabled() &&
> + (aMIMEType.EqualsLiteral(AUDIO_OGG) ||
> + (aTrackTypes & ContainerWriter::HAS_AUDIO))) {
and here
@@ +148,2 @@
> encoder = new MediaEncoder(writer.forget(), audioEncoder.forget(),
> + videoEncoder.forget(), mimeType);
I think we will need to do something to be more flexible with the MIME types we accept here. Although I guess right now we don't actually have an API to choose the MIME type, so we can fix that later.
@@ +229,5 @@
> }
> + LOG(PR_LOG_DEBUG, ("Video encoded TimeStamp = %f", GetEncodeTimeStamp()));
> + // In audio only or video only case, let unavailable track's flag to be true.
> + bool isAudioCompleted = (mAudioEncoder && mAudioEncoder->IsEncodingComplete()) || !mAudioEncoder;
> + bool isVideoCompleted = (mVideoEncoder && mVideoEncoder->IsEncodingComplete()) || !mVideoEncoder;
Lines too long, break them.
Attachment #8345164 -
Flags: review?(roc) → review+
Assignee | ||
Comment 145•11 years ago
|
||
Fix crash problem.
Attachment #8337679 -
Attachment is obsolete: true
Attachment #8347691 -
Flags: review?(roc)
Assignee | ||
Comment 146•11 years ago
|
||
Assignee | ||
Updated•11 years ago
|
Attachment #8347693 -
Flags: review?(roc)
Assignee | ||
Comment 147•11 years ago
|
||
found a typo...
Attachment #8347693 -
Attachment is obsolete: true
Attachment #8347693 -
Flags: review?(roc)
Attachment #8347694 -
Flags: review?(roc)
Assignee | ||
Updated•11 years ago
|
Attachment #8347694 -
Flags: review?(roc)
Assignee | ||
Comment 149•11 years ago
|
||
hmm, found OS X 10.8 Debug stop method run slower than others, so the encoder can start to encode and output blob with data. Remove the blob's mimeType or length check.
Attachment #8347694 -
Attachment is obsolete: true
Attachment #8347882 -
Flags: review?(roc)
Updated•11 years ago
|
Target Milestone: 1.3 Sprint 6 - 12/6 → 1.3 C1/1.4 S1(20dec)
Attachment #8347691 -
Flags: review?(roc) → review+
Assignee | ||
Comment 150•11 years ago
|
||
Change to check the blob item case by case.
Attachment #8347882 -
Attachment is obsolete: true
Attachment #8347882 -
Flags: review?(roc)
Attachment #8348487 -
Flags: review?(roc)
Attachment #8348487 -
Flags: review?(roc) → review+
Comment 151•11 years ago
|
||
Comment on attachment 8348487 [details] [diff] [review]
part 3-4 record_immediate_stop test case change v3
Review of attachment 8348487 [details] [diff] [review]:
-----------------------------------------------------------------
review- mainly because one of the tests was removed & the size test isn't ensuring that the size isn't negative.
::: content/media/test/test_mediarecorder_record_immediate_stop.html
@@ +67,5 @@
>
> ok(evt instanceof BlobEvent,
> 'Events fired from ondataavailable should be BlobEvent');
> is(evt.type, 'dataavailable',
> 'Event type should dataavailable');
Nit - insert a blank line here
@@ -71,5 @@
> 'Event type should dataavailable');
> - ok(evt.data.size > 0,
> - 'Blob data received should be greater than zero');
> - is(evt.data.type, expectedMimeType,
> - 'Blob data received should have type = ' + expectedMimeType);
Why is this removed?
@@ +73,5 @@
> + // On some platforms, the stop method may run after media stream track
> + // available, so the blob can contain the header data.
> + if (evt.data.size > 0) {
> + info(evt.data.size > 0,
> + 'Blob data received should be greater than zero');
I'd recommend changing this to:
info('Blob data size is greater than zero');
Given that you already know the blob size is greater than zero at this point.
@@ +76,5 @@
> + info(evt.data.size > 0,
> + 'Blob data received should be greater than zero');
> + is(evt.data.type, expectedMimeType,
> + 'Blob data received should have type = ' + expectedMimeType);
> + } else {
An else statement won't work here, as this allows for negative numbers.
@@ +78,5 @@
> + is(evt.data.type, expectedMimeType,
> + 'Blob data received should have type = ' + expectedMimeType);
> + } else {
> + info(evt.data.size == 0,
> + 'Blob data received should be zero');
I'd recommend changing this to:
info('Blob data size should be zero');
Given that you already know the blob size is zero at this point.
Attachment #8348487 -
Flags: review-
Assignee | ||
Comment 152•11 years ago
|
||
Comment on attachment 8348487 [details] [diff] [review]
part 3-4 record_immediate_stop test case change v3
Review of attachment 8348487 [details] [diff] [review]:
-----------------------------------------------------------------
::: content/media/test/test_mediarecorder_record_immediate_stop.html
@@ -71,5 @@
> 'Event type should dataavailable');
> - ok(evt.data.size > 0,
> - 'Blob data received should be greater than zero');
> - is(evt.data.type, expectedMimeType,
> - 'Blob data received should have type = ' + expectedMimeType);
Because in some platforms, the encoder haven't started and encoder should choose what kind of mimeType can be used for output blob.
Assignee | ||
Comment 153•11 years ago
|
||
Fix nits.
Attachment #8348487 -
Attachment is obsolete: true
Attachment #8348495 -
Flags: review?(jsmith)
Comment 154•11 years ago
|
||
(In reply to Randy Lin [:rlin] from comment #152)
> Comment on attachment 8348487 [details] [diff] [review]
> part 3-4 record_immediate_stop test case change v3
>
> Review of attachment 8348487 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: content/media/test/test_mediarecorder_record_immediate_stop.html
> @@ -71,5 @@
> > 'Event type should dataavailable');
> > - ok(evt.data.size > 0,
> > - 'Blob data received should be greater than zero');
> > - is(evt.data.type, expectedMimeType,
> > - 'Blob data received should have type = ' + expectedMimeType);
>
> Because in some platforms, the encoder haven't started and encoder should
> choose what kind of mimeType can be used for output blob.
Right - but you need to handle this in that in your if statements respectively in the updated code. Meaning:
if (evt.data.size > 0) {
is(evt.data.type, expectedMimeType, 'Blob data received..');
} else if (evt.data.size === 0) {
is(evt.data.type, '', 'Blob data mime type is empty...');
}
Comment 155•11 years ago
|
||
Comment on attachment 8348495 [details] [diff] [review]
part 3-4 record_immediate_stop test case change v3 .1
Clearing review to address the comment above.
Attachment #8348495 -
Flags: review?(jsmith)
Assignee | ||
Comment 156•11 years ago
|
||
Hi Jason, the v3-1 already have the blob check as my comment.
But I still updated new one. Please help to review it, thanks.
Attachment #8348495 -
Attachment is obsolete: true
Attachment #8348847 -
Flags: review?(jsmith)
Comment 157•11 years ago
|
||
Comment on attachment 8348847 [details] [diff] [review]
part 3-4 record_immediate_stop test case change v3 .2
Review of attachment 8348847 [details] [diff] [review]:
-----------------------------------------------------------------
review- - make sure you are testing evt.data.type & mediaRecorder.type in the if statement & else if statement for what you are expecting in those blocks respectively.
::: content/media/test/test_mediarecorder_record_immediate_stop.html
@@ +74,5 @@
> + // On some platforms, the stop method may run after media stream track
> + // available, so the blob can contain the header data.
> + if (evt.data.size > 0) {
> + is(evt.data.type, expectedMimeType,
> + 'Blob data received and should have mime type');
So within this if statement & the else if statement, I think you should be testing evt.data.type & mediaRecorder.type. Right now, you are only testing one of the two them.
@@ +78,5 @@
> + 'Blob data received and should have mime type');
> + } else if (evt.data.size === 0) {
> + is(mediaRecorder.mimeType, '',
> + 'Blob data mime type is empty');
> + }
Nit - include an else statement here to report an error if the size is negative.
Attachment #8348847 -
Flags: review?(jsmith) → review-
Comment 158•11 years ago
|
||
For clarity - here's what I'd expect the code to look like (ignoring the string messages):
if (evt.data.size > 0) {
is(evt.data.type, expectedMimeType, '...');
is(mediaRecorder.type, expectedMimeType, '...');
} else if (evt.data.size === 0) {
is(evt.data.type, '', '...');
is(mediaRecorder.type, '', '...');
} else {
ok(false, '...')
}
Assignee | ||
Comment 159•11 years ago
|
||
oh, you reqeust to check the mediaRecorder.mimeType
hmm, I miss it.
Assignee | ||
Comment 160•11 years ago
|
||
Attachment #8348847 -
Attachment is obsolete: true
Attachment #8349176 -
Flags: review?(jsmith)
Comment 161•11 years ago
|
||
Comment on attachment 8349176 [details] [diff] [review]
part 3-4 record_immediate_stop test case change v4
Review of attachment 8349176 [details] [diff] [review]:
-----------------------------------------------------------------
review+ with the one fix included
::: content/media/test/test_mediarecorder_record_immediate_stop.html
@@ +83,5 @@
> + 'Blob data mime type is empty');
> + is(mediaRecorder.mimeType, '',
> + 'Media Recorder mime type in ondataavailable is empty');
> + } else {
> + is(false, 'Blob size can not be negative');
This should be ok, not is.
Attachment #8349176 -
Flags: review?(jsmith) → review+
Assignee | ||
Comment 162•11 years ago
|
||
carry reviewer and fix comment.
Assignee | ||
Comment 163•11 years ago
|
||
carry reviewer.
Assignee | ||
Comment 164•11 years ago
|
||
check-in patch, carry reviewer.
Assignee | ||
Comment 165•11 years ago
|
||
carry reviewer, check-in patch
Assignee | ||
Comment 166•11 years ago
|
||
Keywords: checkin-needed
Comment 167•11 years ago
|
||
Plus it for v1.4 because it is the committed feature work
blocking-b2g: - → 1.4+
Assignee | ||
Comment 168•11 years ago
|
||
Fix minor bug, should return nullptr when create encoder fail.
Attachment #8349277 -
Attachment is obsolete: true
Updated•11 years ago
|
Attachment #8349176 -
Attachment is obsolete: true
Updated•11 years ago
|
Attachment #8337469 -
Attachment is obsolete: true
Updated•11 years ago
|
Attachment #8340201 -
Attachment is obsolete: true
Attachment #8340201 -
Attachment is patch: true
Updated•11 years ago
|
Attachment #8345164 -
Attachment is obsolete: true
Updated•11 years ago
|
Attachment #8347691 -
Attachment is obsolete: true
Comment 169•11 years ago
|
||
https://hg.mozilla.org/integration/b2g-inbound/rev/907dc12d8698
https://hg.mozilla.org/integration/b2g-inbound/rev/8517500c5728
https://hg.mozilla.org/integration/b2g-inbound/rev/055ade51ac29
https://hg.mozilla.org/integration/b2g-inbound/rev/10238ed91dd7
Flags: in-testsuite+
Keywords: checkin-needed
Comment 170•11 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/907dc12d8698
https://hg.mozilla.org/mozilla-central/rev/8517500c5728
https://hg.mozilla.org/mozilla-central/rev/055ade51ac29
https://hg.mozilla.org/mozilla-central/rev/10238ed91dd7
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Updated•11 years ago
|
Component: Video/Audio → Video/Audio: Recording
Depends on: 973522
Updated•11 years ago
|
Comment 172•9 years ago
|
||
(In reply to Eric Shepherd [:sheppy] from comment #171)
> + dev-doc-needed
For writers: The main thing here is the addition of video recording support to Firefox in Firefox 29. We need to update all pages that say this isn't implemented yet.
You need to log in
before you can comment on or make changes to this bug.
Description
•