Revision 47146dfb

View differences:

libavcodec/Makefile
14 14
       faanidct.o                                                       \
15 15
       imgconvert.o                                                     \
16 16
       jrevdct.o                                                        \
17
       metadata.o                                                       \
17 18
       opt.o                                                            \
18 19
       parser.o                                                         \
19 20
       raw.o                                                            \
libavcodec/avcodec.h
400 400
 */
401 401
#define FF_MIN_BUFFER_SIZE 16384
402 402

  
403

  
404
/*
405
 * public Metadata API.
406
 * Important concepts, to keep in mind
407
 * 1. keys are unique, there are never 2 tags with equal keys, this is also
408
 *    meant semantically that is a demuxer should not knowingly produce
409
 *    several keys that are litterally different but semantically identical,
410
 *    like key=Author5, key=Author6.
411
 *    All authors have to be placed in the same tag for the case of Authors.
412
 * 2. Metadata is flat, there are no subtags, if you for whatever obscene
413
 *    reason want to store the email address of the child of producer alice
414
 *    and actor bob, that could have key=alice_and_bobs_childs_email_address.
415
 * 3. A tag whichs value is translated has the ISO 639 3-letter language code
416
 *    with a '-' between appended. So for example Author-ger=Michael, Author-eng=Mike
417
 *    the original/default language is in the unqualified "Author"
418
 *    A demuxer should set a default if it sets any translated tag.
419
 */
420

  
421
#define AV_METADATA_IGNORE_CASE     1
422
#define AV_METADATA_IGNORE_SUFFIX   2
423

  
424
typedef struct {
425
    char *key;
426
    char *value;
427
}AVMetaDataTag;
428

  
429
struct AVMetaData;
430

  
431
/**
432
 * gets a metadata element with matching key.
433
 * @param prev set to the previous matching element to find the next.
434
 * @param flags allows case as well as suffix insensitive comparissions.
435
 * @return found tag or NULL, changing key or value leads to undefined behavior.
436
 */
437
AVMetaDataTag *
438
av_metadata_get(struct AVMetaData *m, const char *key, const AVMetaDataTag *prev, int flags);
439

  
440
/**
441
 * sets the given tag in m, overwriting an existing tag.
442
 * @param tag tag to add to m, key and value will be av_strduped.
443
 * @return >= 0 if success otherwise error code that is <0.
444
 */
445
int av_metadata_set(struct AVMetaData **m, AVMetaDataTag tag);
446

  
447

  
403 448
/**
404 449
 * motion estimation type.
405 450
 */
libavcodec/metadata.c
1
/*
2
 * copyright (c) 2009 Michael Niedermayer
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

  
21
#include "metadata.h"
22

  
23
AVMetaDataTag *
24
av_metadata_get(struct AVMetaData *m, const char *key, const AVMetaDataTag *prev, int flags)
25
{
26
    unsigned int i, j;
27

  
28
    if(!m)
29
        return NULL;
30

  
31
    if(prev) i= prev - m->elems + 1;
32
    else     i= 0;
33

  
34
    for(; i<m->count; i++){
35
        const char *s= m->elems[i].key;
36
        if(flags & AV_METADATA_IGNORE_CASE) for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++);
37
        else                                for(j=0;         s[j]  ==         key[j]  && key[j]; j++);
38
        if(key[j])
39
            continue;
40
        if(s[j] && !(flags & AV_METADATA_IGNORE_SUFFIX))
41
            continue;
42
        return &m->elems[i];
43
    }
44
    return NULL;
45
}
46

  
47
int av_metadata_set(struct AVMetaData **pm, AVMetaDataTag elem)
48
{
49
    struct AVMetaData *m= *pm;
50
    AVMetaDataTag *tag= av_metadata_get(m, elem.key, NULL, 0);
51

  
52
    if(!m)
53
        m=*pm= av_mallocz(sizeof(*m));
54

  
55
    if(tag){
56
        av_free(tag->value);
57
        av_free(tag->key);
58
        *tag= m->elems[--m->count];
59
    }else{
60
        AVMetaDataTag *tmp= av_realloc(m->elems, (m->count+1) * sizeof(*m->elems));
61
        if(tmp){
62
            m->elems= tmp;
63
        }else
64
            return AVERROR(ENOMEM);
65
    }
66
    if(elem.value){
67
        elem.key  = av_strdup(elem.key  );
68
        elem.value= av_strdup(elem.value);
69
        m->elems[m->count++]= elem;
70
    }
71
    if(!m->count)
72
        av_freep(pm);
73

  
74
    return 0;
75
}
libavcodec/metadata.h
1
/*
2
 * copyright (c) 2009 Michael Niedermayer
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

  
21
#ifndef AVCODEC_METADATA_H
22
#define AVCODEC_METADATA_H
23

  
24
/**
25
 * @file metadata.h
26
 * internal metadata API header
27
 * see avcodec.h or the public API!
28
 */
29

  
30

  
31
#include "avcodec.h"
32

  
33
struct AVMetaData{
34
    int count;
35
    AVMetaDataTag *elems;
36
};
37

  
38
#endif /* AVCODEC_METADATA_H */
libavformat/avformat.h
608 608
    struct AVPacketList *raw_packet_buffer_end;
609 609

  
610 610
    struct AVPacketList *packet_buffer_end;
611

  
612
    struct AVMetaData *meta_data;
611 613
} AVFormatContext;
612 614

  
613 615
typedef struct AVPacketList {
libavformat/avidec.c
216 216
    }
217 217
}
218 218

  
219
static int avi_read_tag(ByteIOContext *pb, char *buf, int maxlen,  unsigned int size)
219
static int avi_read_tag(AVFormatContext *s, const char *key, unsigned int size)
220 220
{
221
    ByteIOContext *pb = s->pb;
222
    uint8_t value[1024];
223

  
221 224
    int64_t i = url_ftell(pb);
222 225
    size += (size & 1);
223
    get_strz(pb, buf, maxlen);
226
    get_strz(pb, value, sizeof(value));
224 227
    url_fseek(pb, i+size, SEEK_SET);
225
    return 0;
228

  
229
    return av_metadata_set(&s->meta_data, (const AVMetaDataTag){key, value});
226 230
}
227 231

  
228 232
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
......
235 239
    int i;
236 240
    AVStream *st;
237 241
    AVIStream *ast = NULL;
238
    char str_track[4];
239 242
    int avih_width=0, avih_height=0;
240 243
    int amv_file_format=0;
241 244

  
......
561 564
            url_fseek(pb, size, SEEK_CUR);
562 565
            break;
563 566
        case MKTAG('I', 'N', 'A', 'M'):
564
            avi_read_tag(pb, s->title, sizeof(s->title), size);
567
            avi_read_tag(s, "Title", size);
565 568
            break;
566 569
        case MKTAG('I', 'A', 'R', 'T'):
567
            avi_read_tag(pb, s->author, sizeof(s->author), size);
570
            avi_read_tag(s, "Artist", size);
568 571
            break;
569 572
        case MKTAG('I', 'C', 'O', 'P'):
570
            avi_read_tag(pb, s->copyright, sizeof(s->copyright), size);
573
            avi_read_tag(s, "Copyright", size);
571 574
            break;
572 575
        case MKTAG('I', 'C', 'M', 'T'):
573
            avi_read_tag(pb, s->comment, sizeof(s->comment), size);
576
            avi_read_tag(s, "Comment", size);
574 577
            break;
575 578
        case MKTAG('I', 'G', 'N', 'R'):
576
            avi_read_tag(pb, s->genre, sizeof(s->genre), size);
579
            avi_read_tag(s, "Genre", size);
577 580
            break;
578 581
        case MKTAG('I', 'P', 'R', 'D'):
579
            avi_read_tag(pb, s->album, sizeof(s->album), size);
582
            avi_read_tag(s, "Album", size);
580 583
            break;
581 584
        case MKTAG('I', 'P', 'R', 'T'):
582
            avi_read_tag(pb, str_track, sizeof(str_track), size);
583
            sscanf(str_track, "%d", &s->track);
585
            avi_read_tag(s, "Track", size);
584 586
            break;
585 587
        default:
586 588
            if(size > 1000000){
libavformat/avienc.c
103 103
    }
104 104
}
105 105

  
106
static void avi_write_info_tag2(AVFormatContext *s, const char *fourcc, const char *key1, const char *key2)
107
{
108
    AVMetaDataTag *tag= av_metadata_get(s->meta_data, key1, NULL, AV_METADATA_IGNORE_CASE);
109
    if(!tag && key2)
110
        tag= av_metadata_get(s->meta_data, key2, NULL, AV_METADATA_IGNORE_CASE);
111
    if(tag)
112
        avi_write_info_tag(s->pb, fourcc, tag->value);
113
}
114

  
106 115
static int avi_write_counters(AVFormatContext* s, int riff_id)
107 116
{
108 117
    ByteIOContext *pb = s->pb;
......
332 341

  
333 342
    list2 = start_tag(pb, "LIST");
334 343
    put_tag(pb, "INFO");
335
    avi_write_info_tag(pb, "INAM", s->title);
336
    avi_write_info_tag(pb, "IART", s->author);
337
    avi_write_info_tag(pb, "ICOP", s->copyright);
338
    avi_write_info_tag(pb, "ICMT", s->comment);
339
    avi_write_info_tag(pb, "IPRD", s->album);
340
    avi_write_info_tag(pb, "IGNR", s->genre);
341
    if (s->track) {
342
        char str_track[4];
343
        snprintf(str_track, 4, "%d", s->track);
344
        avi_write_info_tag(pb, "IPRT", str_track);
345
    }
344
    avi_write_info_tag2(s, "INAM", "Title", NULL);
345
    avi_write_info_tag2(s, "IART", "Artist", "Author");
346
    avi_write_info_tag2(s, "ICOP", "Copyright", NULL);
347
    avi_write_info_tag2(s, "ICMT", "Comment", NULL);
348
    avi_write_info_tag2(s, "IPRD", "Album", NULL);
349
    avi_write_info_tag2(s, "IGNR", "Genre", NULL);
350
    avi_write_info_tag2(s, "IPRT", "Track", NULL);
346 351
    if(!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
347 352
        avi_write_info_tag(pb, "ISFT", LIBAVFORMAT_IDENT);
348 353
    end_tag(pb, list2);
libavformat/utils.c
21 21
#include "avformat.h"
22 22
#include "internal.h"
23 23
#include "libavcodec/opt.h"
24
#include "libavcodec/metadata.h"
24 25
#include "libavutil/avstring.h"
25 26
#include "riff.h"
26 27
#include <sys/time.h>
......
2305 2306
        av_free(s->chapters[s->nb_chapters]);
2306 2307
    }
2307 2308
    av_freep(&s->chapters);
2309
    if(s->meta_data){
2310
        while(s->meta_data->count--){
2311
            av_freep(&s->meta_data->elems[s->meta_data->count].key);
2312
            av_freep(&s->meta_data->elems[s->meta_data->count].value);
2313
        }
2314
        av_freep(&s->meta_data->elems);
2315
    }
2316
    av_freep(&s->meta_data);
2308 2317
    av_free(s);
2309 2318
}
2310 2319

  

Also available in: Unified diff