Revision b414cb89 libavformat/matroskadec.c

View differences:

libavformat/matroskadec.c
159 159
                                    sizeof(MatroskaSubtitleTrack)))
160 160

  
161 161
typedef struct {
162
    char *filename;
163
    char *mime;
164
    EbmlBin bin;
165
} MatroskaAttachement;
166

  
167
typedef struct {
162 168
    uint64_t start;
163 169
    uint64_t end;
164 170
    uint64_t uid;
......
190 196

  
191 197
    /* timescale in the file */
192 198
    int64_t time_scale;
199
    EbmlList attachments;
193 200
    EbmlList chapters;
194 201
    EbmlList index;
195 202

  
......
238 245
    { 0 }
239 246
};
240 247

  
248
static EbmlSyntax matroska_attachment[] = {
249
    { MATROSKA_ID_FILENAME,           EBML_UTF8, 0, offsetof(MatroskaAttachement,filename) },
250
    { MATROSKA_ID_FILEMIMETYPE,       EBML_STR,  0, offsetof(MatroskaAttachement,mime) },
251
    { MATROSKA_ID_FILEDATA,           EBML_BIN,  0, offsetof(MatroskaAttachement,bin) },
252
    { MATROSKA_ID_FILEUID,            EBML_NONE },
253
    { EBML_ID_VOID,                   EBML_NONE },
254
    { 0 }
255
};
256

  
257
static EbmlSyntax matroska_attachments[] = {
258
    { MATROSKA_ID_ATTACHEDFILE,       EBML_NEST, sizeof(MatroskaAttachement), offsetof(MatroskaDemuxContext,attachments), {.n=matroska_attachment} },
259
    { EBML_ID_VOID,                   EBML_NONE },
260
    { 0 }
261
};
262

  
241 263
static EbmlSyntax matroska_chapter_display[] = {
242 264
    { MATROSKA_ID_CHAPSTRING,         EBML_UTF8, 0, offsetof(MatroskaChapter,title) },
243 265
    { EBML_ID_VOID,                   EBML_NONE },
......
1988 2010
matroska_parse_attachments(AVFormatContext *s)
1989 2011
{
1990 2012
    MatroskaDemuxContext *matroska = s->priv_data;
1991
    int res = 0;
1992
    uint32_t id;
1993

  
1994
    av_log(matroska->ctx, AV_LOG_DEBUG, "parsing attachments...\n");
1995

  
1996
    while (res == 0) {
1997
        if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
1998
            res = AVERROR(EIO);
1999
            break;
2000
        } else if (matroska->level_up) {
2001
            matroska->level_up--;
2002
            break;
2003
        }
2013
    EbmlList *attachements_list = &matroska->attachments;
2014
    MatroskaAttachement *attachements;
2015
    int i, j, res;
2004 2016

  
2005
        switch (id) {
2006
        case MATROSKA_ID_ATTACHEDFILE: {
2007
            char* name = NULL;
2008
            char* mime = NULL;
2009
            uint8_t* data = NULL;
2010
            int i, data_size = 0;
2011
            AVStream *st;
2012

  
2013
            if ((res = ebml_read_master(matroska, &id)) < 0)
2014
                break;
2015

  
2016
            while (res == 0) {
2017
                if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
2018
                    res = AVERROR(EIO);
2019
                    break;
2020
                } else if (matroska->level_up) {
2021
                    matroska->level_up--;
2022
                    break;
2023
                }
2024

  
2025
                switch (id) {
2026
                case MATROSKA_ID_FILENAME:
2027
                    res = ebml_read_utf8 (matroska, &id, &name);
2028
                    break;
2029

  
2030
                case MATROSKA_ID_FILEMIMETYPE:
2031
                    res = ebml_read_ascii (matroska, &id, &mime);
2032
                    break;
2033

  
2034
                case MATROSKA_ID_FILEDATA:
2035
                    res = ebml_read_binary(matroska, &id, &data, &data_size);
2036
                    break;
2017
    res = ebml_parse(matroska, matroska_attachments, matroska, MATROSKA_ID_ATTACHMENTS, 0);
2037 2018

  
2038
                default:
2039
                    av_log(matroska->ctx, AV_LOG_INFO,
2040
                           "Unknown attachedfile ID 0x%x\n", id);
2041
                case MATROSKA_ID_FILEUID:
2042
                case EBML_ID_VOID:
2043
                    res = ebml_read_skip(matroska);
2044
                    break;
2045
                }
2046

  
2047
                if (matroska->level_up) {
2048
                    matroska->level_up--;
2049
                    break;
2050
                }
2051
            }
2052

  
2053
            if (!(name && mime && data && data_size > 0)) {
2054
                av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
2055
                break;
2056
            }
2057

  
2058
            st = av_new_stream(s, matroska->num_streams++);
2019
    attachements = attachements_list->elem;
2020
    for (j=0; j<attachements_list->nb_elem; j++) {
2021
        if (!(attachements[j].filename && attachements[j].mime &&
2022
              attachements[j].bin.data && attachements[j].bin.size > 0)) {
2023
            av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
2024
        } else {
2025
            AVStream *st = av_new_stream(s, matroska->num_streams++);
2059 2026
            if (st == NULL)
2060
                return AVERROR(ENOMEM);
2061
            st->filename = av_strdup(name);
2027
                break;
2028
            st->filename          = av_strdup(attachements[j].filename);
2062 2029
            st->codec->codec_id = CODEC_ID_NONE;
2063 2030
            st->codec->codec_type = CODEC_TYPE_ATTACHMENT;
2064
            st->codec->extradata = av_malloc(data_size);
2031
            st->codec->extradata  = av_malloc(attachements[j].bin.size);
2065 2032
            if(st->codec->extradata == NULL)
2066
                return AVERROR(ENOMEM);
2067
            st->codec->extradata_size = data_size;
2068
            memcpy(st->codec->extradata, data, data_size);
2033
                break;
2034
            st->codec->extradata_size = attachements[j].bin.size;
2035
            memcpy(st->codec->extradata, attachements[j].bin.data, attachements[j].bin.size);
2069 2036

  
2070 2037
            for (i=0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++) {
2071
                if (!strncmp(ff_mkv_mime_tags[i].str, mime,
2038
                if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime,
2072 2039
                             strlen(ff_mkv_mime_tags[i].str))) {
2073 2040
                    st->codec->codec_id = ff_mkv_mime_tags[i].id;
2074 2041
                    break;
2075 2042
                }
2076 2043
            }
2077

  
2078
            av_log(matroska->ctx, AV_LOG_DEBUG, "new attachment: %s, %s, size %d \n", name, mime, data_size);
2079
            break;
2080
        }
2081

  
2082
        default:
2083
            av_log(matroska->ctx, AV_LOG_INFO,
2084
                   "Unknown attachments ID 0x%x\n", id);
2085
            /* fall-through */
2086

  
2087
        case EBML_ID_VOID:
2088
            res = ebml_read_skip(matroska);
2089
            break;
2090
        }
2091

  
2092
        if (matroska->level_up) {
2093
            matroska->level_up--;
2094
            break;
2095 2044
        }
2096 2045
    }
2097 2046

  
......
2246 2195
            }
2247 2196

  
2248 2197
            case MATROSKA_ID_ATTACHMENTS: {
2249
                if ((res = ebml_read_master(matroska, &id)) < 0)
2250
                    break;
2251 2198
                res = matroska_parse_attachments(s);
2252 2199
                break;
2253 2200
            }

Also available in: Unified diff