Home > Mobile >  Video function to solve AudioRecord MediaCodec camera2
Video function to solve AudioRecord MediaCodec camera2

Time:09-20

Functional requirement is that the video recording and save for the mp4 files, because of the need to take two sound channel input after the sound of a voice channel, so must cooperate AudioRecord to collect audio source, use camera2 take video, voice and video by MediaCodec coding, finally made channel MediaMuxer merged into mp4,

After open the camera to enable MediaCodec encoding synthesis there is no problem,,,


But but but,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Because the video is segmented to record (according to K song video, to record every song), can produce such as video a 5 minute video, after the record closed immediately, and video to record the second paragraph, immediately so camera2 cannot be closed (start time is longer),

So I take apart the two steps, the first step is to camera2 through MediaCodec (call it A) processing to generate data flow, open after the camera has been transfer, don't stop,
The second step to video, to create A new MediaCodec (call it B), on receiving A flow, processing it add MediaMuxer merged into mp4 with sound,


The problem is that B is unable to process A data, or stuck, or pulling out of the loan, the great god help, genuflect is begged devious! Devious! Devious! Important things (three times)



for the code snippet below:

Try {
/* */
create encoderMMuxerMediaCodec=MediaCodec. CreateEncoderByType (codecType);
} the catch (IOException e) {
The d (Tag, "getMuxerMediaCodec" + um participant etMessage ());
MMuxerMediaCodec=null;
}
If (mMuxerMediaCodec==null) return;
/* set encoding parameters */
MediaFormat mediaFormatSave=MediaFormat. CreateVideoFormat (codecType, CanUseMinSize getWidth (), CanUseMinSize. GetHeight ());
/* set the color format */
MediaFormatSave. SetInteger (MediaFormat. KEY_COLOR_FORMAT, MediaCodecInfo. CodecCapabilities. COLOR_FormatSurface);
/* set the bit rate */
MediaFormatSave. SetInteger (MediaFormat KEY_BIT_RATE, 1200000);
Set the frame rate *//*
MediaFormatSave. SetInteger (MediaFormat KEY_FRAME_RATE, 24).
/* set keyframes time interval (S) */
MediaFormatSave. SetInteger (MediaFormat. KEY_I_FRAME_INTERVAL, 2);

//set the h264 of PPS and SPS data
Byte [] header_sps={0, 0, 0, 1, 103, 66, 0, 42, 149 (byte), 168 (byte), 30, 0, 137 (byte), (byte), 249, 102, 224 (byte), 32, 32, 32, 64};
Byte [] header_pps={0, 0, 0, 1, 104, 206 (byte), 60, 128 (byte), 0, 0, 0, 1, 6, 229 (byte), 1, 151 (byte), 128} (byte);
MediaFormatSave. SetByteBuffer (" CSD "0, ByteBuffer. Wrap (header_sps));
MediaFormatSave. SetByteBuffer (" CSD - 1 ", ByteBuffer. Wrap (header_pps));

//if the format for the decoder, here said the format of the input data; If for the encoder, the output data format,
Specify a surface//surface, can be used as the output of the decode rendering,
//crypto if need to the media data encryption, specify here a crypto class.
//if the flags are configured object is used as the encoder, with CONFIGURE_FLAG_ENCODE here,
MMuxerMediaCodec. Configure (mediaFormatSave, mRSurfaceHolder getSurface (), null, MediaCodec. CRYPTO_MODE_UNENCRYPTED);
//mMuxerMediaCodec getOutputFormat ();
MMuxerMediaCodec. Start ();




























-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- writing data:
Try {
InputBufferIndex=mMediaCodec. DequeueInputBuffer (10000);
} the catch (an IllegalStateException e) {
The w (Tag, FromType + "encode an IllegalStateException:" + um participant etMessage ());
return;
}
The d (Tag, "encode mMediaCodec:" + FromType);
The d (Tag, FromType + "inputBufferIndex:" + String. The valueOf (inputBufferIndex));
If (inputBufferIndex & gt;=0) {
ByteBuffer inputBuffer=mMediaCodec. GetInputBuffer (inputBufferIndex);
InputBuffer. The clear ();
If (buffer!=null) {
InputBuffer. Put (buffer);
}
//the v (Tag, "encode: queueInputBuffer");
If (buffer==null) {
The Log i. (Tag, "send BUFFER_FLAG_END_OF_STREAM");
MMediaCodec. QueueInputBuffer (inputBufferIndex, 0, 0, presentationTimeUs, MediaCodec BUFFER_FLAG_END_OF_STREAM);
return;
}
MMediaCodec. QueueInputBuffer (inputBufferIndex, 0, inputBuffer limit (), presentationTimeUs, 0).
} else if (inputBufferIndex==MediaCodec INFO_TRY_AGAIN_LATER) {
}

























-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- data out


Try {
Status=mMediaCodec. DequeueOutputBuffer (saveBufferInfo, 100000000);//waiting time is not suitable for too short, too short cause problems
} the catch (an IllegalStateException e) {
The d (Tag, String. The valueOf (fromType) + "MediaMuxerdrain:" + um participant etMessage ());
}
If (status==MediaCodec. INFO_TRY_AGAIN_LATER) {
//wait 5 counts (=TIMEOUT_USEC x 5=500 msec) until the data/EOS has
If (+ + count & gt; 5)
break;//out of the while
continue;
} else if (status==MediaCodec INFO_OUTPUT_FORMAT_CHANGED) {
The v (Tag, String. The valueOf (fromType) + "INFO_OUTPUT_FORMAT_CHANGED");
If (mMuxerStarted) {//the second time the request is error
The d (Tag, String. The valueOf (fromType) + "format changed twice");
break;
}
The d (Tag, String. The valueOf (fromType) + "MediaMuxerWrapper: getStart");
//if not start, first to join channel and start
if (! MediaMuxerWrapper. GetInstance (). GetStart ()) {
MTrackIndex=MediaMuxerWrapper. GetInstance (). AddTrack (mMediaCodec. GetOutputFormat ());//API & gt;=16
MMuxerStarted=true;
}
continue;
} else if (the status & lt; 0 {
The w (Tag, String. The valueOf (fromType) + "drain" tapping unexpected result from encoder# dequeueOutputBuffer: "+ status);
continue;
}


nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related