Ticket #551: movenc.c.diff

File movenc.c.diff, 7.9 KB (added by ilevin, 5 years ago)
  • movenc.c

    old new  
    2020 * License along with FFmpeg; if not, write to the Free Software 
    2121 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
    2222 */ 
     23//------------------------------------------------------Modifications History 
     24// DATE       DESCRIPTION 
     25// 06/09/2011 Resolution update for H264 reimplementation. 
     26// 05/27/2011 Added writing 'btrt' bitrate info box in H263 
     27// 03/07/2011 Write the AVCodecContext image size values to 
     28//            output file. 
     29// 02/28/2011 added support for max NAL size 
     30// 02/17/2011 Fixed handling of no data AMR frames 
     31// 02-22-2011 added support for max bitrate 
    2332 
    2433#include "movenc.h" 
    2534#include "avformat.h" 
     
    473482    return updateSize(pb, pos); 
    474483} 
    475484 
    476 static int mov_write_d263_tag(ByteIOContext *pb) 
     485/* Writes optional H263 specific 'bitr' box */ 
     486static int mov_write_bitr_tag(ByteIOContext *pb, MOVTrack *track) 
    477487{ 
    478     put_be32(pb, 0xf); /* size */ 
     488    put_be32(pb, 16); 
     489    put_tag(pb, "bitr"); 
     490 
     491    if( (track->enc->rc_max_rate != track->enc->rc_min_rate) || 
     492        (track->enc->rc_min_rate==0) ) 
     493        put_be32(pb, 0); // vbr 
     494    else 
     495        put_be32(pb, track->enc->rc_max_rate); // avg bitrate 
     496 
     497    put_be32(pb, track->enc->rc_max_rate);  
     498     
     499    return 16; 
     500} 
     501 
     502static int mov_write_d263_tag(ByteIOContext *pb, MOVTrack *track) 
     503{ 
     504    int64_t pos = url_ftell(pb); 
     505 
     506    put_be32(pb, 0); /* size placeholder */ 
    479507    put_tag(pb, "d263"); 
    480508    put_tag(pb, "FFMP"); 
    481509    put_byte(pb, 0); /* decoder version */ 
    482510    /* FIXME use AVCodecContext level/profile, when encoder will set values */ 
    483511    put_byte(pb, 0xa); /* level */ 
    484512    put_byte(pb, 0); /* profile */ 
    485     return 0xf; 
     513 
     514    /* Write optional H263 specific 'bitr' box, which holds 
     515       the bitrate info */ 
     516    mov_write_bitr_tag(pb, track); 
     517 
     518    return updateSize(pb, pos); 
    486519} 
    487520 
    488521/* TODO: No idea about these values */ 
     
    744777    return updateSize(pb, pos); 
    745778} 
    746779 
     780// Write the optional MP4 'btrt' box, in H264 case it comes after avcC 
     781// inside avc1. Not suitable for H263, which has its own special 'bitr' box. 
     782static int mov_write_btrt_tag(ByteIOContext *pb, MOVTrack *track) 
     783{ 
     784    put_be32(pb, 20); 
     785    put_tag(pb, "btrt"); 
     786    put_be32(pb,  track->enc->rc_buffer_size); // Buffersize DB (32 bits) 
     787 
     788    put_be32(pb, track->enc->rc_max_rate);  
     789    if( (track->enc->rc_max_rate != track->enc->rc_min_rate) || 
     790        (track->enc->rc_min_rate==0) ) 
     791        put_be32(pb, 0); // vbr 
     792    else 
     793        put_be32(pb, track->enc->rc_max_rate); // avg bitrate 
     794 
     795    return 20; 
     796} 
     797 
     798// Write the non-standard 'cmvt' box at "stsd" level 
     799static int mov_write_cmvt_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st) 
     800{ 
     801    AVMetadataTag *pAVMetadataTag = NULL; 
     802    int nNalSize = 0; 
     803    if ( NULL == st ) 
     804    { 
     805        av_log(NULL, AV_LOG_ERROR, 
     806             "mov_write_cmvt_tag() st is NULL !!!\n"); 
     807        return 0; 
     808    } 
     809    if ( NULL ==st->metadata ) 
     810    { 
     811        av_log(NULL, AV_LOG_ERROR, 
     812             "mov_write_cmvt_tag() st->metadata is NULL !!!\n"); 
     813    } 
     814    pAVMetadataTag = av_metadata_get(st->metadata, "NALSize", NULL, 0); 
     815 
     816    if (!pAVMetadataTag || !strlen(pAVMetadataTag->value)) 
     817    { 
     818        av_log(NULL, AV_LOG_ERROR, 
     819            "mov_write_cmvt_tag() pAVMetadataTag is NULL or bad value\n"); 
     820        return 0; 
     821    } 
     822    nNalSize = atoi(pAVMetadataTag->value); 
     823    put_be32(pb, 20); 
     824    put_tag(pb, "cmvt"); 
     825    put_be32(pb, nNalSize); // NAL size (32 bits) 
     826    put_be32(pb, 0); // empty 
     827    put_be32(pb, 0); // empty 
     828    return 20; 
     829} 
     830 
    747831static int mov_write_video_tag(ByteIOContext *pb, MOVTrack *track) 
    748832{ 
    749833    int64_t pos = url_ftell(pb); 
     
    771855        put_be32(pb, 0); /* Reserved */ 
    772856        put_be32(pb, 0); /* Reserved */ 
    773857    } 
    774     put_be16(pb, track->enc->width); /* Video width */ 
    775     put_be16(pb, track->height); /* Video height */ 
     858 
     859    put_be16(pb, track->enc->width); /* Video width - for it 'enc' is always used */ 
     860    /* Video height - in most cases should be the same as 'enc'. 
     861       If explicitly updating picture size after mov_write_header,  
     862       make sure to call cms_mov_update_dimensions(). */ 
     863    put_be16(pb, track->height);  
     864 
    776865    put_be32(pb, 0x00480000); /* Horizontal resolution 72dpi */ 
    777866    put_be32(pb, 0x00480000); /* Vertical resolution 72dpi */ 
    778867    put_be32(pb, 0); /* Data size (= 0) */ 
     
    792881    put_be16(pb, 0xffff); /* Reserved */ 
    793882    if(track->tag == MKTAG('m','p','4','v')) 
    794883        mov_write_esds_tag(pb, track); 
    795     else if(track->enc->codec_id == CODEC_ID_H263) 
    796         mov_write_d263_tag(pb); 
     884    else if (track->enc->codec_id == CODEC_ID_H263) 
     885    { 
     886        mov_write_d263_tag(pb, track); 
     887    } 
    797888    else if(track->enc->codec_id == CODEC_ID_SVQ3) 
    798889        mov_write_svq3_tag(pb); 
    799890    else if(track->enc->codec_id == CODEC_ID_DNXHD) 
    800891        mov_write_avid_tag(pb, track); 
    801892    else if(track->enc->codec_id == CODEC_ID_H264) { 
    802893        mov_write_avcc_tag(pb, track); 
     894        mov_write_btrt_tag(pb, track); 
    803895        if(track->mode == MODE_IPOD) 
    804896            mov_write_uuid_tag_ipod(pb); 
    805897    } else if(track->vosLen > 0) 
     
    12661358    if (track->tref_tag) 
    12671359        mov_write_tref_tag(pb, track); 
    12681360    mov_write_mdia_tag(pb, track); 
     1361    if ( st && st->codec && CODEC_ID_H264 == st->codec->codec_id) 
     1362        mov_write_cmvt_tag(pb, track, st); 
    12691363    if (track->mode == MODE_PSP) 
    12701364        mov_write_uuid_tag_psp(pb,track);  // PSP Movies require this uuid box 
    12711365    if (track->tag == MKTAG('r','t','p',' ')) 
     
    21802281    return res; 
    21812282} 
    21822283 
     2284/* That function is used to update video resolution after mov_write_header. */ 
     2285int cms_mov_update_dimensions(AVFormatContext *s, int streamNumber, 
     2286                              unsigned int imageWidthInPixels,  
     2287                              unsigned int imageHeightInPixels,  
     2288                              AVRational *sampleAspectRatio) 
     2289{ 
     2290    MOVMuxContext *mov; 
     2291    MOVTrack *track; 
     2292 
     2293    if ((s == NULL) || (streamNumber >= s->nb_streams)) 
     2294    { 
     2295        // inexistent stream 
     2296        av_log(s, AV_LOG_ERROR, "Stream %d does not exist\n", 
     2297               streamNumber); 
     2298        return -1; 
     2299    } 
     2300 
     2301    if (s->streams[streamNumber]->codec->codec_type != AVMEDIA_TYPE_VIDEO) 
     2302    { 
     2303        // We only update resolution for video streams 
     2304        av_log(s, AV_LOG_ERROR, "Stream %d is not video\n", 
     2305               streamNumber); 
     2306        return -2; 
     2307    } 
     2308 
     2309    // Internal, .mov specific parts 
     2310    mov = s->priv_data; 
     2311 
     2312    if (!mov) 
     2313    { 
     2314        av_log(s, AV_LOG_ERROR, "MOV context does not exist\n"); 
     2315        return -3; 
     2316    } 
     2317 
     2318    track = &mov->tracks[streamNumber]; 
     2319 
     2320    if (!track) 
     2321    { 
     2322        av_log(s, AV_LOG_ERROR, "MOV track %d does not exist\n", 
     2323               streamNumber); 
     2324        return -4; 
     2325    } 
     2326 
     2327    /* Special handling for D-10/IMX */ 
     2328    if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') || 
     2329        track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') || 
     2330        track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n'))  
     2331    { 
     2332        if ((imageWidthInPixels != 720) ||  
     2333            ((imageHeightInPixels != 608) && (imageHeightInPixels != 512))) 
     2334        { 
     2335           av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n"); 
     2336           return -5; 
     2337        } 
     2338         
     2339        track->height = track->tag>>24 == 'n' ? 486 : 576; 
     2340    } 
     2341    else 
     2342    { 
     2343        track->height = imageHeightInPixels; 
     2344    } 
     2345 
     2346    // High level (visible outside) parts 
     2347    s->streams[streamNumber]->codec->width = imageWidthInPixels; 
     2348    s->streams[streamNumber]->codec->height = imageHeightInPixels; 
     2349    s->streams[streamNumber]->sample_aspect_ratio = *sampleAspectRatio; 
     2350    s->streams[streamNumber]->codec->sample_aspect_ratio = *sampleAspectRatio; 
     2351 
     2352    return 0; 
     2353} 
     2354 
    21832355#if CONFIG_MOV_MUXER 
    21842356AVOutputFormat mov_muxer = { 
    21852357    "mov",