]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/nutenc.c
ffmdec: fix hypothetical overflows
[ffmpeg] / libavformat / nutenc.c
index f719c8ea59df7bd05ba473d7b257db2c79cf3cbb..53ebd74c3cae31f20306541ebdce3e41aaed7e26 100644 (file)
@@ -156,6 +156,19 @@ static void build_frame_code(AVFormatContext *s){
         int is_audio= codec->codec_type == AVMEDIA_TYPE_AUDIO;
         int intra_only= /*codec->intra_only || */is_audio;
         int pred_count;
+        int frame_size = 0;
+
+        if (codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            frame_size = av_get_audio_frame_duration(codec, 0);
+            if (codec->codec_id == AV_CODEC_ID_VORBIS && !frame_size)
+                frame_size = 64;
+        } else {
+            AVRational f = av_div_q(codec->time_base, *nut->stream[stream_id].time_base);
+            if(f.den == 1 && f.num>0)
+                frame_size = f.num;
+        }
+        if(!frame_size)
+            frame_size = 1;
 
         for(key_frame=0; key_frame<2; key_frame++){
             if(intra_only && keyframe_0_esc && key_frame==0)
@@ -185,7 +198,7 @@ static void build_frame_code(AVFormatContext *s){
                     ft->stream_id= stream_id;
                     ft->size_mul=frame_bytes + 2;
                     ft->size_lsb=frame_bytes + pred;
-                    ft->pts_delta=pts;
+                    ft->pts_delta=pts * frame_size;
                     ft->header_idx= find_header_idx(s, codec, frame_bytes + pred, key_frame);
                     start2++;
                 }
@@ -195,7 +208,7 @@ static void build_frame_code(AVFormatContext *s){
             ft->flags= FLAG_KEY | FLAG_SIZE_MSB;
             ft->stream_id= stream_id;
             ft->size_mul=1;
-            ft->pts_delta=1;
+            ft->pts_delta=frame_size;
             start2++;
         }
 #endif
@@ -221,6 +234,8 @@ static void build_frame_code(AVFormatContext *s){
             int start3= start2 + (end2-start2)*pred / pred_count;
             int end3  = start2 + (end2-start2)*(pred+1) / pred_count;
 
+            pred_table[pred] *= frame_size;
+
             for(index=start3; index<end3; index++){
                 FrameCode *ft= &nut->frame_code[index];
                 ft->flags= FLAG_KEY*key_frame;
@@ -476,6 +491,11 @@ static int write_streaminfo(NUTContext *nut, AVIOContext *bc, int stream_id){
         if (st->disposition & ff_nut_dispositions[i].flag)
             count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str);
     }
+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        uint8_t buf[256];
+        snprintf(buf, sizeof(buf), "%d/%d", st->codec->time_base.den, st->codec->time_base.num);
+        count += add_info(dyn_bc, "r_frame_rate", buf);
+    }
     dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
 
     if (count) {
@@ -653,6 +673,12 @@ static int nut_write_header(AVFormatContext *s){
         AVRational time_base;
         ff_parse_specific_params(st->codec, &time_base.den, &ssize, &time_base.num);
 
+        if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->sample_rate) {
+            time_base = (AVRational){1, st->codec->sample_rate};
+        } else {
+            time_base = ff_choose_timebase(s, st, 48000);
+        }
+
         avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
 
         for(j=0; j<nut->time_base_count; j++){
@@ -955,8 +981,5 @@ AVOutputFormat ff_nut_muxer = {
     .write_packet   = nut_write_packet,
     .write_trailer  = nut_write_trailer,
     .flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
-    .codec_tag      = (const AVCodecTag * const []){
-        ff_codec_bmp_tags, ff_nut_video_tags, ff_codec_wav_tags,
-        ff_nut_subtitle_tags, 0
-    },
+    .codec_tag      = ff_nut_codec_tags,
 };