smooth lines, motion51, opengl pbuffer bit typo, misc fixes
[goodguy/history.git] / cinelerra-5.1 / cinelerra / bdwrite.C
index 56b0b3f795f8b21977f51df36ba3c7204df88805..e70aa69a1503549c5bc1bb03b988e43942a48264 100644 (file)
@@ -2424,13 +2424,14 @@ static int bd_audio_rate(int rate)
 
 static int bd_video_format(int w, int h, int ilace)
 {
-  if( w == 720 && h == 480 && ilace ) return BLURAY_VIDEO_FORMAT_480I;
-  if( w == 720 && h == 576 && ilace ) return BLURAY_VIDEO_FORMAT_576I;
-  if( w == 720 && h == 480 && !ilace ) return BLURAY_VIDEO_FORMAT_480P;
-  if( w == 1920 && h == 1080 && ilace ) return BLURAY_VIDEO_FORMAT_1080I;
-  if( w == 1280 && h == 720 && !ilace ) return BLURAY_VIDEO_FORMAT_720P;
-  if( w == 1920 && h == 1080 && !ilace ) return BLURAY_VIDEO_FORMAT_1080P;
-  if( w == 720 && h == 576 && !ilace ) return BLURAY_VIDEO_FORMAT_576P;
+  if( w ==  720 && h ==  480    &&  ilace   ) return BLURAY_VIDEO_FORMAT_480I;
+  if( w ==  720 && h ==  576    &&  ilace   ) return BLURAY_VIDEO_FORMAT_576I;
+  if( w ==  720 && h ==  480    && !ilace   ) return BLURAY_VIDEO_FORMAT_480P;
+  if( w ==  720 && h ==  576    && !ilace   ) return BLURAY_VIDEO_FORMAT_576P;
+// this seems to be overly restrictive
+  if( w == 1280 && h ==  720 /* && !ilace*/ ) return BLURAY_VIDEO_FORMAT_720P;
+  if( w == 1440 && h == 1080 /* &&  ilace*/ ) return BLURAY_VIDEO_FORMAT_1080I;
+  if( w == 1920 && h == 1080 /* && !ilace*/ ) return BLURAY_VIDEO_FORMAT_1080P;
   fprintf(stderr, "unknown bluray video format %dx%d %silace\n",
     w, h, !ilace ? "not " : "");
   exit(1);
@@ -2458,6 +2459,46 @@ static int bd_aspect_ratio(int w, int h, double ratio)
   exit(1);
 }
 
+static int field_probe(AVFormatContext *fmt_ctx, AVStream *st)
+{
+  AVDictionary *copts = 0;
+  //av_dict_copy(&copts, opts, 0);
+  AVCodecID codec_id = st->codec->codec_id;
+  AVCodec *decoder = avcodec_find_decoder(codec_id);
+  if( avcodec_open2(st->codec, decoder, &copts) < 0 ) {
+    fprintf(stderr,"codec open failed\n");
+    return -1;
+  }
+  av_dict_free(&copts);
+
+  AVFrame *ipic = av_frame_alloc();
+  AVPacket ipkt;
+  av_init_packet(&ipkt);
+  int ilaced = -1;
+  for( int retrys=100; --retrys>=0 && ilaced<0; ) {
+    av_packet_unref(&ipkt);
+    int ret = av_read_frame(fmt_ctx, &ipkt);
+    if( ret == AVERROR_EOF ) break;
+    if( ret != 0 ) continue;
+    if( !ipkt.data ) continue;
+    if( ipkt.stream_index != st->index ) continue;
+    while( ipkt.size > 0 ) {
+      int got_frame = 0;
+      ret = avcodec_decode_video2(st->codec, ipic, &got_frame, &ipkt);
+      if( ret <= 0 ) break;
+      if( got_frame ) {
+        ilaced = ipic->interlaced_frame ? 1 : 0;
+        break;
+      }
+      ipkt.data += ret;
+      ipkt.size -= ret;
+    }
+  }
+  av_packet_unref(&ipkt);
+  av_frame_free(&ipic);
+  return ilaced;
+}
+
 int media_info::scan()
 {
   struct stat st;
@@ -2492,8 +2533,12 @@ int media_info::scan()
     case AVMEDIA_TYPE_VIDEO: {
       if( ep_pid < 0 ) ep_pid = st->id;
       s->coding_type = bd_stream_type(codec_id);
-      s->format = bd_video_format(st->codec->width, st->codec->height,
-               st->codec->flags & CODEC_FLAG_INTERLACED_ME);
+      int ilace = field_probe(fmt_ctx, st);
+      if( ilace < 0 ) {
+        fprintf(stderr, "interlace probe failed\n");
+        exit(1);
+      }
+      s->format = bd_video_format(st->codec->width, st->codec->height, ilace);
       s->rate = bd_video_rate(!st->codec->framerate.den ? 0 :
                (double)st->codec->framerate.num / st->codec->framerate.den);
       s->aspect = bd_aspect_ratio(st->codec->width, st->codec->height,
@@ -2602,7 +2647,18 @@ int media_info::scan(AVFormatContext *fmt_ctx)
   int ret = 0;
   AVPacket ipkt;
   av_init_packet(&ipkt);
-
+#if 0
+// zero pts at pos zero
+  for( int i=0; i<programs.size(); ++i ) {
+    program *p = programs[i];
+    for( int j=0; j<p->strm_idx.size(); ++j ) {
+      stream *sp = streams[p->strm_idx[j]];
+      sp->last_pts = 0;
+      AVStream *st = fmt_ctx->streams[sp->av_idx];
+      p->add_label(0, 0, 0, st->id);
+    }
+  }
+#endif
   for( int64_t count=0; ret>=0; ++count ) {
     av_packet_unref(&ipkt);
     ipkt.data = 0; ipkt.size = 0;