~ubuntu-branches/ubuntu/utopic/libav/utopic-proposed

« back to all changes in this revision

Viewing changes to libavformat/movenc.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler, Reinhard Tartler, Rico Tzschichholz
  • Date: 2014-08-30 11:02:45 UTC
  • mfrom: (1.3.47 sid)
  • Revision ID: package-import@ubuntu.com-20140830110245-io3dg7q85wfr7125
Tags: 6:11~beta1-2
[ Reinhard Tartler ]
* Make libavcodec-dev depend on libavresample-dev

[ Rico Tzschichholz ]
* Some fixes and leftovers from soname bumps

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 */
23
23
 
24
24
#include <stdint.h>
 
25
#include <inttypes.h>
25
26
 
26
27
#include "movenc.h"
27
28
#include "avformat.h"
56
57
    { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
57
58
    { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
58
59
    { "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
 
60
    { "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
59
61
    FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
60
62
    { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
61
63
    { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
76
78
    .version    = LIBAVUTIL_VERSION_INT,\
77
79
};
78
80
 
 
81
static int utf8len(const uint8_t *b)
 
82
{
 
83
    int len = 0;
 
84
    int val;
 
85
    while (*b) {
 
86
        GET_UTF8(val, *b++, return -1;)
 
87
        len++;
 
88
    }
 
89
    return len;
 
90
}
 
91
 
79
92
//FIXME support 64 bit variant with wide placeholders
80
93
static int64_t update_size(AVIOContext *pb, int64_t pos)
81
94
{
309
322
 
310
323
    // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
311
324
    // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
312
 
    if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
 
325
    if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
 
326
        avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
 
327
    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
313
328
        avio_w8(pb, 0x15); // flags (= Audiostream)
314
329
    else
315
330
        avio_w8(pb, 0x11); // flags (= Visualstream)
480
495
    put_bits(&pbc, 1, !slices); /* no slice code */
481
496
    put_bits(&pbc, 1, 0); /* no bframe */
482
497
    put_bits(&pbc, 1, 0); /* reserved */
483
 
    put_bits32(&pbc, track->enc->time_base.den); /* framerate */
 
498
 
 
499
    /* framerate */
 
500
    if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
 
501
        put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
 
502
    else
 
503
        put_bits32(&pbc, 0xffffffff);
 
504
 
484
505
    flush_put_bits(&pbc);
485
506
 
486
507
    av_free(unescaped);
760
781
    else if (track->enc->codec_id == AV_CODEC_ID_VC1)       tag = MKTAG('v','c','-','1');
761
782
    else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)  tag = MKTAG('m','p','4','v');
762
783
    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)  tag = MKTAG('m','p','4','a');
 
784
    else if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)  tag = MKTAG('m','p','4','s');
763
785
 
764
786
    return tag;
765
787
}
804
826
        else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
805
827
        else                                                tag = MKTAG('d','v','p','p');
806
828
    else if (track->enc->height == 720) /* HD 720 line */
807
 
        if  (track->enc->time_base.den == 50)               tag = MKTAG('d','v','h','q');
 
829
        if  (track->st->time_base.den == 50)                tag = MKTAG('d','v','h','q');
808
830
        else                                                tag = MKTAG('d','v','h','p');
809
831
    else if (track->enc->height == 1080) /* HD 1080 line */
810
 
        if  (track->enc->time_base.den == 25)               tag = MKTAG('d','v','h','5');
 
832
        if  (track->st->time_base.den == 25)                tag = MKTAG('d','v','h','5');
811
833
        else                                                tag = MKTAG('d','v','h','6');
812
834
    else {
813
835
        av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
976
998
    avio_wb16(pb, 0);    /* Reserved */
977
999
    avio_wb16(pb, 1);    /* Data-reference index */
978
1000
 
979
 
    if (track->enc->extradata_size)
 
1001
    if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
 
1002
        mov_write_esds_tag(pb, track);
 
1003
    else if (track->enc->extradata_size)
980
1004
        avio_write(pb, track->enc->extradata, track->enc->extradata_size);
981
1005
 
982
1006
    return update_size(pb, pos);
997
1021
 
998
1022
static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
999
1023
{
 
1024
    AVDictionaryEntry *encoder;
1000
1025
    int64_t pos = avio_tell(pb);
1001
1026
    char compressor_name[32] = { 0 };
1002
1027
 
1030
1055
    avio_wb16(pb, 1); /* Frame count (= 1) */
1031
1056
 
1032
1057
    /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
1033
 
    if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
1034
 
        av_strlcpy(compressor_name, track->enc->codec->name, 32);
 
1058
    if (track->mode == MODE_MOV &&
 
1059
        (encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0)))
 
1060
        av_strlcpy(compressor_name, encoder->value, 32);
1035
1061
    avio_w8(pb, strlen(compressor_name));
1036
1062
    avio_write(pb, compressor_name, 31);
1037
1063
 
1289
1315
    return 0x14;
1290
1316
}
1291
1317
 
 
1318
static int is_clcp_track(MOVTrack *track)
 
1319
{
 
1320
    return track->tag == MKTAG('c','7','0','8') ||
 
1321
           track->tag == MKTAG('c','6','0','8');
 
1322
}
 
1323
 
1292
1324
static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
1293
1325
{
1294
1326
    const char *hdlr, *descr = NULL, *hdlr_type = NULL;
1307
1339
            hdlr_type = "soun";
1308
1340
            descr     = "SoundHandler";
1309
1341
        } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1310
 
            if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
1311
 
            else                                      hdlr_type = "text";
 
1342
            if (track->tag == MKTAG('t','x','3','g')) {
 
1343
                hdlr_type = "sbtl";
 
1344
            } else if (track->tag == MKTAG('m','p','4','s')) {
 
1345
                hdlr_type = "subp";
 
1346
            } else if (is_clcp_track(track)) {
 
1347
                hdlr_type = "clcp";
 
1348
            } else {
 
1349
                hdlr_type = "text";
 
1350
            }
1312
1351
            descr = "SubtitleHandler";
1313
1352
        } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
1314
1353
            hdlr_type = "hint";
1325
1364
                   "Unknown hldr_type for %s / 0x%04X, writing dummy values\n",
1326
1365
                   tag_buf, track->enc->codec_tag);
1327
1366
        }
 
1367
        if (track->st) {
 
1368
            // hdlr.name is used by some players to identify the content title
 
1369
            // of the track. So if an alternate handler description is
 
1370
            // specified, use it.
 
1371
            AVDictionaryEntry *t;
 
1372
            t = av_dict_get(track->st->metadata, "handler", NULL, 0);
 
1373
            if (t && utf8len(t->value))
 
1374
                descr = t->value;
 
1375
        }
1328
1376
    }
1329
1377
 
1330
1378
    avio_wb32(pb, 0); /* size */
1368
1416
    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1369
1417
        mov_write_smhd_tag(pb);
1370
1418
    else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1371
 
        if (track->tag == MKTAG('t','e','x','t')) mov_write_gmhd_tag(pb);
1372
 
        else                                      mov_write_nmhd_tag(pb);
 
1419
        if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
 
1420
            mov_write_gmhd_tag(pb);
 
1421
        } else {
 
1422
            mov_write_nmhd_tag(pb);
 
1423
        }
1373
1424
    } else if (track->tag == MKTAG('r','t','p',' ')) {
1374
1425
        mov_write_hmhd_tag(pb);
1375
1426
    } else if (track->tag == MKTAG('t','m','c','d')) {
1429
1480
    return update_size(pb, pos);
1430
1481
}
1431
1482
 
1432
 
static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
 
1483
static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov,
 
1484
                              MOVTrack *track, AVStream *st)
1433
1485
{
1434
1486
    int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
1435
1487
                                      track->timescale, AV_ROUND_UP);
1436
1488
    int version = duration < INT32_MAX ? 0 : 1;
 
1489
    int flags   = MOV_TKHD_FLAG_IN_MOVIE;
 
1490
    int group   = 0;
 
1491
 
 
1492
 
 
1493
    if (st) {
 
1494
        if (mov->per_stream_grouping)
 
1495
            group = st->index;
 
1496
        else
 
1497
            group = st->codec->codec_type;
 
1498
    }
 
1499
 
 
1500
    if (track->flags & MOV_TRACK_ENABLED)
 
1501
        flags |= MOV_TKHD_FLAG_ENABLED;
1437
1502
 
1438
1503
    if (track->mode == MODE_ISM)
1439
1504
        version = 1;
1441
1506
    (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
1442
1507
    ffio_wfourcc(pb, "tkhd");
1443
1508
    avio_w8(pb, version);
1444
 
    avio_wb24(pb, (track->flags & MOV_TRACK_ENABLED) ?
1445
 
                  MOV_TKHD_FLAG_ENABLED | MOV_TKHD_FLAG_IN_MOVIE :
1446
 
                  MOV_TKHD_FLAG_IN_MOVIE);
 
1509
    avio_wb24(pb, flags);
1447
1510
    if (version == 1) {
1448
1511
        avio_wb64(pb, track->time);
1449
1512
        avio_wb64(pb, track->time);
1461
1524
    avio_wb32(pb, 0); /* reserved */
1462
1525
    avio_wb32(pb, 0); /* reserved */
1463
1526
    avio_wb16(pb, 0); /* layer */
1464
 
    avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
 
1527
    avio_wb16(pb, group); /* alternate group) */
1465
1528
    /* Volume, only for audio */
1466
1529
    if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1467
1530
        avio_wb16(pb, 0x0100);
1517
1580
    avio_wb32(pb, track->enc->height << 16);
1518
1581
 
1519
1582
    avio_wb32(pb, 20);
 
1583
    ffio_wfourcc(pb, "prof");
 
1584
    avio_wb32(pb, 0);
 
1585
    avio_wb32(pb, width << 16);
 
1586
    avio_wb32(pb, track->enc->height << 16);
 
1587
 
 
1588
    avio_wb32(pb, 20);
1520
1589
    ffio_wfourcc(pb, "enof");
1521
1590
    avio_wb32(pb, 0);
1522
1591
    avio_wb32(pb, track->enc->width << 16);
1623
1692
    return len + 24;
1624
1693
}
1625
1694
 
 
1695
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st,
 
1696
                                    const char *tag, const char *str)
 
1697
{
 
1698
    int64_t pos = avio_tell(pb);
 
1699
    AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
 
1700
    if (!t || !utf8len(t->value))
 
1701
        return 0;
 
1702
 
 
1703
    avio_wb32(pb, 0);   /* size */
 
1704
    ffio_wfourcc(pb, tag); /* type */
 
1705
    avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
 
1706
    return update_size(pb, pos);
 
1707
}
 
1708
 
 
1709
static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
 
1710
                                    AVStream *st)
 
1711
{
 
1712
    AVIOContext *pb_buf;
 
1713
    int ret, size;
 
1714
    uint8_t *buf;
 
1715
 
 
1716
    if (!st || mov->fc->flags & AVFMT_FLAG_BITEXACT)
 
1717
        return 0;
 
1718
 
 
1719
    ret = avio_open_dyn_buf(&pb_buf);
 
1720
    if (ret < 0)
 
1721
        return ret;
 
1722
 
 
1723
    if (mov->mode & MODE_MP4)
 
1724
        mov_write_track_metadata(pb_buf, st, "name", "title");
 
1725
 
 
1726
    if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
 
1727
        avio_wb32(pb, size + 8);
 
1728
        ffio_wfourcc(pb, "udta");
 
1729
        avio_write(pb, buf, size);
 
1730
    }
 
1731
    av_free(buf);
 
1732
 
 
1733
    return 0;
 
1734
}
 
1735
 
1626
1736
static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,
1627
1737
                              MOVTrack *track, AVStream *st)
1628
1738
{
1629
1739
    int64_t pos = avio_tell(pb);
1630
1740
    avio_wb32(pb, 0); /* size */
1631
1741
    ffio_wfourcc(pb, "trak");
1632
 
    mov_write_tkhd_tag(pb, track, st);
 
1742
    mov_write_tkhd_tag(pb, mov, track, st);
1633
1743
    if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS ||
1634
 
        (track->entry && track->cluster[0].dts)) {
 
1744
        (track->entry && track->cluster[0].dts) ||
 
1745
        is_clcp_track(track)) {
1635
1746
        if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
1636
1747
            mov_write_edts_tag(pb, track);  // PSP Movies require edts box
1637
1748
    }
1642
1753
        mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
1643
1754
    if (track->tag == MKTAG('r','t','p',' '))
1644
1755
        mov_write_udta_sdp(pb, track);
1645
 
    if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
1646
 
        double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
1647
 
        if (0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)
 
1756
    if (track->mode == MODE_MOV) {
 
1757
        if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
 
1758
            double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
 
1759
            if ((0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)) {
 
1760
                mov_write_tapt_tag(pb, track);
 
1761
            }
 
1762
        }
 
1763
        if (is_clcp_track(track)) {
1648
1764
            mov_write_tapt_tag(pb, track);
 
1765
        }
1649
1766
    }
 
1767
    mov_write_track_udta_tag(pb, mov, st);
1650
1768
    return update_size(pb, pos);
1651
1769
}
1652
1770
 
1904
2022
    return size;
1905
2023
}
1906
2024
 
1907
 
static int utf8len(const uint8_t *b)
1908
 
{
1909
 
    int len = 0;
1910
 
    int val;
1911
 
    while (*b) {
1912
 
        GET_UTF8(val, *b++, return -1;)
1913
 
        len++;
1914
 
    }
1915
 
    return len;
1916
 
}
1917
 
 
1918
2025
static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
1919
2026
{
1920
2027
    int val;
1985
2092
                              AVFormatContext *s)
1986
2093
{
1987
2094
    AVIOContext *pb_buf;
1988
 
    int i, ret, size;
 
2095
    int ret, size;
1989
2096
    uint8_t *buf;
1990
2097
 
1991
 
    for (i = 0; i < s->nb_streams; i++)
1992
 
        if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
1993
 
            return 0;
1994
 
        }
 
2098
    if (s->flags & AVFMT_FLAG_BITEXACT)
 
2099
        return 0;
1995
2100
 
1996
2101
    ret = avio_open_dyn_buf(&pb_buf);
1997
2102
    if (ret < 0)
2021
2126
        mov_write_meta_tag(pb_buf, mov, s);
2022
2127
    }
2023
2128
 
2024
 
    if (s->nb_chapters)
 
2129
    if (s->nb_chapters && !(mov->flags & FF_MOV_FLAG_DISABLE_CHPL))
2025
2130
        mov_write_chpl_tag(pb_buf, s);
2026
2131
 
2027
2132
    if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
2613
2718
 
2614
2719
static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
2615
2720
{
 
2721
    AVStream       *video_st    = s->streams[0];
2616
2722
    AVCodecContext *video_codec = s->streams[0]->codec;
2617
2723
    AVCodecContext *audio_codec = s->streams[1]->codec;
2618
2724
    int audio_rate = audio_codec->sample_rate;
2619
 
    int frame_rate = ((video_codec->time_base.den) * (0x10000)) / (video_codec->time_base.num);
 
2725
    // TODO: should be avg_frame_rate
 
2726
    int frame_rate = ((video_st->time_base.den) * (0x10000)) / (video_st->time_base.num);
2620
2727
    int audio_kbitrate = audio_codec->bit_rate / 1000;
2621
2728
    int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
2622
2729
 
3075
3182
        return AVERROR(ENOMEM);
3076
3183
    track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
3077
3184
    track->enc->extradata = av_malloc(sizeof(chapter_properties));
3078
 
    if (track->enc->extradata == NULL)
 
3185
    if (!track->enc->extradata)
3079
3186
        return AVERROR(ENOMEM);
3080
3187
    track->enc->extradata_size = sizeof(chapter_properties);
3081
3188
    memcpy(track->enc->extradata, chapter_properties, sizeof(chapter_properties));
3089
3196
        pkt.duration = end - pkt.dts;
3090
3197
 
3091
3198
        if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
 
3199
            const char encd[12] = {
 
3200
                0x00, 0x00, 0x00, 0x0C,
 
3201
                'e',  'n',  'c',  'd',
 
3202
                0x00, 0x00, 0x01, 0x00 };
3092
3203
            len      = strlen(t->value);
3093
 
            pkt.size = len + 2;
 
3204
            pkt.size = len + 2 + 12;
3094
3205
            pkt.data = av_malloc(pkt.size);
3095
3206
            if (!pkt.data)
3096
3207
                return AVERROR(ENOMEM);
3097
3208
            AV_WB16(pkt.data, len);
3098
3209
            memcpy(pkt.data + 2, t->value, len);
 
3210
            memcpy(pkt.data + len + 2, encd, sizeof(encd));
3099
3211
            ff_mov_write_packet(s, &pkt);
3100
3212
            av_freep(&pkt.data);
3101
3213
        }
3119
3231
{
3120
3232
    MOVMuxContext *mov = s->priv_data;
3121
3233
    int i;
3122
 
    uint8_t enabled[AVMEDIA_TYPE_NB];
 
3234
    int enabled[AVMEDIA_TYPE_NB];
3123
3235
    int first[AVMEDIA_TYPE_NB];
3124
3236
 
3125
3237
    for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
3138
3250
            first[st->codec->codec_type] = i;
3139
3251
        if (st->disposition & AV_DISPOSITION_DEFAULT) {
3140
3252
            mov->tracks[i].flags |= MOV_TRACK_ENABLED;
3141
 
            enabled[st->codec->codec_type] = 1;
 
3253
            enabled[st->codec->codec_type]++;
3142
3254
        }
3143
3255
    }
3144
3256
 
3147
3259
        case AVMEDIA_TYPE_VIDEO:
3148
3260
        case AVMEDIA_TYPE_AUDIO:
3149
3261
        case AVMEDIA_TYPE_SUBTITLE:
 
3262
            if (enabled[i] > 1)
 
3263
                mov->per_stream_grouping = 1;
3150
3264
            if (!enabled[i] && first[i] >= 0)
3151
3265
                mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
3152
3266
            break;
3178
3292
    av_freep(&mov->tracks);
3179
3293
}
3180
3294
 
 
3295
static uint32_t rgb_to_yuv(uint32_t rgb)
 
3296
{
 
3297
    uint8_t r, g, b;
 
3298
    int y, cb, cr;
 
3299
 
 
3300
    r = (rgb >> 16) & 0xFF;
 
3301
    g = (rgb >>  8) & 0xFF;
 
3302
    b = (rgb      ) & 0xFF;
 
3303
 
 
3304
    y  = av_clip_uint8( 16. +  0.257 * r + 0.504 * g + 0.098 * b);
 
3305
    cb = av_clip_uint8(128. -  0.148 * r - 0.291 * g + 0.439 * b);
 
3306
    cr = av_clip_uint8(128. +  0.439 * r - 0.368 * g - 0.071 * b);
 
3307
 
 
3308
    return (y << 16) | (cr << 8) | cb;
 
3309
}
 
3310
 
 
3311
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
 
3312
                                                    AVStream *st)
 
3313
{
 
3314
    int i, width = 720, height = 480;
 
3315
    int have_palette = 0, have_size = 0;
 
3316
    uint32_t palette[16];
 
3317
    char *cur = st->codec->extradata;
 
3318
 
 
3319
    while (cur && *cur) {
 
3320
        if (strncmp("palette:", cur, 8) == 0) {
 
3321
            int i, count;
 
3322
            count = sscanf(cur + 8,
 
3323
                "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
 
3324
                "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
 
3325
                "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
 
3326
                "%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
 
3327
                &palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
 
3328
                &palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
 
3329
                &palette[ 8], &palette[ 9], &palette[10], &palette[11],
 
3330
                &palette[12], &palette[13], &palette[14], &palette[15]);
 
3331
 
 
3332
            for (i = 0; i < count; i++) {
 
3333
                palette[i] = rgb_to_yuv(palette[i]);
 
3334
            }
 
3335
            have_palette = 1;
 
3336
        } else if (!strncmp("size:", cur, 5)) {
 
3337
            sscanf(cur + 5, "%dx%d", &width, &height);
 
3338
            have_size = 1;
 
3339
        }
 
3340
        if (have_palette && have_size)
 
3341
            break;
 
3342
        cur += strcspn(cur, "\n\r");
 
3343
        cur += strspn(cur, "\n\r");
 
3344
    }
 
3345
    if (have_palette) {
 
3346
        track->vos_data = av_malloc(16*4);
 
3347
        if (!track->vos_data)
 
3348
            return AVERROR(ENOMEM);
 
3349
        for (i = 0; i < 16; i++) {
 
3350
            AV_WB32(track->vos_data + i * 4, palette[i]);
 
3351
        }
 
3352
        track->vos_len = 16 * 4;
 
3353
    }
 
3354
    st->codec->width = width;
 
3355
    st->codec->height = track->height = height;
 
3356
 
 
3357
    return 0;
 
3358
}
 
3359
 
3181
3360
static int mov_write_header(AVFormatContext *s)
3182
3361
{
3183
3362
    AVIOContext *pb = s->pb;
3185
3364
    AVDictionaryEntry *t;
3186
3365
    int i, hint_track = 0;
3187
3366
 
 
3367
    mov->fc = s;
 
3368
 
3188
3369
    /* Default mode == MP4 */
3189
3370
    mov->mode = MODE_MP4;
3190
3371
 
3191
 
    if (s->oformat != NULL) {
 
3372
    if (s->oformat) {
3192
3373
        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
3193
3374
        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
3194
3375
        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
3266
3447
        MOVTrack *track= &mov->tracks[i];
3267
3448
        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
3268
3449
 
 
3450
        track->st  = st;
3269
3451
        track->enc = st->codec;
3270
3452
        track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
3271
3453
        if (track->language < 0)
3291
3473
                }
3292
3474
                track->height = track->tag >> 24 == 'n' ? 486 : 576;
3293
3475
            }
3294
 
            track->timescale = st->codec->time_base.den;
 
3476
            track->timescale = st->time_base.den;
3295
3477
            if (track->mode == MODE_MOV && track->timescale > 100000)
3296
3478
                av_log(s, AV_LOG_WARNING,
3297
3479
                       "WARNING codec timebase is very high. If duration is too long,\n"
3319
3501
                goto error;
3320
3502
            }
3321
3503
        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3322
 
            track->timescale = st->codec->time_base.den;
 
3504
            track->timescale = st->time_base.den;
3323
3505
        } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {
3324
 
            track->timescale = st->codec->time_base.den;
 
3506
            track->timescale = st->time_base.den;
3325
3507
        }
3326
3508
        if (!track->height)
3327
3509
            track->height = st->codec->height;
3334
3516
 
3335
3517
        /* copy extradata if it exists */
3336
3518
        if (st->codec->extradata_size) {
3337
 
            track->vos_len  = st->codec->extradata_size;
3338
 
            track->vos_data = av_malloc(track->vos_len);
3339
 
            memcpy(track->vos_data, st->codec->extradata, track->vos_len);
 
3519
            if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
 
3520
                mov_create_dvd_sub_decoder_specific_info(track, st);
 
3521
            else {
 
3522
                track->vos_len  = st->codec->extradata_size;
 
3523
                track->vos_data = av_malloc(track->vos_len);
 
3524
                memcpy(track->vos_data, st->codec->extradata, track->vos_len);
 
3525
            }
3340
3526
        }
3341
3527
    }
3342
3528