Ticket #551: mov.c.diff

File mov.c.diff, 9.0 KB (added by ilevin, 15 years ago)
  • mov.c

    old new  
    2020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    2121 */
    2222
     23//------------------------------------------------------Modifications History
     24// DATE            DESCRIPTION
     25// 06-06-2011      support reading H263 'bitr' box
     26// 02-25-2011      added support for max NALSize
     27// 02-22-2011      added support for max bitrate
     28// 12-10-2010      Allow parsing udta box metadata on stream level
     29
     30
    2331#include <limits.h>
     32#include <alloca.h>
    2433
    2534//#define DEBUG
    2635//#define DEBUG_METADATA
    27 //#define MOV_EXPORT_ALL_METADATA
     36#define MOV_EXPORT_ALL_METADATA
    2837
    2938#include "libavutil/intreadwrite.h"
    3039#include "libavutil/avstring.h"
    … …  
    93102    return 0;
    94103}
    95104
     105static int mov_metadata_hnti(MOVContext *c, ByteIOContext *pb, unsigned len)
     106{
     107    unsigned int remainder = len;
     108    int size, tag;
     109    AVMetadata **pm;
     110    AVStream *st;
     111    char *str;
     112
     113    if (c->metadata_ext & META_EXT_STREAM_LEVEL)
     114    {
     115        if (c->fc->nb_streams < 1)
     116            return 0;
     117
     118        st = c->fc->streams[c->fc->nb_streams-1];
     119        pm = &st->metadata;
     120    }
     121    else
     122    {
     123        pm = &c->fc->metadata;
     124    }
     125
     126    str = alloca(len + 1);
     127
     128    while (remainder > 4)
     129    {
     130        // read next element
     131        size = get_be32(pb);
     132        tag = get_le32(pb);
     133
     134        if (tag == MKTAG('s','d','p',' '))
     135        {
     136            get_buffer(pb, str, size - 8);
     137            str[size - 8] = 0;
     138
     139            av_metadata_set2(pm, "sdp", str, 0);
     140        }
     141
     142        remainder -= size;
     143
     144    }
     145
     146    return 0;
     147}
     148
    96149static const uint32_t mac_to_unicode[128] = {
    97150    0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
    98151    0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
    … …  
    141194    uint32_t data_type = 0;
    142195    int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL;
    143196
    144     switch (atom.type) {
     197    AVMetadata **pm;
     198    AVStream *st;
     199
     200    if (c->metadata_ext & META_EXT_STREAM_LEVEL)
     201    {
     202       if (c->fc->nb_streams < 1)
     203            return 0;
     204
     205        st = c->fc->streams[c->fc->nb_streams-1];
     206        pm = &st->metadata;
     207    }
     208    else
     209    {
     210       pm = &c->fc->metadata;
     211    }
     212
     213    switch (atom.type)
     214    {
    145215    case MKTAG(0xa9,'n','a','m'): key = "title";     break;
    146216    case MKTAG(0xa9,'a','u','t'):
    147217    case MKTAG(0xa9,'A','R','T'): key = "artist";    break;
    … …  
    161231    case MKTAG( 't','v','e','n'): key = "episode_id";break;
    162232    case MKTAG( 't','v','n','n'): key = "network";   break;
    163233    case MKTAG( 't','r','k','n'): key = "track";
    164         parse = mov_metadata_trkn; break;
     234        parse = mov_metadata_trkn;
     235        break;
     236
     237    case MKTAG( 'h','n','t','i'):
     238        parse = mov_metadata_hnti;
     239        break;
     240
    165241    }
    166242
    167     if (c->itunes_metadata && atom.size > 8) {
     243    if ((c->metadata_ext & META_EXT_ITUNES_TYPE) && atom.size > 8)
     244    {
    168245        int data_size = get_be32(pb);
    169246        int tag = get_le32(pb);
    170         if (tag == MKTAG('d','a','t','a')) {
     247        if (tag == MKTAG('d','a','t','a'))
     248        {
    171249            data_type = get_be32(pb); // type
    172250            get_be32(pb); // unknown
    173251            str_size = data_size - 16;
    174252            atom.size -= 16;
    175253        } else return 0;
    176     } else if (atom.size > 4 && key && !c->itunes_metadata) {
     254    }
     255    else if (atom.size > 4 && key && !(c->metadata_ext & META_EXT_ITUNES_TYPE))
     256    {
    177257        str_size = get_be16(pb); // string length
    178258        langcode = get_be16(pb);
    179259        ff_mov_lang_to_iso639(langcode, language);
    … …  
    197277
    198278    if (parse)
    199279        parse(c, pb, str_size);
    200     else {
     280    else
     281    {
    201282        if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded
    202283            mov_read_mac_string(c, pb, str_size, str, sizeof(str));
    203284        } else {
    204285            get_buffer(pb, str, str_size);
    205286            str[str_size] = 0;
    206287        }
    207         av_metadata_set2(&c->fc->metadata, key, str, 0);
     288        av_metadata_set2(pm, key, str, 0);
    208289        if (*language && strcmp(language, "und")) {
    209290            snprintf(key2, sizeof(key2), "%s-%s", key, language);
    210             av_metadata_set2(&c->fc->metadata, key2, str, 0);
     291            av_metadata_set2(pm, key2, str, 0);
    211292        }
    212293    }
    213294#ifdef DEBUG_METADATA
    … …  
    17591840    st->codec->codec_type = AVMEDIA_TYPE_DATA;
    17601841    sc->ffindex = st->index;
    17611842
     1843    /* we are at the stream level now */
     1844    c->metadata_ext = c->metadata_ext | META_EXT_STREAM_LEVEL;
     1845
    17621846    if ((ret = mov_read_default(c, pb, atom)) < 0)
    17631847        return ret;
    17641848
    … …  
    18391923    av_freep(&sc->stts_data);
    18401924    av_freep(&sc->stps_data);
    18411925
     1926    c->metadata_ext = c->metadata_ext & ~META_EXT_STREAM_LEVEL;
     1927
    18421928    return 0;
    18431929}
    18441930
    18451931static int mov_read_ilst(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
    18461932{
    18471933    int ret;
    1848     c->itunes_metadata = 1;
     1934    c->metadata_ext = c->metadata_ext | META_EXT_ITUNES_TYPE;
    18491935    ret = mov_read_default(c, pb, atom);
    1850     c->itunes_metadata = 0;
     1936    c->metadata_ext = c->metadata_ext & ~META_EXT_ITUNES_TYPE;
    18511937    return ret;
    18521938}
    18531939
    … …  
    21942280    return 0;
    21952281}
    21962282
     2283/* MP4/H264 variant of bitrate box */
     2284static int mov_read_btrt(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
     2285{
     2286    AVFormatContext* myContext = NULL;
     2287    AVStream* myStream = NULL;
     2288
     2289    int nMaxBitRate = 0;
     2290
     2291    myContext = c->fc;
     2292    get_be32(pb); //buffSize
     2293    nMaxBitRate = get_be32(pb);
     2294    get_be32(pb); // nBitRate
     2295
     2296    if (myContext->nb_streams < 1)
     2297    {
     2298        av_log(myContext, AV_LOG_ERROR,
     2299            "mov_read_btrt() number of streams is 0 ");
     2300        return 0;
     2301    }
     2302    av_log(myContext, AV_LOG_DEBUG,
     2303        "mov_read_btrt() reads nMaxBitRate=%d, \n",
     2304        nMaxBitRate);
     2305
     2306    myStream = myContext->streams[(myContext->nb_streams -1)];
     2307    myStream->codec->rc_max_rate = nMaxBitRate;
     2308
     2309    return 0;
     2310}
     2311
     2312/* H263 specific variant of bitrate box */
     2313static int mov_read_bitr(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
     2314{
     2315    AVFormatContext* myContext = NULL;
     2316    AVStream* myStream = NULL;
     2317
     2318    int nMaxBitRate = 0;
     2319
     2320    myContext = c->fc;
     2321    get_be32(pb); // avgBitRate - we are not interested right now
     2322
     2323    nMaxBitRate = get_be32(pb);
     2324
     2325    if (myContext->nb_streams < 1)
     2326    {
     2327        av_log(myContext, AV_LOG_ERROR,
     2328            "%s(): number of streams is 0 ", __FUNCTION__);
     2329        return 0;
     2330    }
     2331    av_log(myContext, AV_LOG_DEBUG,
     2332        "%s(): reads nMaxBitRate=%d", __FUNCTION__,
     2333        nMaxBitRate);
     2334
     2335    myStream = myContext->streams[(myContext->nb_streams -1)];
     2336    myStream->codec->rc_max_rate = nMaxBitRate;
     2337
     2338    return 0;
     2339}
     2340
     2341
     2342static int mov_read_cmvt(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
     2343{
     2344
     2345    AVFormatContext* myContext = NULL;
     2346    AVStream* myStream = NULL;
     2347    int nNalSize = 0;
     2348    char buffer[8];
     2349
     2350
     2351    myContext = c->fc;
     2352
     2353    nNalSize = get_be32(pb); // NAL Size
     2354    get_be32(pb); // empty
     2355    get_be32(pb); // empty
     2356
     2357    if (myContext->nb_streams < 1)
     2358    {
     2359        av_log(myContext, AV_LOG_ERROR,
     2360            "mov_read_cmvt() number of streams is 0 ");
     2361        return 0;
     2362    }
     2363    av_log(myContext, AV_LOG_DEBUG,
     2364        "mov_read_cmvt() reads nNalSize=%d\n",
     2365        nNalSize);
     2366
     2367    myStream = myContext->streams[(myContext->nb_streams -1)];
     2368    snprintf(buffer, sizeof(buffer), "%d", nNalSize);
     2369    av_metadata_set2(&myStream->metadata, "NALSize", buffer, 0);
     2370
     2371    return 0;
     2372}
     2373
     2374/* Read the H263 decoder info. Usually not very important,
     2375   contrary to avcC in H264 for example */
     2376static int mov_read_d263(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
     2377{
     2378   MOVAtom a = { 0 };
     2379
     2380   url_fskip(pb, 7); /* 7 bytes fixed data of decoder config */
     2381
     2382   /* May have optional bitr box, which we are interested in */
     2383   /* 15 below is:
     2384      7 bytes of decoder data we skipped above + 8 bytes of bitr header */
     2385   if (atom.size > 15)
     2386   {
     2387      a.size = atom.size - 7;
     2388      return mov_read_default(c, pb, a);
     2389   }
     2390   else
     2391   {
     2392      return 0;
     2393   }
     2394}
     2395
    21972396static const MOVParseTableEntry mov_default_parse_table[] = {
    21982397{ MKTAG('a','v','s','s'), mov_read_extradata },
    21992398{ MKTAG('c','h','p','l'), mov_read_chpl },
    … …  
    22212420{ MKTAG('m','v','h','d'), mov_read_mvhd },
    22222421{ MKTAG('S','M','I',' '), mov_read_smi }, /* Sorenson extension ??? */
    22232422{ MKTAG('a','l','a','c'), mov_read_extradata }, /* alac specific atom */
    2224 { MKTAG('a','v','c','C'), mov_read_glbl },
     2423{ MKTAG('a','v','c','C'), mov_read_glbl },  /* H264 decoder config */
     2424{ MKTAG('d','2','6','3'), mov_read_d263 }, /* H263 decoder config */
    22252425{ MKTAG('p','a','s','p'), mov_read_pasp },
    22262426{ MKTAG('s','t','b','l'), mov_read_default },
    22272427{ MKTAG('s','t','c','o'), mov_read_stco },
    … …  
    22462446{ MKTAG('e','s','d','s'), mov_read_esds },
    22472447{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
    22482448{ MKTAG('c','m','o','v'), mov_read_cmov },
     2449{ MKTAG('b','t','r','t'), mov_read_btrt },
     2450{ MKTAG('b','i','t','r'), mov_read_bitr },
     2451{ MKTAG('c','m','v','t'), mov_read_cmvt },
    22492452{ 0, NULL }
    22502453};
    22512454