Skip to content
RC3 edited this page Jul 16, 2013 · 12 revisions

.

Hardware Video Encoder Setting - View maguro source(no edit)

    <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.

(opt) Add Debug Log

 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

Patch 1/2 - Skip Sink's M3 Response "xxx" port number

 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;
    }

Patch 2/2 - Skip Sink's M3 Response "xxx" audio codec

     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");
+    }

Sink

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";

adb logcat on Miracast Source


// 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;

What's ducati-m3.bin?

I don't know, but OMAP devices required ducati-m3.bin into /system/vendor/firmware/.

No ducati-m3.bin

dmesg log on boot
<3>[    4.832672] omap-rproc omap-rproc.1: rproc_loader_cont: failed to load ducati-m3.bin
adb logcat on boot
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

After ducati-m3.bin put into /system/vendor/firmware/.

dmesg log on boot
<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
adb logcat on invoked Miracast Source without patch
      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
adb logcat on invoked Miracast Source with applied patch
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

framework

     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() {
+            // ...

app

    DisplayManager mDisplayManager = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
    mDisplayManager.connectWifiDisplay("source-ip:port"); // @hide method

(opt) Frame rate Change

(diff code is here!)