Search code examples
androidandroid-5.0-lollipopstagefright

MKV video file not playing on Lollipop


I was trying to play MKV video file on the Lollipop release but could not able to play, though it was working properly in Kitkat release.

My findings on debugging into the issue as below,

In the function ParseTrackEntry()

the default track settings for audio, video and content encoding is set to -1

If the id of the current track is not video nor audio but of type content_encoding, the track settings is updated accordingly.

Later in the function, the buffer is parsed based on the type of track, i.e if the track is of type video then audio track setting should be less than 0, similarly if the track consist of audio the video track setting should be less than 0.

But in case the track consist of content encoding type, there is a check for video, audio and content encoding track settings as well.

As the track settings will be updated in case of type content encoding, it fails here

if (e.start >= 0)
    return E_FILE_FORMAT_INVALID;

When the check for content encoding is removed the MKV file plays successfully.

My file has a video track, an audio track and multiple subtitles. What could be the issue? Please help.


Solution

  • I think this issue could be due to a missing check in mkvparser.cpp. In ParseTrackEntry, once a TrackEntry is identified, there are checks for audio presence in video packet and vice-versa.

    Though the Matroska file specification (Ref: Page 21, comment before Table 8) specifies that this is also permissible, the current implementation reports an error.

    When the TrackEntry element is not a video or audio i.e. subtitle or metadata, then the way ContentEncoding is handled has to be very clear. The check in this line is valid for metadata. However, for subtitle track, the specification shows that ContentEncoding element can be present (Ref: Page 24 of standard above).

    Hence, this check should probably become

    if((info.type == Track::kMetadata) && (e.start >= 0))
        return E_FILE_FORMAT_INVALID;
    

    With this change, for subtitle tracks with ContentEncoding, the processing would continue and your file should playback.

    P.S: We may have to check with Google if they agree with this change.