diff options
author | François Revol <revol@free.fr> | 2005-12-30 20:34:08 +0000 |
---|---|---|
committer | François Revol <revol@free.fr> | 2005-12-30 20:34:08 +0000 |
commit | ab561df995ccf41ad6fde7e80adba6966cf86954 (patch) | |
tree | 612774cd2659226ef49c68f1cf62d476d5ffa5b0 /libavformat | |
parent | b9a87c4d6c73d3b1462b6f09940b0a9649b123c9 (diff) | |
download | ffmpeg-ab561df995ccf41ad6fde7e80adba6966cf86954.tar.gz |
finally found what those >138 codes were... crappy compressed 5bit ascii. this gets them correctly, and adds setting track lang in movenc too.
Originally committed as revision 4792 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mov.c | 55 | ||||
-rw-r--r-- | libavformat/movenc.c | 8 |
2 files changed, 49 insertions, 14 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index c5ddec3e20..8bf364f642 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -151,6 +151,8 @@ static const CodecTag mov_audio_tags[] = { /* map numeric codes from mdhd atom to ISO 639 */ /* cf. QTFileFormat.pdf p253, qtff.pdf p205 */ +/* http://developer.apple.com/documentation/mac/Text/Text-368.html */ +/* deprecated by putting the code as 3*5bit ascii */ static const char *mov_mdhd_language_map[] = { /* 0-9 */ "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor", @@ -353,24 +355,54 @@ void print_atom(const char *str, MOV_atom_t atom) #define print_atom(a,b) #endif -const char *ff_mov_lang_to_iso639(int code) +static int ff_mov_lang_to_iso639(int code, char *to) { + int i; + /* is it the mangled iso code? */ + /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */ + if (code > 138) { + for (i = 2; i >= 0; i--) { + to[i] = 0x60 + (code & 0x1f); + code >>= 5; + } + return 1; + } + /* old fashion apple lang code */ if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *))) - return NULL; + return 0; if (!mov_mdhd_language_map[code]) - return NULL; - return mov_mdhd_language_map[code]; + return 0; + strncpy(to, mov_mdhd_language_map[code], 4); + return 1; } -extern int ff_mov_iso639_to_lang(const char *lang); /* for movenc.c */ -int ff_mov_iso639_to_lang(const char *lang) +extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */ +int ff_mov_iso639_to_lang(const char *lang, int mp4) { - int i; - for (i = 0; i < (sizeof(mov_mdhd_language_map)/sizeof(char *)); i++) { + int i, code = 0; + + /* old way, only for QT? */ + for (i = 0; !mp4 && (i < (sizeof(mov_mdhd_language_map)/sizeof(char *))); i++) { if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i])) return i; } - return -1; + /* XXX:can we do that in mov too? */ + if (!mp4) + return 0; + /* handle undefined as such */ + if (lang[0] == '\0') + lang = "und"; + /* 5bit ascii */ + for (i = 0; i < 3; i++) { + unsigned char c = (unsigned char)lang[i]; + if (c < 0x60) + return 0; + if (c > 0x60 + 0x1f) + return 0; + code <<= 5; + code |= (c - 0x60); + } + return code; } static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) @@ -675,7 +707,6 @@ static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) { int version; int lang; - const char *iso639; print_atom("mdhd", atom); version = get_byte(pb); /* version */ @@ -697,9 +728,7 @@ static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */ lang = get_be16(pb); /* language */ - iso639 = ff_mov_lang_to_iso639(lang); - if (iso639) - strncpy(c->fc->streams[c->fc->nb_streams-1]->language, iso639, 4); + ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language); get_be16(pb); /* quality */ return 0; diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 1c721d7200..a340644b79 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -52,6 +52,7 @@ typedef struct MOVIndex { long sampleCount; long sampleDuration; int hasKeyframes; + int language; int trackID; AVCodecContext *enc; @@ -72,6 +73,9 @@ typedef struct MOVContext { static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track); +/* output language code from iso639 language name */ +extern int ff_mov_iso639_to_lang(const char *lang, int mp4); + const CodecTag ff_mov_obj_type[] = { { CODEC_ID_MPEG4 , 32 }, { CODEC_ID_AAC , 64 }, @@ -701,7 +705,7 @@ static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track) put_be32(pb, track->time); /* modification time */ put_be32(pb, track->timescale); /* time scale (sample rate for audio) */ put_be32(pb, track->trackDuration); /* duration */ - put_be16(pb, 0); /* language, 0 = english */ + put_be16(pb, track->language); /* language */ put_be16(pb, 0); /* reserved (quality) */ return 32; } @@ -1331,6 +1335,8 @@ static int mov_write_header(AVFormatContext *s) av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n"); } } + /* don't know yet if mp4 or not */ + mov->tracks[i].language = ff_mov_iso639_to_lang(s->streams[i]->language, 1); } /* Default mode == MP4 */ |