[FFmpeg-devel] [PATCH]yuv4mpeg: Do not set interlaced_frame

Carl Eugen Hoyos cehoyos at ag.or.at
Tue Jan 29 10:18:33 CET 2013


Hi!

The documentation of interlaced_frame says that it should only be written by 
libavcodec, the yuv4mpeg demuxer currently violates this.

Attached patch fixes this and changes the behaviour on damaged headers 
slightly.

Please review, Carl Eugen
-------------- next part --------------
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index ff039bd..0eaa48c 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -58,6 +58,12 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf)
     inter = 'p'; /* progressive is the default */
     if (st->codec->coded_frame && st->codec->coded_frame->interlaced_frame)
         inter = st->codec->coded_frame->top_field_first ? 't' : 'b';
+    if (st->codec->field_order > AV_FIELD_UNKNOWN)
+        if (st->codec->field_order > AV_FIELD_PROGRESSIVE) {
+            inter = st->codec->field_order == AV_FIELD_TT || st->codec->field_order == AV_FIELD_TB ? 't' : 'b';
+        } else {
+             inter = 'p';
+        }
 
     switch (st->codec->pix_fmt) {
     case AV_PIX_FMT_GRAY8:
@@ -319,7 +325,7 @@ static int yuv4_read_header(AVFormatContext *s)
 {
     char header[MAX_YUV4_HEADER + 10];  // Include headroom for
                                         // the longest option
-    char *tokstart, *tokend, *header_end;
+    char *tokstart, *tokend, *header_end, interlaced = '?';
     int i;
     AVIOContext *pb = s->pb;
     int width = -1, height  = -1, raten   = 0,
@@ -425,28 +431,7 @@ static int yuv4_read_header(AVFormatContext *s)
                 tokstart++;
             break;
         case 'I': // Interlace type
-            switch (*tokstart++){
-            case '?':
-                break;
-            case 'p':
-                s1->interlaced_frame = 0;
-                break;
-            case 't':
-                s1->interlaced_frame = 1;
-                s1->top_field_first = 1;
-                break;
-            case 'b':
-                s1->interlaced_frame = 1;
-                s1->top_field_first = 0;
-                break;
-            case 'm':
-                av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
-                       "interlaced and non-interlaced frames.\n");
-                return -1;
-            default:
-                av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
-                return -1;
-            }
+            interlaced = *tokstart++;
             break;
         case 'F': // Frame rate
             sscanf(tokstart, "%d:%d", &raten, &rated); // 0:0 if unknown
@@ -547,6 +532,27 @@ static int yuv4_read_header(AVFormatContext *s)
     st->sample_aspect_ratio           = (AVRational){ aspectn, aspectd };
     st->codec->chroma_sample_location = chroma_sample_location;
 
+    switch (interlaced){
+    case 'p':
+        st->codec->field_order = AV_FIELD_PROGRESSIVE;
+        break;
+    case 't':
+        st->codec->field_order = AV_FIELD_TT;
+        break;
+    case 'b':
+        st->codec->field_order = AV_FIELD_BB;
+        break;
+    case 'm':
+        av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed "
+               "interlaced and non-interlaced frames.\n");
+    case '?':
+        st->codec->field_order = AV_FIELD_UNKNOWN;
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
+        st->codec->field_order = AV_FIELD_UNKNOWN;
+    }
+
     return 0;
 }
 
@@ -556,7 +562,6 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
     char header[MAX_FRAME_HEADER+1];
     int packet_size, width, height, ret;
     AVStream *st = s->streams[0];
-    struct frame_attributes *s1 = s->priv_data;
 
     for (i = 0; i < MAX_FRAME_HEADER; i++) {
         header[i] = avio_r8(s->pb);
@@ -588,11 +593,6 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt)
     else if (ret != packet_size)
         return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO);
 
-    if (st->codec->coded_frame) {
-        st->codec->coded_frame->interlaced_frame = s1->interlaced_frame;
-        st->codec->coded_frame->top_field_first  = s1->top_field_first;
-    }
-
     pkt->stream_index = 0;
     return 0;
 }


More information about the ffmpeg-devel mailing list