Source patch - kensuke/How-to-Miracast-on-AOSP GitHub Wiki
.
Hardware Video Encoder Setting - View maguro source(no edit)
- need "video/avc" H/W encoder
- Reference(Nexus 4): /device/lge/mako/media_codecs.xml
<Encoders>
<MediaCodec name="OMX.qcom.video.encoder.avc" type="video/avc" > <!-- H/W Video Encoder -->
<Quirk name="requires-allocate-on-input-ports" />
<Quirk name="requires-allocate-on-output-ports"/>
<Quirk name="requires-loaded-to-idle-after-allocation"/>
</MediaCodec>
<MediaCodec name="OMX.google.h264.encoder" type="video/avc" /> <!-- S/W Video Encoder -->
<MediaCodec name="OMX.google.aac.encoder" type="audio/mp4a-latm" /> <!-- S/W Audio Encoder -->
</Encoders>
Added "OMX.google.h264.encoder" for S/W Video Encoder, not used. This is a reference addition for future.
Send - View AOSP patch
status_t ANetworkSession::sendRequest(int32_t sessionID, const void *data, ssize_t size) {
// ...
interrupt();
+ ALOGD("sendRequest() session[%d] result[%d] --> --> -->", sessionID, err);
+ ALOGD("[%s]", (char*)data);
+
return err;
}
Receive - View AOSP patch
status_t WifiDisplaySource::onReceiveClientData(const sp<AMessage> &msg) {
// ...
AString method;
AString uri;
data->getRequestField(0, &method);
+ ALOGI("onReceiveClientData() session[%d] method[%s] <== <== <==", sessionID, method.c_str());
+ ALOGI("[%s]", data->debugString().c_str());
+
HDCP Authentication Skip - View AOSP patch
status_t WifiDisplaySource::sendM3(int32_t sessionID) {
AString body =
//"wfd_content_protection\r\n" // deleted this line! for HDCP Authentication Skip
"wfd_video_formats\r\n"
"wfd_audio_codecs\r\n"
"wfd_client_rtp_ports\r\n";
AOSP Sink Response Fix - View AOSP patch
status_t WifiDisplaySource::onReceiveM3Response(
int32_t sessionID, const sp<ParsedMessage> &msg) {
// ...
unsigned port0, port1;
if (sscanf(value.c_str(),
"RTP/AVP/UDP;unicast %u %u mode=play",
&port0,
&port1) != 2
|| port0 == 0 || port0 > 65535 || port1 != 0) {
ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)",
value.c_str());
+ ALOGE("onReceiveM3Response() SKIP!! port check.");
+ port0 = 19000; // FIX ME. default port read from build.prop or other without re-compile
+ port1 = 0;
+ //return ERROR_MALFORMED;
}
if (value == "none") {
ALOGE("Sink doesn't support audio at all.");
return ERROR_UNSUPPORTED;
}
+ if (value == "xxx") {
+ ALOGE("onReceiveM3Response() Force Apply wfd_audio_codecs to AAC");
+ value.clear();
+ value.append("LPCM 00000003 00, AAC 0000000F 00");
+ }
void WifiDisplaySink::onGetParameterRequest(
int32_t sessionID,
int32_t cseq,
const sp<ParsedMessage> &data) {
AString body =
"wfd_video_formats: xxx\r\n"
"wfd_audio_codecs: xxx\r\n"
"wfd_client_rtp_ports: RTP/AVP/UDP;unicast xxx 0 mode=play\r\n";
// Source to Sink
D/NetworkSession( 131): --> --> --> sendRequest() session[2] result[0]
D/NetworkSession( 131): [GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0
D/NetworkSession( 131): Date: Tue, 25 Jun 2013 05:04:44 +0000
D/NetworkSession( 131): Server: Mine/1.0
D/NetworkSession( 131): CSeq: 2
D/NetworkSession( 131): Content-Type: text/parameters
D/NetworkSession( 131): Content-Length: 83
D/NetworkSession( 131):
D/NetworkSession( 131): wfd_content_protection
D/NetworkSession( 131): wfd_video_formats
D/NetworkSession( 131): wfd_audio_codecs
D/NetworkSession( 131): wfd_client_rtp_ports
D/NetworkSession( 131): ]
// Sink to Source
I/WifiDisplaySource( 131): <== <== <== onReceiveClientData() session[2] method[RTSP/1.0]
I/WifiDisplaySource( 131): [RTSP/1.0 200 OK
I/WifiDisplaySource( 131): content-length: 106
I/WifiDisplaySource( 131): content-type: text/parameters
I/WifiDisplaySource( 131): cseq: 2
I/WifiDisplaySource( 131): date: Tue, 25 Jun 2013 05:04:38 +0000
I/WifiDisplaySource( 131): user-agent: stagefright/1.1 (Linux;Android 4.1)
I/WifiDisplaySource( 131):
I/WifiDisplaySource( 131): wfd_video_formats: xxx
I/WifiDisplaySource( 131): wfd_audio_codecs: xxx
I/WifiDisplaySource( 131): wfd_client_rtp_ports: RTP/AVP/UDP;unicast xxx 0 mode=play
I/WifiDisplaySource( 131): ]
// Port Check Error
E/WifiDisplaySource( 131): Sink chose its wfd_client_rtp_ports poorly (RTP/AVP/UDP;unicast xxx 0 mode=play)
// Audio Codec Check Error
I/WifiDisplaySource( 131): Sink doesn't support an audio format we do.
// Error Close..
W/WifiDisplaySource( 131): Response handler for session 2, cseq 2 returned err -1010 (Unknown error 1010)
I/WifiDisplayController( 391): Lost RTSP connection with Wifi display due to error 1: Nexus4
I/WifiDisplayController( 391): Wifi display connection failed!
I/WifiDisplayController( 391): Retrying Wifi display connection. Retries left: 2
I/WifiDisplaySource( 131): We're stopped.
// SKIP!! Port Check Error
E/WifiDisplaySource( 131): onReceiveM3Response() SKIP!! port check.
// SKIP!! Audio Codec Check Error
E/WifiDisplaySource( 131): onReceiveM3Response() Force Apply wfd_audio_codecs to AAC
// Continue
I/WifiDisplaySource( 131): Using AAC audio.
I/WifiDisplaySource( 131): Sink doesn't appear to support content protection.
// Source to Sink
D/NetworkSession( 131): --> --> --> sendRequest() session[2] result[0]
D/NetworkSession( 131): [SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0
D/NetworkSession( 131): Date: Tue, 25 Jun 2013 05:04:44 +0000
D/NetworkSession( 131): Server: Mine/1.0
D/NetworkSession( 131): CSeq: 3
D/NetworkSession( 131): Content-Type: text/parameters
D/NetworkSession( 131): Content-Length: 249
D/NetworkSession( 131):
D/NetworkSession( 131): wfd_video_formats: 28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none
D/NetworkSession( 131): wfd_audio_codecs: AAC 00000001 00
D/NetworkSession( 131): wfd_presentation_URL: rtsp://192.168.49.208/wfd1.0/streamid=0 none
D/NetworkSession( 131): wfd_client_rtp_ports: RTP/AVP/UDP;unicast 19000 0 mode=play
D/NetworkSession( 131): ]
H/W Encoder Fix - View AOSP patch
- This patch is work for Nexus 7 and Galaxy Nexus.
- Nexus 4 don't need this patch.
- xxx : Galaxy S2, Wandboard wfd-Source.
- /frameworks/av/media/libstagefright/ACodec.cpp
- (Galaxy Nexus, other OMAP devices) patch ACodec.cpp and put "ducati-m3.bin" into /system/vendor/firmware/
if (err != OK) {
ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
err, intraRefreshMode);
- return err;
+ ALOGE("setupAVCEncoderParameters() SKIP!! intra-refresh-mode");
+ //return err;
I don't know, but OMAP devices required ducati-m3.bin into /system/vendor/firmware/.
<3>[ 4.832672] omap-rproc omap-rproc.1: rproc_loader_cont: failed to load ducati-m3.bin
D/DOMX ( 131): ERROR: Can-t open device, errorno from open = 2
D/DOMX ( 131): ERROR: DOMX Write failed 0xffffffff -1
D/DOMX ( 131): ERROR: failed check:status >= 0 - returning error: 0x81001 - Write failed
D/DOMX ( 131): ERROR: RPC function returned error 0x81001
D/DOMX ( 131): ERROR: Close failed on omx fd
E/ACodec ( 131): Unable to instantiate a decoder for type 'video/avc'.
E/MediaCodec( 131): Codec reported an error. (omx error 0x80001003, internalError -2147483648)
E/PlaybackSession( 131): video converter returned err -1010
<6>[ 4.574157] omap-rproc omap-rproc.1: Loaded BIOS image ducati-m3.bin, size 4515844
<6>[ 4.574523] omap-rproc omap-rproc.1: BIOS image version is 2
<6>[ 4.597045] omap-iommu omap-iommu.0: iommu_get: ducati qos_request
<4>[ 4.611053] omap_hwmod: ipu: failed to hardreset
<6>[ 4.611206] omap-iommu omap-iommu.0: ducati: version 2.1
<6>[ 4.617126] omap-rproc omap-rproc.1: remote processor ipu is now up
I/Converter( 131): using audio bitrate of 128000 bps, video bitrate of 5000000 bps
D/DOMX ( 131): ERROR: failed check:(eError == OMX_ErrorNone) || (eError == OMX_ErrorNoMore) - returning error: 0x8000101a - Error returned from OMX API in ducati
D/DOMX ( 131): ERROR: failed check:(eError == OMX_ErrorNone) || (eError == OMX_ErrorNoMore) - returning error: 0x8000101a - Error returned from OMX API in ducati
D/DOMX ( 131): ERROR: failed check:eError == OMX_ErrorNone - returning error: 0x8000101a - Error in Proxy SetParameter
E/ACodec ( 131): Encoder could not be configured to emit SPS/PPS before IDR frames. (err -2147483648)
E/ACodec ( 131): [OMX.TI.DUCATI1.VIDEO.H264E] configureCodec returning error -2147483648
E/MediaCodec( 131): Codec reported an error. (omx error 0x80001001, internalError -2147483648)
I/Converter( 131): We going to manually prepend SPS and PPS to IDR frames.
D/DOMX ( 131): ERROR: failed check:(eError == OMX_ErrorNone) || (eError == OMX_ErrorNoMore) - returning error: 0x80001019 - Error returned from OMX API in ducati
D/DOMX ( 131): ERROR: failed check:eError == OMX_ErrorNone - returning error: 0x80001019 - Error in Proxy SetParameter
E/ACodec ( 131): Setting intra macroblock refresh mode (-1010) failed: 0x0
I/ACodec ( 131): setupVideoEncoder succeeded
E/ACodec ( 131): [OMX.TI.DUCATI1.VIDEO.H264E] configureCodec returning error -1010
E/MediaCodec( 131): Codec reported an error. (omx error 0x80001001, internalError -1010)
E/PlaybackSession( 131): video converter returned err -2147483648
I/WifiDisplaySource(131): <== <== <== onReceiveClientData() session[2] method[SETUP]
I/WifiDisplaySource(131): [SETUP rtsp://192.168.49.1/wfd1.0/streamid=0 RTSP/1.0
I/WifiDisplaySource(131): cseq: 321
I/WifiDisplaySource(131): transport: RTP/AVP/UDP;unicast;client_port=24030
I/WifiDisplaySource(131): ]
I/Converter(131): using audio bitrate of 128000 bps, video bitrate of 5000000 bps
D/DOMX(131): ERROR: failed check:(eError == OMX_ErrorNone) || (eError == OMX_ErrorNoMore) - returning error: 0x80001019 - Error returned from OMX API in ducati
D/DOMX(131): ERROR: failed check:eError == OMX_ErrorNone - returning error: 0x80001019 - Error in Proxy SetParameter
E/ACodec(131): Setting intra macroblock refresh mode (-1010) failed: 0x0
E/ACodec(131): setupAVCEncoderParameters() SKIP!! setCyclicIntraMacroblockRefresh()[-1010]
W/ACodec(131): Use baseline profile instead of 8 for AVC recording
I/ACodec(131): setupVideoEncoder succeeded
I/r_submix(131): adev_open_input_stream()
I/r_submix(131): in_standby()
I/r_submix(131): in_standby()
I/Converter(131): using audio bitrate of 128000 bps, video bitrate of 5000000 bps
E/OMXNodeInstance(131): OMX_GetExtensionIndex failed
I/Sender(131): rtpSessionID = 3, rtcpSessionID = 0
D/NetworkSession(131): --> --> --> sendRequest() session[2] result[0]
D/NetworkSession(131): [RTSP/1.0 200 OK
D/NetworkSession(131): Date: Mon, 24 Jun 2013 04:17:22 +0000
D/NetworkSession(131): Server: Mine/1.0
D/NetworkSession(131): CSeq: 321
D/NetworkSession(131): Session: 1812838326;timeout=30
D/NetworkSession(131): Transport: RTP/AVP/UDP;unicast;client_port=24030;server_port=15550
D/NetworkSession(131):
D/NetworkSession(131): ]
My patch skips a few errors occurred in a Miracast Source sequence!
(opt) Connect by Wi-Fi - View AOSP patch
public void requestConnect(String address) {
for (WifiP2pDevice device : mAvailableWifiDisplayPeers) {
if (device.deviceAddress.equals(address)) {
connect(device);
+ Slog.d(TAG, "requestConnect()[p2p] " + device);
+ return;
}
}
+
+ listenWiFiDisplay(address);
+ }
+ private void listenWiFiDisplay(final String ipaddr_port) {
// ...
+ mRemoteDisplay = RemoteDisplay.listen(iface, new RemoteDisplay.Listener() {
+ // ...
DisplayManager mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.connectWifiDisplay("source-ip:port"); // @hide method
(diff code is here!)