]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/matroskadec.c
Cosmetics
[ffmpeg] / libavformat / matroskadec.c
index f99de66e5adcbe9580ac3f5135b06f0b92fb7f2d..9847d38df4b600de3ba8f7481fcc9a48bba25c55 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 /**
- * @file matroska.c
+ * @file matroskadec.c
  * Matroska file demuxer
  * by Ronald Bultje <rbultje@ronald.bitfreak.net>
  * with a little help from Moritz Bunkus <moritz@bunkus.org>
@@ -39,15 +39,15 @@ typedef struct Track {
 
     /* Unique track number and track ID. stream_index is the index that
      * the calling app uses for this track. */
-    uint32_t num,
-        uid,
-        stream_index;
+    uint32_t num;
+    uint32_t uid;
+    int stream_index;
 
-    char *name,
-        *language;
+    char *name;
+    char language[4];
 
-    char *codec_id,
-        *codec_name;
+    char *codec_id;
+    char *codec_name;
 
     unsigned char *codec_priv;
     int codec_priv_size;
@@ -59,10 +59,10 @@ typedef struct Track {
 typedef struct MatroskaVideoTrack {
     MatroskaTrack track;
 
-    int pixel_width,
-        pixel_height,
-        display_width,
-        display_height;
+    int pixel_width;
+    int pixel_height;
+    int display_width;
+    int display_height;
 
     uint32_t fourcc;
 
@@ -75,10 +75,10 @@ typedef struct MatroskaVideoTrack {
 typedef struct MatroskaAudioTrack {
     MatroskaTrack track;
 
-    int channels,
-        bitdepth,
-        internal_samplerate,
-        samplerate;
+    int channels;
+    int bitdepth;
+    int internal_samplerate;
+    int samplerate;
     int block_align;
 
     /* real audio header */
@@ -95,6 +95,7 @@ typedef struct MatroskaAudioTrack {
 typedef struct MatroskaSubtitleTrack {
     MatroskaTrack track;
 
+    int ass;
     //..
 } MatroskaSubtitleTrack;
 
@@ -103,7 +104,8 @@ typedef struct MatroskaSubtitleTrack {
                                     sizeof(MatroskaSubtitleTrack)))
 
 typedef struct MatroskaLevel {
-    uint64_t start, length;
+    uint64_t start;
+    uint64_t length;
 } MatroskaLevel;
 
 typedef struct MatroskaDemuxIndex {
@@ -121,8 +123,8 @@ typedef struct MatroskaDemuxContext {
     int level_up;
 
     /* matroska stuff */
-    char *writing_app,
-        *muxing_app;
+    char *writing_app;
+    char *muxing_app;
     int64_t created;
 
     /* timescale in the file */
@@ -130,7 +132,8 @@ typedef struct MatroskaDemuxContext {
 
     /* num_streams is the number of streams that av_new_stream() was called
      * for ( = that are available to the calling program). */
-    int num_tracks, num_streams;
+    int num_tracks;
+    int num_streams;
     MatroskaTrack *tracks[MAX_STREAMS];
 
     /* cache for ID peeking */
@@ -144,9 +147,9 @@ typedef struct MatroskaDemuxContext {
     int num_packets;
 
     /* have we already parse metadata/cues/clusters? */
-    int metadata_parsed,
-        index_parsed,
-        done;
+    int metadata_parsed;
+    int index_parsed;
+    int done;
 
     /* The index for seeking. */
     int num_indexes;
@@ -220,7 +223,7 @@ ebml_read_num (MatroskaDemuxContext *matroska,
                    "Read error at pos. %"PRIu64" (0x%"PRIx64")\n",
                    pos, pos);
         }
-        return AVERROR_IO; /* EOS or actual I/O error */
+        return AVERROR(EIO); /* EOS or actual I/O error */
     }
 
     /* get the length of the EBML number */
@@ -307,8 +310,6 @@ ebml_peek_id (MatroskaDemuxContext *matroska,
 {
     uint32_t id;
 
-    assert(level_up != NULL);
-
     if (ebml_read_element_id(matroska, &id, level_up) < 0)
         return 0;
 
@@ -484,13 +485,13 @@ ebml_read_ascii (MatroskaDemuxContext *matroska,
      * byte more, read the string and NULL-terminate it ourselves. */
     if (size < 0 || !(*str = av_malloc(size + 1))) {
         av_log(matroska->ctx, AV_LOG_ERROR, "Memory allocation failed\n");
-        return AVERROR_NOMEM;
+        return AVERROR(ENOMEM);
     }
     if (get_buffer(pb, (uint8_t *) *str, size) != size) {
         offset_t pos = url_ftell(pb);
         av_log(matroska->ctx, AV_LOG_ERROR,
                "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", pos, pos);
-        return AVERROR_IO;
+        return AVERROR(EIO);
     }
     (*str)[size] = '\0';
 
@@ -546,7 +547,7 @@ ebml_read_master (MatroskaDemuxContext *matroska,
     if (matroska->num_levels >= EBML_MAX_DEPTH) {
         av_log(matroska->ctx, AV_LOG_ERROR,
                "File moves beyond max. allowed depth (%d)\n", EBML_MAX_DEPTH);
-        return AVERROR_NOTSUPP;
+        return AVERROR(ENOSYS);
     }
 
     /* remember level */
@@ -580,14 +581,14 @@ ebml_read_binary (MatroskaDemuxContext *matroska,
     if (!(*binary = av_malloc(*size))) {
         av_log(matroska->ctx, AV_LOG_ERROR,
                "Memory allocation error\n");
-        return AVERROR_NOMEM;
+        return AVERROR(ENOMEM);
     }
 
     if (get_buffer(pb, *binary, *size) != *size) {
         offset_t pos = url_ftell(pb);
         av_log(matroska->ctx, AV_LOG_ERROR,
                "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", pos, pos);
-        return AVERROR_IO;
+        return AVERROR(EIO);
     }
 
     return 0;
@@ -692,7 +693,7 @@ ebml_read_header (MatroskaDemuxContext *matroska,
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &level_up)))
-            return AVERROR_IO;
+            return AVERROR(EIO);
 
         /* end-of-header */
         if (level_up)
@@ -858,8 +859,7 @@ matroska_probe (AVProbeData *p)
     uint8_t probe_data[] = { 'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
 
     /* ebml header? */
-    if ((p->buf[0] << 24 | p->buf[1] << 16 |
-         p->buf[2] << 8 | p->buf[3]) != EBML_ID_HEADER)
+    if (AV_RB32(p->buf) != EBML_ID_HEADER)
         return 0;
 
     /* length of header */
@@ -903,7 +903,7 @@ matroska_parse_info (MatroskaDemuxContext *matroska)
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -993,6 +993,7 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
     /* Allocate a generic track. As soon as we know its type we'll realloc. */
     track = av_mallocz(MAX_TRACK_SIZE);
     matroska->num_tracks++;
+    strcpy(track->language, "eng");
 
     /* start with the master */
     if ((res = ebml_read_master(matroska, &id)) < 0)
@@ -1001,7 +1002,7 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
     /* try reading the trackentry headers */
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up > 0) {
             matroska->level_up--;
@@ -1074,7 +1075,7 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
 
                 while (res == 0) {
                     if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-                        res = AVERROR_IO;
+                        res = AVERROR(EIO);
                         break;
                     } else if (matroska->level_up > 0) {
                         matroska->level_up--;
@@ -1088,7 +1089,7 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
                             if ((res = ebml_read_uint (matroska, &id,
                                                        &num)) < 0)
                                 break;
-                            track->default_duration = num/matroska->time_scale;
+                            track->default_duration = num;
                             break;
                         }
 
@@ -1098,7 +1099,8 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
                             if ((res = ebml_read_float(matroska, &id,
                                                        &num)) < 0)
                                 break;
-                            track->default_duration = 1000000000/(matroska->time_scale*num);
+                            if (!track->default_duration)
+                                track->default_duration = 1000000000/num;
                             break;
                         }
 
@@ -1245,7 +1247,7 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
 
                 while (res == 0) {
                     if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-                        res = AVERROR_IO;
+                        res = AVERROR(EIO);
                         break;
                     } else if (matroska->level_up > 0) {
                         matroska->level_up--;
@@ -1352,10 +1354,14 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
 
                 /* language (matters for audio/subtitles, mostly) */
             case MATROSKA_ID_TRACKLANGUAGE: {
-                char *text;
+                char *text, *end;
                 if ((res = ebml_read_utf8(matroska, &id, &text)) < 0)
                     break;
-                track->language = text;
+                if ((end = strchr(text, '-')))
+                    *end = '\0';
+                if (strlen(text) == 3)
+                    strcpy(track->language, text);
+                av_free(text);
                 break;
             }
 
@@ -1401,7 +1407,7 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
                 uint64_t num;
                 if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
                     break;
-                track->default_duration = num / matroska->time_scale;
+                track->default_duration = num;
                 break;
             }
 
@@ -1439,7 +1445,7 @@ matroska_parse_tracks (MatroskaDemuxContext *matroska)
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -1482,7 +1488,7 @@ matroska_parse_index (MatroskaDemuxContext *matroska)
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -1503,7 +1509,7 @@ matroska_parse_index (MatroskaDemuxContext *matroska)
 
                 while (res == 0) {
                     if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-                        res = AVERROR_IO;
+                        res = AVERROR(EIO);
                         break;
                     } else if (matroska->level_up) {
                         matroska->level_up--;
@@ -1530,7 +1536,7 @@ matroska_parse_index (MatroskaDemuxContext *matroska)
                             while (res == 0) {
                                 if (!(id = ebml_peek_id (matroska,
                                                     &matroska->level_up))) {
-                                    res = AVERROR_IO;
+                                    res = AVERROR(EIO);
                                     break;
                                 } else if (matroska->level_up) {
                                     matroska->level_up--;
@@ -1637,7 +1643,7 @@ matroska_parse_metadata (MatroskaDemuxContext *matroska)
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -1675,7 +1681,7 @@ matroska_parse_seekhead (MatroskaDemuxContext *matroska)
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -1692,7 +1698,7 @@ matroska_parse_seekhead (MatroskaDemuxContext *matroska)
 
                 while (res == 0) {
                     if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-                        res = AVERROR_IO;
+                        res = AVERROR(EIO);
                         break;
                     } else if (matroska->level_up) {
                         matroska->level_up--;
@@ -1908,7 +1914,7 @@ matroska_read_header (AVFormatContext    *s,
     /* The next thing is a segment. */
     while (1) {
         if (!(id = ebml_peek_id(matroska, &last_level)))
-            return AVERROR_IO;
+            return AVERROR(EIO);
         if (id == MATROSKA_ID_SEGMENT)
             break;
 
@@ -1931,7 +1937,7 @@ matroska_read_header (AVFormatContext    *s,
     /* we've found our segment, start reading the different contents in here */
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -2020,11 +2026,10 @@ matroska_read_header (AVFormatContext    *s,
             int extradata_size = 0;
             int extradata_offset = 0;
             track = matroska->tracks[i];
+            track->stream_index = -1;
 
-            /* libavformat does not really support subtitles.
-             * Also apply some sanity checks. */
-            if ((track->type == MATROSKA_TRACK_TYPE_SUBTITLE) ||
-                (track->codec_id == NULL))
+            /* Apply some sanity checks. */
+            if (track->codec_id == NULL)
                 continue;
 
             for(j=0; ff_mkv_codec_tags[j].str; j++){
@@ -2042,13 +2047,11 @@ matroska_read_header (AVFormatContext    *s,
                         MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC) &&
                 (track->codec_priv_size >= 40) &&
                 (track->codec_priv != NULL)) {
-                unsigned char *p;
+                MatroskaVideoTrack *vtrack = (MatroskaVideoTrack *) track;
 
                 /* Offset of biCompression. Stored in LE. */
-                p = (unsigned char *)track->codec_priv + 16;
-                ((MatroskaVideoTrack *)track)->fourcc = (p[3] << 24) |
-                                 (p[2] << 16) | (p[1] << 8) | p[0];
-                codec_id = codec_get_id(codec_bmp_tags, ((MatroskaVideoTrack *)track)->fourcc);
+                vtrack->fourcc = AV_RL32(track->codec_priv + 16);
+                codec_id = codec_get_id(codec_bmp_tags, vtrack->fourcc);
 
             }
 
@@ -2058,12 +2061,10 @@ matroska_read_header (AVFormatContext    *s,
                              MATROSKA_CODEC_ID_AUDIO_ACM) &&
                 (track->codec_priv_size >= 18) &&
                 (track->codec_priv != NULL)) {
-                unsigned char *p;
                 uint16_t tag;
 
                 /* Offset of wFormatTag. Stored in LE. */
-                p = (unsigned char *)track->codec_priv;
-                tag = (p[1] << 8) | p[0];
+                tag = AV_RL16(track->codec_priv);
                 codec_id = codec_get_id(codec_wav_tags, tag);
 
             }
@@ -2074,7 +2075,7 @@ matroska_read_header (AVFormatContext    *s,
                 int sri = matroska_aac_sri(audiotrack->internal_samplerate);
                 extradata = av_malloc(5);
                 if (extradata == NULL)
-                    return AVERROR_NOMEM;
+                    return AVERROR(ENOMEM);
                 extradata[0] = (profile << 3) | ((sri&0x0E) >> 1);
                 extradata[1] = ((sri&0x01) << 7) | (audiotrack->channels<<3);
                 if (strstr(track->codec_id, "SBR")) {
@@ -2086,7 +2087,6 @@ matroska_read_header (AVFormatContext    *s,
                 } else {
                     extradata_size = 2;
                 }
-                track->default_duration = 1024*1000 / audiotrack->internal_samplerate;
             }
 
             else if (codec_id == CODEC_ID_TTA) {
@@ -2095,7 +2095,7 @@ matroska_read_header (AVFormatContext    *s,
                 extradata_size = 30;
                 extradata = av_mallocz(extradata_size);
                 if (extradata == NULL)
-                    return AVERROR_NOMEM;
+                    return AVERROR(ENOMEM);
                 init_put_byte(&b, extradata, extradata_size, 1,
                               NULL, NULL, NULL, NULL);
                 put_buffer(&b, (uint8_t *) "TTA1", 4);
@@ -2144,6 +2144,15 @@ matroska_read_header (AVFormatContext    *s,
                 }
             }
 
+            else if (codec_id == CODEC_ID_TEXT) {
+                MatroskaSubtitleTrack *subtrack=(MatroskaSubtitleTrack *)track;
+                if (!strcmp(track->codec_id, "S_TEXT/ASS") ||
+                    !strcmp(track->codec_id, "S_TEXT/SSA") ||
+                    !strcmp(track->codec_id, "S_ASS") ||
+                    !strcmp(track->codec_id, "S_SSA"))
+                    subtrack->ass = 1;
+            }
+
             if (codec_id == CODEC_ID_NONE) {
                 av_log(matroska->ctx, AV_LOG_INFO,
                        "Unknown/unsupported CodecID %s.\n",
@@ -2155,15 +2164,17 @@ matroska_read_header (AVFormatContext    *s,
             matroska->num_streams++;
             st = av_new_stream(s, track->stream_index);
             if (st == NULL)
-                return AVERROR_NOMEM;
+                return AVERROR(ENOMEM);
             av_set_pts_info(st, 64, matroska->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
 
             st->codec->codec_id = codec_id;
             st->start_time = 0;
+            if (strcmp(track->language, "und"))
+                strcpy(st->language, track->language);
 
             if (track->default_duration)
                 av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
-                          track->default_duration, 1000, 30000);
+                          track->default_duration, 1000000000, 30000);
 
             if(extradata){
                 st->codec->extradata = extradata;
@@ -2171,7 +2182,7 @@ matroska_read_header (AVFormatContext    *s,
             } else if(track->codec_priv && track->codec_priv_size > 0){
                 st->codec->extradata = av_malloc(track->codec_priv_size);
                 if(st->codec->extradata == NULL)
-                    return AVERROR_NOMEM;
+                    return AVERROR(ENOMEM);
                 st->codec->extradata_size = track->codec_priv_size;
                 memcpy(st->codec->extradata,track->codec_priv+extradata_offset,
                        track->codec_priv_size);
@@ -2216,9 +2227,10 @@ matroska_read_header (AVFormatContext    *s,
             MatroskaDemuxIndex *idx = &matroska->index[i];
             track = matroska_find_track_by_num(matroska, idx->track);
             stream = matroska->tracks[track]->stream_index;
-            av_add_index_entry(matroska->ctx->streams[stream],
-                               idx->pos, idx->time/matroska->time_scale,
-                               0, 0, AVINDEX_KEYFRAME);
+            if (stream >= 0)
+                av_add_index_entry(matroska->ctx->streams[stream],
+                                   idx->pos, idx->time/matroska->time_scale,
+                                   0, 0, AVINDEX_KEYFRAME);
         }
     }
 
@@ -2263,23 +2275,23 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
         av_free(origdata);
         return res;
     }
+    if (matroska->tracks[track]->stream_index < 0)
+        return res;
     st = matroska->ctx->streams[matroska->tracks[track]->stream_index];
     if (st->discard >= AVDISCARD_ALL) {
         av_free(origdata);
         return res;
     }
     if (duration == AV_NOPTS_VALUE)
-        duration = matroska->tracks[track]->default_duration;
+        duration = matroska->tracks[track]->default_duration / matroska->time_scale;
 
     /* block_time (relative to cluster time) */
-    block_time = (data[0] << 8) | data[1];
+    block_time = AV_RB16(data);
     data += 2;
-    size -= 2;
-    flags = *data;
-    data += 1;
-    size -= 1;
+    flags = *data++;
+    size -= 3;
     if (is_keyframe == -1)
-        is_keyframe = flags & 1 ? PKT_FLAG_KEY : 0;
+        is_keyframe = flags & 0x80 ? PKT_FLAG_KEY : 0;
 
     if (matroska->skip_to_keyframe) {
         if (!is_keyframe || st != matroska->skip_to_stream)
@@ -2370,7 +2382,8 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
         int real_v = matroska->tracks[track]->flags & MATROSKA_TRACK_REAL_V;
         uint64_t timecode = AV_NOPTS_VALUE;
 
-        if (cluster_time != (uint64_t)-1 && cluster_time + block_time >= 0)
+        if (cluster_time != (uint64_t)-1
+            && (block_time >= 0 || cluster_time >= -block_time))
             timecode = cluster_time + block_time;
 
         for (n = 0; n < laces; n++) {
@@ -2426,24 +2439,34 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
                         matroska_queue_packet(matroska, pkt);
                     }
                 } else {
-                pkt = av_mallocz(sizeof(AVPacket));
-                /* XXX: prevent data copy... */
-                if (av_new_packet(pkt, slice_size) < 0) {
-                    res = AVERROR_NOMEM;
-                    n = laces-1;
-                    break;
-                }
-                memcpy (pkt->data, data+slice_offset, slice_size);
+                    int offset = 0;
+
+                    if (st->codec->codec_id == CODEC_ID_TEXT
+                        && ((MatroskaSubtitleTrack *)(matroska->tracks[track]))->ass) {
+                        int i;
+                        for (i=0; i<8 && data[slice_offset+offset]; offset++)
+                            if (data[slice_offset+offset] == ',')
+                                i++;
+                    }
+
+                    pkt = av_mallocz(sizeof(AVPacket));
+                    /* XXX: prevent data copy... */
+                    if (av_new_packet(pkt, slice_size-offset) < 0) {
+                        res = AVERROR(ENOMEM);
+                        n = laces-1;
+                        break;
+                    }
+                    memcpy (pkt->data, data+slice_offset+offset, slice_size-offset);
 
-                if (n == 0)
-                    pkt->flags = is_keyframe;
-                pkt->stream_index = matroska->tracks[track]->stream_index;
+                    if (n == 0)
+                        pkt->flags = is_keyframe;
+                    pkt->stream_index = matroska->tracks[track]->stream_index;
 
-                pkt->pts = timecode;
-                pkt->pos = pos;
-                pkt->duration = duration;
+                    pkt->pts = timecode;
+                    pkt->pos = pos;
+                    pkt->duration = duration;
 
-                matroska_queue_packet(matroska, pkt);
+                    matroska_queue_packet(matroska, pkt);
                 }
 
                 if (timecode != AV_NOPTS_VALUE)
@@ -2475,7 +2498,7 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -2495,7 +2518,6 @@ matroska_parse_blockgroup (MatroskaDemuxContext *matroska,
             case MATROSKA_ID_BLOCKDURATION: {
                 if ((res = ebml_read_uint(matroska, &id, &duration)) < 0)
                     break;
-                duration /= matroska->time_scale;
                 break;
             }
 
@@ -2554,7 +2576,7 @@ matroska_parse_cluster (MatroskaDemuxContext *matroska)
 
     while (res == 0) {
         if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR_IO;
+            res = AVERROR(EIO);
             break;
         } else if (matroska->level_up) {
             matroska->level_up--;
@@ -2619,12 +2641,12 @@ matroska_read_packet (AVFormatContext *s,
 
         /* Have we already reached the end? */
         if (matroska->done)
-            return AVERROR_IO;
+            return AVERROR(EIO);
 
         res = 0;
         while (res == 0) {
             if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-                return AVERROR_IO;
+                return AVERROR(EIO);
             } else if (matroska->level_up) {
                 matroska->level_up--;
                 break;
@@ -2703,7 +2725,6 @@ matroska_read_close (AVFormatContext *s)
         av_free(track->codec_name);
         av_free(track->codec_priv);
         av_free(track->name);
-        av_free(track->language);
 
         if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
             MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track;