0

I am trying to use Android's MediaPlayer class to play an RTSP stream. MediaPlayer calls to a native library called stagefright to make this happen. This library, and the entire media framework, crash on the following error:

15988-23172/? A/APacketSource﹕ frameworks/av/media/libstagefright/rtsp/APacketSource.cpp:143 CHECK_EQ( (unsigned)nalType,7u) failed: 22 vs. 7

So it seems pretty obvious what the error is - the assert fails when nalType is supposed to be 7, but instead evaluates to 22. I don't understand why this is though. For context, the RTSP stream's SDP contains an attribute sprop-parameter-sets, which is a base64-encoded set of bytes. nalType seems to refer to the first byte of the result of base64-decoding sprop-parameter-sets. In this instance, this is the base64-encoded version:

NjdkMDAxNmRhMDI4MGY2YzA1NTIwMDAwMDAzMDA0MDAwMDAwNzhjMDgwMDNlODAwMDBhOGMzN2JkZjBiYzIy

Decoded, it should look like this:

67d0016da0280f6c0552000000300400000078c08003e80000a8c37bdf0bc22

Below is the relevant excerpt from APacketSource.cpp, from the Android 4.4 source code:

// Appears to assign value of "sprop-parameter-sets" from SDP to 'val'
if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
    return NULL;
}

size_t start = 0;
for (;;) {
    ssize_t commaPos = val.find(",", start);
    size_t end = (commaPos < 0) ? val.size() : commaPos;

    AString nalString(val, start, end - start);
    sp<ABuffer> nal = decodeBase64(nalString);

    CHECK(nal != NULL);
    CHECK_GT(nal->size(), 0u);
    CHECK_LE(nal->size(), 65535u);


    // Mask away everything but 0001 1111 from the first byte 
    uint8_t nalType = nal->data()[0] & 0x1f;
    if (numSeqParameterSets == 0) {

        // Line 143, where the failure happens. 
        CHECK_EQ((unsigned)nalType, 7u); 
    }

    ...
}

The first byte, 0x67, after being masked, should evaluate to 0x07. Somehow, it valuates to 0x16. I have no idea why this may be, though I suspect maybe something unusual is being returned by nal->data().

I can provide the stacktrace that gets printed to the log, but it's quite large and I'm not sure it's relevant. Why is this assert failing?

sigmabeta
  • 1,174
  • 1
  • 12
  • 28
  • 1
    I won't have time to check for you any time soon, but you would perhaps be better served to provide the link to the media if that's possible. Just looking at what you've provided, I think you meant "evalutates to 22" if the logcat error is copied correctly. Also notice the last byte of the decoded base64 value is 0x22. Perhaps the byte order has somehow become reversed. – Dave Apr 05 '14 at 06:32
  • Good catch, fixed the typo – sigmabeta Apr 05 '14 at 14:40
  • @sigmabeta.. Excellent and well written question. In your log have you tried to print the `nal->data()[0]` to say `nal->data()[7]` and check if the first 8 bytes are actually coming correctly? – Ganesh Apr 06 '14 at 01:42
  • 1
    `nal` is an `ABuffer` which basically is an android abstraction of an underlying buffer. `nal->data()` returns the pointer to the underlying buffer and is widely across the framework. – Ganesh Apr 06 '14 at 01:51
  • Thanks for your comments. I'm not sure I have any way of accessing `nal->data()` directly from my code, as this C++ excerpt is straight from AOSP, and it is out of the scope of what I can do to recompile/deploy customized Android builds. If I am mistaken and there is another way to get at that information, please let me know. – sigmabeta Apr 06 '14 at 21:12

0 Answers0