avformat/au: Write MetaData in AU Sun audio file header
Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
		
							parent
							
								
									12f47539ca
								
							
						
					
					
						commit
						1f8c0e44cb
					
				@ -36,7 +36,7 @@
 | 
				
			|||||||
/* if we don't know the size in advance */
 | 
					/* if we don't know the size in advance */
 | 
				
			||||||
#define AU_UNKNOWN_SIZE ((uint32_t)(~0))
 | 
					#define AU_UNKNOWN_SIZE ((uint32_t)(~0))
 | 
				
			||||||
/* the specification requires an annotation field of at least eight bytes */
 | 
					/* the specification requires an annotation field of at least eight bytes */
 | 
				
			||||||
#define AU_HEADER_SIZE (24+8)
 | 
					#define AU_DEFAULT_HEADER_SIZE (24+8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const AVCodecTag codec_au_tags[] = {
 | 
					static const AVCodecTag codec_au_tags[] = {
 | 
				
			||||||
    { AV_CODEC_ID_PCM_MULAW,  1 },
 | 
					    { AV_CODEC_ID_PCM_MULAW,  1 },
 | 
				
			||||||
@ -163,12 +163,53 @@ AVInputFormat ff_au_demuxer = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if CONFIG_AU_MUXER
 | 
					#if CONFIG_AU_MUXER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct AUContext {
 | 
				
			||||||
 | 
					    uint32_t header_size;
 | 
				
			||||||
 | 
					} AUContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "rawenc.h"
 | 
					#include "rawenc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int au_get_annotations(AVFormatContext *s, char **buffer)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const char * keys[] = {
 | 
				
			||||||
 | 
					        "Title",
 | 
				
			||||||
 | 
					        "Artist",
 | 
				
			||||||
 | 
					        "Album",
 | 
				
			||||||
 | 
					        "Track",
 | 
				
			||||||
 | 
					        "Genre",
 | 
				
			||||||
 | 
					        NULL };
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    int cnt = 0;
 | 
				
			||||||
 | 
					    AVDictionary *m = s->metadata;
 | 
				
			||||||
 | 
					    AVDictionaryEntry *t = NULL;
 | 
				
			||||||
 | 
					    AVBPrint bprint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; keys[i] != NULL; i++) {
 | 
				
			||||||
 | 
					        t = av_dict_get(m, keys[i], NULL, 0);
 | 
				
			||||||
 | 
					        if (t != NULL) {
 | 
				
			||||||
 | 
					            if (cnt++)
 | 
				
			||||||
 | 
					                av_bprint_chars(&bprint, '\n', 1);
 | 
				
			||||||
 | 
					            av_bprint_append_data(&bprint, keys[i], strlen(keys[i]));
 | 
				
			||||||
 | 
					            av_bprint_chars(&bprint, '=', 1);
 | 
				
			||||||
 | 
					            av_bprint_append_data(&bprint, t->value, strlen(t->value));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /* pad with 0's */
 | 
				
			||||||
 | 
					    av_bprint_append_data(&bprint, "\0\0\0\0\0\0\0\0", 8);
 | 
				
			||||||
 | 
					    return av_bprint_finalize(&bprint, buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int au_write_header(AVFormatContext *s)
 | 
					static int au_write_header(AVFormatContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    AUContext *au = s->priv_data;
 | 
				
			||||||
    AVIOContext *pb = s->pb;
 | 
					    AVIOContext *pb = s->pb;
 | 
				
			||||||
    AVCodecParameters *par = s->streams[0]->codecpar;
 | 
					    AVCodecParameters *par = s->streams[0]->codecpar;
 | 
				
			||||||
 | 
					    char *annotations = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    au->header_size = AU_DEFAULT_HEADER_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->nb_streams != 1) {
 | 
					    if (s->nb_streams != 1) {
 | 
				
			||||||
        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
 | 
					        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
 | 
				
			||||||
@ -181,13 +222,28 @@ static int au_write_header(AVFormatContext *s)
 | 
				
			|||||||
        return AVERROR(EINVAL);
 | 
					        return AVERROR(EINVAL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (av_dict_count(s->metadata) > 0) {
 | 
				
			||||||
 | 
					        ret = au_get_annotations(s, &annotations);
 | 
				
			||||||
 | 
					        if (ret < 0)
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        if (annotations != NULL) {
 | 
				
			||||||
 | 
					            au->header_size = (24 + strlen(annotations) + 8) & ~7;
 | 
				
			||||||
 | 
					            if (au->header_size < AU_DEFAULT_HEADER_SIZE)
 | 
				
			||||||
 | 
					                au->header_size = AU_DEFAULT_HEADER_SIZE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    ffio_wfourcc(pb, ".snd");                   /* magic number */
 | 
					    ffio_wfourcc(pb, ".snd");                   /* magic number */
 | 
				
			||||||
    avio_wb32(pb, AU_HEADER_SIZE);              /* header size */
 | 
					    avio_wb32(pb, au->header_size);             /* header size */
 | 
				
			||||||
    avio_wb32(pb, AU_UNKNOWN_SIZE);             /* data size */
 | 
					    avio_wb32(pb, AU_UNKNOWN_SIZE);             /* data size */
 | 
				
			||||||
    avio_wb32(pb, par->codec_tag);              /* codec ID */
 | 
					    avio_wb32(pb, par->codec_tag);              /* codec ID */
 | 
				
			||||||
    avio_wb32(pb, par->sample_rate);
 | 
					    avio_wb32(pb, par->sample_rate);
 | 
				
			||||||
    avio_wb32(pb, par->channels);
 | 
					    avio_wb32(pb, par->channels);
 | 
				
			||||||
 | 
					    if (annotations != NULL) {
 | 
				
			||||||
 | 
					        avio_write(pb, annotations, au->header_size - 24);
 | 
				
			||||||
 | 
					        av_freep(&annotations);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
        avio_wb64(pb, 0); /* annotation field */
 | 
					        avio_wb64(pb, 0); /* annotation field */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    avio_flush(pb);
 | 
					    avio_flush(pb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
@ -196,12 +252,13 @@ static int au_write_header(AVFormatContext *s)
 | 
				
			|||||||
static int au_write_trailer(AVFormatContext *s)
 | 
					static int au_write_trailer(AVFormatContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    AVIOContext *pb = s->pb;
 | 
					    AVIOContext *pb = s->pb;
 | 
				
			||||||
 | 
					    AUContext *au = s->priv_data;
 | 
				
			||||||
    int64_t file_size = avio_tell(pb);
 | 
					    int64_t file_size = avio_tell(pb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->pb->seekable && file_size < INT32_MAX) {
 | 
					    if (s->pb->seekable && file_size < INT32_MAX) {
 | 
				
			||||||
        /* update file size */
 | 
					        /* update file size */
 | 
				
			||||||
        avio_seek(pb, 8, SEEK_SET);
 | 
					        avio_seek(pb, 8, SEEK_SET);
 | 
				
			||||||
        avio_wb32(pb, (uint32_t)(file_size - AU_HEADER_SIZE));
 | 
					        avio_wb32(pb, (uint32_t)(file_size - au->header_size));
 | 
				
			||||||
        avio_seek(pb, file_size, SEEK_SET);
 | 
					        avio_seek(pb, file_size, SEEK_SET);
 | 
				
			||||||
        avio_flush(pb);
 | 
					        avio_flush(pb);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -214,6 +271,7 @@ AVOutputFormat ff_au_muxer = {
 | 
				
			|||||||
    .long_name     = NULL_IF_CONFIG_SMALL("Sun AU"),
 | 
					    .long_name     = NULL_IF_CONFIG_SMALL("Sun AU"),
 | 
				
			||||||
    .mime_type     = "audio/basic",
 | 
					    .mime_type     = "audio/basic",
 | 
				
			||||||
    .extensions    = "au",
 | 
					    .extensions    = "au",
 | 
				
			||||||
 | 
					    .priv_data_size = sizeof(AUContext),
 | 
				
			||||||
    .audio_codec   = AV_CODEC_ID_PCM_S16BE,
 | 
					    .audio_codec   = AV_CODEC_ID_PCM_S16BE,
 | 
				
			||||||
    .video_codec   = AV_CODEC_ID_NONE,
 | 
					    .video_codec   = AV_CODEC_ID_NONE,
 | 
				
			||||||
    .write_header  = au_write_header,
 | 
					    .write_header  = au_write_header,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,3 @@
 | 
				
			|||||||
aa5ec1f82ac07c653ffc527b0f0dc10d *./tests/data/lavf/lavf.au
 | 
					5228ad3783888c45a08dac5ab6118794 *./tests/data/lavf/lavf.au
 | 
				
			||||||
88232 ./tests/data/lavf/lavf.au
 | 
					88240 ./tests/data/lavf/lavf.au
 | 
				
			||||||
./tests/data/lavf/lavf.au CRC=0x3a1da17e
 | 
					./tests/data/lavf/lavf.au CRC=0x3a1da17e
 | 
				
			||||||
 | 
				
			|||||||
@ -1,53 +1,53 @@
 | 
				
			|||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st:-1 flags:0  ts:-1.000000
 | 
					ret: 0         st:-1 flags:0  ts:-1.000000
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st:-1 flags:1  ts: 1.894167
 | 
					ret: 0         st:-1 flags:1  ts: 1.894167
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st: 0 flags:0  ts: 0.788345
 | 
					ret: 0         st: 0 flags:0  ts: 0.788345
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos:  69564 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos:  69572 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:1  ts:-0.317506
 | 
					ret: 0         st: 0 flags:1  ts:-0.317506
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st:-1 flags:0  ts: 2.576668
 | 
					ret: 0         st:-1 flags:0  ts: 2.576668
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:1  ts: 1.470835
 | 
					ret: 0         st:-1 flags:1  ts: 1.470835
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st: 0 flags:0  ts: 0.365011
 | 
					ret: 0         st: 0 flags:0  ts: 0.365011
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos:  32226 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos:  32234 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:1  ts:-0.740839
 | 
					ret: 0         st: 0 flags:1  ts:-0.740839
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st:-1 flags:0  ts: 2.153336
 | 
					ret: 0         st:-1 flags:0  ts: 2.153336
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:1  ts: 1.047503
 | 
					ret: 0         st:-1 flags:1  ts: 1.047503
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st: 0 flags:0  ts:-0.058322
 | 
					ret: 0         st: 0 flags:0  ts:-0.058322
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:1  ts: 2.835828
 | 
					ret: 0         st: 0 flags:1  ts: 2.835828
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:0  ts: 1.730004
 | 
					ret: 0         st:-1 flags:0  ts: 1.730004
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:1  ts: 0.624171
 | 
					ret: 0         st:-1 flags:1  ts: 0.624171
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos:  55084 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos:  55092 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:0  ts:-0.481655
 | 
					ret: 0         st: 0 flags:0  ts:-0.481655
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:1  ts: 2.412494
 | 
					ret: 0         st: 0 flags:1  ts: 2.412494
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:0  ts: 1.306672
 | 
					ret: 0         st:-1 flags:0  ts: 1.306672
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:1  ts: 0.200839
 | 
					ret: 0         st:-1 flags:1  ts: 0.200839
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos:  17746 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos:  17754 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:0  ts:-0.904989
 | 
					ret: 0         st: 0 flags:0  ts:-0.904989
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:1  ts: 1.989184
 | 
					ret: 0         st: 0 flags:1  ts: 1.989184
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:0  ts: 0.883340
 | 
					ret: 0         st:-1 flags:0  ts: 0.883340
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos:  77942 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos:  77950 size:  2048
 | 
				
			||||||
ret: 0         st:-1 flags:1  ts:-0.222493
 | 
					ret: 0         st:-1 flags:1  ts:-0.222493
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
ret: 0         st: 0 flags:0  ts: 2.671678
 | 
					ret: 0         st: 0 flags:0  ts: 2.671678
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st: 0 flags:1  ts: 1.565850
 | 
					ret: 0         st: 0 flags:1  ts: 1.565850
 | 
				
			||||||
ret:-EOF
 | 
					ret:-EOF
 | 
				
			||||||
ret: 0         st:-1 flags:0  ts: 0.460008
 | 
					ret: 0         st:-1 flags:0  ts: 0.460008
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos:  40604 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos:  40612 size:  2048
 | 
				
			||||||
ret: 0         st:-1 flags:1  ts:-0.645825
 | 
					ret: 0         st:-1 flags:1  ts:-0.645825
 | 
				
			||||||
ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  2048
 | 
					ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     40 size:  2048
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user