mirror of https://git.ffmpeg.org/ffmpeg.git
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
This commit is contained in:
parent
b9a87c4d6c
commit
ab561df995
|
@ -151,6 +151,8 @@ static const CodecTag mov_audio_tags[] = {
|
||||||
|
|
||||||
/* map numeric codes from mdhd atom to ISO 639 */
|
/* map numeric codes from mdhd atom to ISO 639 */
|
||||||
/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */
|
/* 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[] = {
|
static const char *mov_mdhd_language_map[] = {
|
||||||
/* 0-9 */
|
/* 0-9 */
|
||||||
"eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
|
"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)
|
#define print_atom(a,b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char *ff_mov_lang_to_iso639(int code)
|
static int ff_mov_lang_to_iso639(int code, char *to)
|
||||||
{
|
|
||||||
if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *)))
|
|
||||||
return NULL;
|
|
||||||
if (!mov_mdhd_language_map[code])
|
|
||||||
return NULL;
|
|
||||||
return mov_mdhd_language_map[code];
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int ff_mov_iso639_to_lang(const char *lang); /* for movenc.c */
|
|
||||||
int ff_mov_iso639_to_lang(const char *lang)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < (sizeof(mov_mdhd_language_map)/sizeof(char *)); 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 0;
|
||||||
|
if (!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, int mp4); /* for movenc.c */
|
||||||
|
int ff_mov_iso639_to_lang(const char *lang, int mp4)
|
||||||
|
{
|
||||||
|
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]))
|
if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i]))
|
||||||
return 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)
|
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 version;
|
||||||
int lang;
|
int lang;
|
||||||
const char *iso639;
|
|
||||||
print_atom("mdhd", atom);
|
print_atom("mdhd", atom);
|
||||||
|
|
||||||
version = get_byte(pb); /* version */
|
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 */
|
c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
|
||||||
|
|
||||||
lang = get_be16(pb); /* language */
|
lang = get_be16(pb); /* language */
|
||||||
iso639 = ff_mov_lang_to_iso639(lang);
|
ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
|
||||||
if (iso639)
|
|
||||||
strncpy(c->fc->streams[c->fc->nb_streams-1]->language, iso639, 4);
|
|
||||||
get_be16(pb); /* quality */
|
get_be16(pb); /* quality */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -52,6 +52,7 @@ typedef struct MOVIndex {
|
||||||
long sampleCount;
|
long sampleCount;
|
||||||
long sampleDuration;
|
long sampleDuration;
|
||||||
int hasKeyframes;
|
int hasKeyframes;
|
||||||
|
int language;
|
||||||
int trackID;
|
int trackID;
|
||||||
AVCodecContext *enc;
|
AVCodecContext *enc;
|
||||||
|
|
||||||
|
@ -72,6 +73,9 @@ typedef struct MOVContext {
|
||||||
|
|
||||||
static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track);
|
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[] = {
|
const CodecTag ff_mov_obj_type[] = {
|
||||||
{ CODEC_ID_MPEG4 , 32 },
|
{ CODEC_ID_MPEG4 , 32 },
|
||||||
{ CODEC_ID_AAC , 64 },
|
{ 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->time); /* modification time */
|
||||||
put_be32(pb, track->timescale); /* time scale (sample rate for audio) */
|
put_be32(pb, track->timescale); /* time scale (sample rate for audio) */
|
||||||
put_be32(pb, track->trackDuration); /* duration */
|
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) */
|
put_be16(pb, 0); /* reserved (quality) */
|
||||||
return 32;
|
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");
|
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 */
|
/* Default mode == MP4 */
|
||||||
|
|
Loading…
Reference in New Issue