[FFmpeg-devel] [PATCH] libavformat/gxfenc.c: fix the field number in the media_preamble for video

Thierry Foucu tfoucu
Fri Feb 13 22:01:28 CET 2009


Hi,

This patch includes 2 changes:
   - rename nb_frames to nb_fields, as we are using it to count the number
of video field and not frame
   - for the media preamble, the SMPTE 360 clause 6.4.2.1.3 says:
        "For video media, the field number shall be the number of a single
field or frame. If the video is frame-encoded, the frame numbers (time line
locations) shall be represented by even field numbers."
         However, the function av_rescale_rnd could return a odd number for
NTSC video. So for video, let's use the nb_field from GXFContext
-------------- next part --------------
Index: libavformat/gxfenc.c
===================================================================
--- libavformat/gxfenc.c	(revision 17212)
+++ libavformat/gxfenc.c	(working copy)
@@ -50,7 +50,7 @@
 } GXFStreamContext;
 
 typedef struct GXFContext {
-    uint32_t nb_frames;
+    uint32_t nb_fields;
     uint32_t material_flags;
     uint16_t audio_tracks;
     uint16_t mpeg_tracks;
@@ -296,7 +296,7 @@
     /* last field */
     put_byte(pb, MAT_LAST_FIELD);
     put_byte(pb, 4);
-    put_be32(pb, ctx->nb_frames);
+    put_be32(pb, ctx->nb_fields);
 
     /* reserved */
     put_byte(pb, MAT_MARK_IN);
@@ -305,7 +305,7 @@
 
     put_byte(pb, MAT_MARK_OUT);
     put_byte(pb, 4);
-    put_be32(pb, ctx->nb_frames);
+    put_be32(pb, ctx->nb_fields);
 
     /* estimated size */
     put_byte(pb, MAT_SIZE);
@@ -365,16 +365,16 @@
 {
     // XXX drop frame
     uint32_t timecode =
-        ctx->nb_frames / (ctx->sample_rate * 3600) % 24 << 24 | // hours
-        ctx->nb_frames / (ctx->sample_rate * 60) % 60   << 16 | // minutes
-        ctx->nb_frames / ctx->sample_rate % 60          <<  8 | // seconds
-        ctx->nb_frames % ctx->sample_rate;                    // fields
+        ctx->nb_fields / (ctx->sample_rate * 3600) % 24 << 24 | // hours
+        ctx->nb_fields / (ctx->sample_rate * 60) % 60   << 16 | // minutes
+        ctx->nb_fields / ctx->sample_rate % 60          <<  8 | // seconds
+        ctx->nb_fields % ctx->sample_rate;                    // fields
 
     put_le32(pb, ctx->flags);
-    put_le32(pb, ctx->nb_frames); /* length of the longest track */
-    put_le32(pb, ctx->nb_frames); /* length of the shortest track */
+    put_le32(pb, ctx->nb_fields); /* length of the longest track */
+    put_le32(pb, ctx->nb_fields); /* length of the shortest track */
     put_le32(pb, 0); /* mark in */
-    put_le32(pb, ctx->nb_frames); /* mark out */
+    put_le32(pb, ctx->nb_fields); /* mark out */
     put_le32(pb, 0); /* timecode mark in */
     put_le32(pb, timecode); /* timecode mark out */
     put_le64(pb, ctx->fc->timestamp); /* modification time */
@@ -520,10 +520,10 @@
         put_le16(pb, sc->media_info);
         put_le16(pb, 0); /* reserved */
         put_le16(pb, 0); /* reserved */
-        put_le32(pb, ctx->nb_frames);
+        put_le32(pb, ctx->nb_fields);
         put_le32(pb, 0); /* attributes rw, ro */
         put_le32(pb, 0); /* mark in */
-        put_le32(pb, ctx->nb_frames); /* mark out */
+        put_le32(pb, ctx->nb_fields); /* mark out */
         strncpy(buffer, ES_NAME_PATTERN, path_size);
         put_buffer(pb, (uint8_t *)buffer, path_size);
         put_be16(pb, sc->media_info);
@@ -728,11 +728,17 @@
 static int gxf_write_media_preamble(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt, int size)
 {
     GXFStreamContext *sc = ctx->fc->streams[pkt->stream_index]->priv_data;
-    int64_t dts = av_rescale_rnd(pkt->dts, ctx->sample_rate, sc->codec->time_base.den, AV_ROUND_UP);
+    int64_t field_nb = av_rescale_rnd(pkt->dts, ctx->sample_rate, sc->codec->time_base.den, AV_ROUND_UP);
 
+    /* If the video is frame-encoded, the frame numbers shall be represented by
+     * even field numbers.
+     * see SMPTE360M-2004  6.4.2.1.3 Media field number */
+    if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
+       field_nb = ctx->nb_fields;
+    }
     put_byte(pb, sc->media_type);
     put_byte(pb, sc->index);
-    put_be32(pb, dts);
+    put_be32(pb, field_nb);
     if (sc->codec->codec_type == CODEC_TYPE_AUDIO) {
         put_be16(pb, 0);
         put_be16(pb, size / 2);
@@ -754,7 +760,7 @@
         put_be24(pb, 0);
     } else
         put_be32(pb, size);
-    put_be32(pb, dts);
+    put_be32(pb, field_nb);
     put_byte(pb, 1); /* flags */
     put_byte(pb, 0); /* reserved */
     return 16;
@@ -776,7 +782,7 @@
     gxf_write_padding(pb, padding);
 
     if (sc->codec->codec_type == CODEC_TYPE_VIDEO)
-        ctx->nb_frames += 2; // count fields
+        ctx->nb_fields += 2; // count fields
 
     return updatePacketSize(pb, pos);
 }



More information about the ffmpeg-devel mailing list