mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-07-01 05:31:04 +08:00
use new metadata API in mov muxer
Originally committed as revision 17609 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
@ -1230,23 +1230,25 @@ static int mov_write_string_tag(ByteIOContext *pb, const char *name, const char
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iTunes year */
|
static int mov_write_string_metadata(AVFormatContext *s, ByteIOContext *pb,
|
||||||
static int mov_write_day_tag(ByteIOContext *pb, int year, int long_style)
|
const char *name, const char *tag,
|
||||||
|
int long_style)
|
||||||
{
|
{
|
||||||
if(year){
|
AVMetadataTag *t;
|
||||||
char year_str[5];
|
|
||||||
snprintf(year_str, sizeof(year_str), "%04d", year);
|
if (!(t = av_metadata_get(s->metadata, tag, NULL, 0)))
|
||||||
return mov_write_string_tag(pb, "\251day", year_str, long_style);
|
|
||||||
}else
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
return mov_write_string_tag(pb, name, t->value, long_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iTunes track number */
|
/* iTunes track number */
|
||||||
static int mov_write_trkn_tag(ByteIOContext *pb, MOVContext *mov,
|
static int mov_write_trkn_tag(ByteIOContext *pb, MOVContext *mov,
|
||||||
AVFormatContext *s)
|
AVFormatContext *s)
|
||||||
{
|
{
|
||||||
int size = 0;
|
AVMetadataTag *t = av_metadata_get(s->metadata, "track", NULL, 0);
|
||||||
if (s->track) {
|
int size = 0, track = t ? atoi(t->value) : 0;
|
||||||
|
if (track) {
|
||||||
int64_t pos = url_ftell(pb);
|
int64_t pos = url_ftell(pb);
|
||||||
put_be32(pb, 0); /* size */
|
put_be32(pb, 0); /* size */
|
||||||
put_tag(pb, "trkn");
|
put_tag(pb, "trkn");
|
||||||
@ -1257,7 +1259,7 @@ static int mov_write_trkn_tag(ByteIOContext *pb, MOVContext *mov,
|
|||||||
put_be32(pb, 0); // 8 bytes empty
|
put_be32(pb, 0); // 8 bytes empty
|
||||||
put_be32(pb, 0);
|
put_be32(pb, 0);
|
||||||
put_be16(pb, 0); // empty
|
put_be16(pb, 0); // empty
|
||||||
put_be16(pb, s->track); // track number
|
put_be16(pb, track); // track number
|
||||||
put_be16(pb, 0); // total track number
|
put_be16(pb, 0); // total track number
|
||||||
put_be16(pb, 0); // empty
|
put_be16(pb, 0); // empty
|
||||||
updateSize(pb, pos);
|
updateSize(pb, pos);
|
||||||
@ -1274,15 +1276,15 @@ static int mov_write_ilst_tag(ByteIOContext *pb, MOVContext *mov,
|
|||||||
int64_t pos = url_ftell(pb);
|
int64_t pos = url_ftell(pb);
|
||||||
put_be32(pb, 0); /* size */
|
put_be32(pb, 0); /* size */
|
||||||
put_tag(pb, "ilst");
|
put_tag(pb, "ilst");
|
||||||
mov_write_string_tag(pb, "\251nam", s->title , 1);
|
mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
|
||||||
mov_write_string_tag(pb, "\251ART", s->author , 1);
|
mov_write_string_metadata(s, pb, "\251ART", "author" , 1);
|
||||||
mov_write_string_tag(pb, "\251wrt", s->author , 1);
|
mov_write_string_metadata(s, pb, "\251wrt", "author" , 1);
|
||||||
mov_write_string_tag(pb, "\251alb", s->album , 1);
|
mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
|
||||||
mov_write_day_tag(pb, s->year ,1);
|
mov_write_string_metadata(s, pb, "\251day", "year" , 1);
|
||||||
mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 1);
|
mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 1);
|
||||||
mov_write_string_tag(pb, "\251cmt", s->comment , 1);
|
mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
|
||||||
mov_write_string_tag(pb, "\251gen", s->genre , 1);
|
mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
|
||||||
mov_write_string_tag(pb, "\251cpy", s->copyright , 1);
|
mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1);
|
||||||
mov_write_trkn_tag(pb, mov, s);
|
mov_write_trkn_tag(pb, mov, s);
|
||||||
return updateSize(pb, pos);
|
return updateSize(pb, pos);
|
||||||
}
|
}
|
||||||
@ -1293,9 +1295,6 @@ static int mov_write_meta_tag(ByteIOContext *pb, MOVContext *mov,
|
|||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
// only save meta tag if required
|
|
||||||
if (s->title[0] || s->author[0] || s->album[0] || s->year ||
|
|
||||||
s->comment[0] || s->genre[0] || s->track) {
|
|
||||||
int64_t pos = url_ftell(pb);
|
int64_t pos = url_ftell(pb);
|
||||||
put_be32(pb, 0); /* size */
|
put_be32(pb, 0); /* size */
|
||||||
put_tag(pb, "meta");
|
put_tag(pb, "meta");
|
||||||
@ -1303,7 +1302,6 @@ static int mov_write_meta_tag(ByteIOContext *pb, MOVContext *mov,
|
|||||||
mov_write_itunes_hdlr_tag(pb, mov, s);
|
mov_write_itunes_hdlr_tag(pb, mov, s);
|
||||||
mov_write_ilst_tag(pb, mov, s);
|
mov_write_ilst_tag(pb, mov, s);
|
||||||
size = updateSize(pb, pos);
|
size = updateSize(pb, pos);
|
||||||
}
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,18 +1336,20 @@ static int mov_write_3gp_udta_tag(ByteIOContext *pb, AVFormatContext *s,
|
|||||||
const char *tag, const char *str)
|
const char *tag, const char *str)
|
||||||
{
|
{
|
||||||
int64_t pos = url_ftell(pb);
|
int64_t pos = url_ftell(pb);
|
||||||
if (!utf8len(str))
|
AVMetadataTag *t = av_metadata_get(s->metadata, str, NULL, 0);
|
||||||
|
if (!t || !utf8len(t->value))
|
||||||
return 0;
|
return 0;
|
||||||
put_be32(pb, 0); /* size */
|
put_be32(pb, 0); /* size */
|
||||||
put_tag (pb, tag); /* type */
|
put_tag (pb, tag); /* type */
|
||||||
put_be32(pb, 0); /* version + flags */
|
put_be32(pb, 0); /* version + flags */
|
||||||
if (!strcmp(tag, "yrrc"))
|
if (!strcmp(tag, "yrrc"))
|
||||||
put_be16(pb, s->year);
|
put_be16(pb, atoi(t->value));
|
||||||
else {
|
else {
|
||||||
put_be16(pb, language_code("eng")); /* language */
|
put_be16(pb, language_code("eng")); /* language */
|
||||||
ascii_to_wc(pb, str);
|
ascii_to_wc(pb, t->value);
|
||||||
if (!strcmp(tag, "albm") && s->year)
|
if (!strcmp(tag, "albm") &&
|
||||||
put_byte(pb, s->year);
|
(t = av_metadata_get(s->metadata, "year", NULL, 0)))
|
||||||
|
put_byte(pb, atoi(t->value));
|
||||||
}
|
}
|
||||||
return updateSize(pb, pos);
|
return updateSize(pb, pos);
|
||||||
}
|
}
|
||||||
@ -1357,44 +1357,46 @@ static int mov_write_3gp_udta_tag(ByteIOContext *pb, AVFormatContext *s,
|
|||||||
static int mov_write_udta_tag(ByteIOContext *pb, MOVContext *mov,
|
static int mov_write_udta_tag(ByteIOContext *pb, MOVContext *mov,
|
||||||
AVFormatContext *s)
|
AVFormatContext *s)
|
||||||
{
|
{
|
||||||
int i;
|
ByteIOContext *pb_buf;
|
||||||
int bitexact = 0;
|
int i, ret, size;
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
for (i = 0; i < s->nb_streams; i++)
|
for (i = 0; i < s->nb_streams; i++)
|
||||||
if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
|
if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
|
||||||
bitexact = 1;
|
return 0;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bitexact && (s->title[0] || s->author[0] || s->album[0] || s->year ||
|
ret = url_open_dyn_buf(&pb_buf);
|
||||||
s->comment[0] || s->genre[0] || s->track)) {
|
if(ret < 0)
|
||||||
int64_t pos = url_ftell(pb);
|
return ret;
|
||||||
|
|
||||||
put_be32(pb, 0); /* size */
|
|
||||||
put_tag(pb, "udta");
|
|
||||||
|
|
||||||
if (mov->mode & MODE_3GP) {
|
if (mov->mode & MODE_3GP) {
|
||||||
mov_write_3gp_udta_tag(pb, s, "titl", s->title);
|
mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
|
||||||
mov_write_3gp_udta_tag(pb, s, "auth", s->author);
|
mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
|
||||||
mov_write_3gp_udta_tag(pb, s, "gnre", s->genre);
|
mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
|
||||||
mov_write_3gp_udta_tag(pb, s, "dscp", s->comment);
|
mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
|
||||||
mov_write_3gp_udta_tag(pb, s, "albm", s->album);
|
mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
|
||||||
mov_write_3gp_udta_tag(pb, s, "cprt", s->copyright);
|
mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
|
||||||
mov_write_3gp_udta_tag(pb, s, "yrrc", "nil");
|
mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "year");
|
||||||
} else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
|
} else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
|
||||||
mov_write_string_tag(pb, "\251nam", s->title , 0);
|
mov_write_string_metadata(s, pb_buf, "\251nam", "title" , 0);
|
||||||
mov_write_string_tag(pb, "\251aut", s->author , 0);
|
mov_write_string_metadata(s, pb_buf, "\251aut", "author" , 0);
|
||||||
mov_write_string_tag(pb, "\251alb", s->album , 0);
|
mov_write_string_metadata(s, pb_buf, "\251alb", "album" , 0);
|
||||||
mov_write_day_tag(pb, s->year, 0);
|
mov_write_string_metadata(s, pb_buf, "\251day", "year" , 0);
|
||||||
mov_write_string_tag(pb, "\251enc", LIBAVFORMAT_IDENT, 0);
|
mov_write_string_tag(pb_buf, "\251enc", LIBAVFORMAT_IDENT, 0);
|
||||||
mov_write_string_tag(pb, "\251des", s->comment , 0);
|
mov_write_string_metadata(s, pb_buf, "\251des", "comment" , 0);
|
||||||
mov_write_string_tag(pb, "\251gen", s->genre , 0);
|
mov_write_string_metadata(s, pb_buf, "\251gen", "genre" , 0);
|
||||||
mov_write_string_tag(pb, "\251cpy", s->copyright , 0);
|
mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright" , 0);
|
||||||
} else {
|
} else {
|
||||||
/* iTunes meta data */
|
/* iTunes meta data */
|
||||||
mov_write_meta_tag(pb, mov, s);
|
mov_write_meta_tag(pb_buf, mov, s);
|
||||||
}
|
}
|
||||||
return updateSize(pb, pos);
|
|
||||||
|
if ((size = url_close_dyn_buf(pb_buf, &buf)) > 0) {
|
||||||
|
put_be32(pb, size+8);
|
||||||
|
put_tag(pb, "udta");
|
||||||
|
put_buffer(pb, buf, size);
|
||||||
|
av_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1415,9 +1417,10 @@ static void mov_write_psp_udta_tag(ByteIOContext *pb,
|
|||||||
|
|
||||||
static int mov_write_uuidusmt_tag(ByteIOContext *pb, AVFormatContext *s)
|
static int mov_write_uuidusmt_tag(ByteIOContext *pb, AVFormatContext *s)
|
||||||
{
|
{
|
||||||
|
AVMetadataTag *title = av_metadata_get(s->metadata, "title", NULL, 0);
|
||||||
int64_t pos, pos2;
|
int64_t pos, pos2;
|
||||||
|
|
||||||
if (s->title[0]) {
|
if (title) {
|
||||||
pos = url_ftell(pb);
|
pos = url_ftell(pb);
|
||||||
put_be32(pb, 0); /* size placeholder*/
|
put_be32(pb, 0); /* size placeholder*/
|
||||||
put_tag(pb, "uuid");
|
put_tag(pb, "uuid");
|
||||||
@ -1439,7 +1442,7 @@ static int mov_write_uuidusmt_tag(ByteIOContext *pb, AVFormatContext *s)
|
|||||||
put_be16(pb, 0x021C); /* data */
|
put_be16(pb, 0x021C); /* data */
|
||||||
|
|
||||||
mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
|
mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
|
||||||
mov_write_psp_udta_tag(pb, s->title, "eng", 0x01);
|
mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
|
||||||
// snprintf(dt,32,"%04d/%02d/%02d %02d:%02d:%02d",t_st->tm_year+1900,t_st->tm_mon+1,t_st->tm_mday,t_st->tm_hour,t_st->tm_min,t_st->tm_sec);
|
// snprintf(dt,32,"%04d/%02d/%02d %02d:%02d:%02d",t_st->tm_year+1900,t_st->tm_mon+1,t_st->tm_mday,t_st->tm_hour,t_st->tm_min,t_st->tm_sec);
|
||||||
mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
|
mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
|
||||||
|
|
||||||
@ -1645,9 +1648,10 @@ static int mov_write_header(AVFormatContext *s)
|
|||||||
for(i=0; i<s->nb_streams; i++){
|
for(i=0; i<s->nb_streams; i++){
|
||||||
AVStream *st= s->streams[i];
|
AVStream *st= s->streams[i];
|
||||||
MOVTrack *track= &mov->tracks[i];
|
MOVTrack *track= &mov->tracks[i];
|
||||||
|
AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL,0);
|
||||||
|
|
||||||
track->enc = st->codec;
|
track->enc = st->codec;
|
||||||
track->language = ff_mov_iso639_to_lang(st->language, mov->mode != MODE_MOV);
|
track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
|
||||||
track->mode = mov->mode;
|
track->mode = mov->mode;
|
||||||
track->tag = mov_find_codec_tag(s, track);
|
track->tag = mov_find_codec_tag(s, track);
|
||||||
if (!track->tag) {
|
if (!track->tag) {
|
||||||
|
Reference in New Issue
Block a user