changeset 9899:06ab8ac1a593 libavcodec

Fix libx264.c to not drop SEI userdata from x264 encoder. Most muxers in ffmpeg ignore the SEI if it is placed in extradata, so instead it has to be catted to the front of the first video frame.
author darkshikari
date Tue, 30 Jun 2009 23:45:01 +0000
parents 003d7f830e2a
children 681cf949c1cf
files libx264.c
diffstat 1 files changed, 26 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libx264.c	Tue Jun 30 12:11:29 2009 +0000
+++ b/libx264.c	Tue Jun 30 23:45:01 2009 +0000
@@ -30,6 +30,8 @@
     x264_param_t params;
     x264_t *enc;
     x264_picture_t pic;
+    uint8_t *sei;
+    int sei_size;
     AVFrame out_pic;
 } X264Context;
 
@@ -51,13 +53,30 @@
 
 
 static int
-encode_nals(uint8_t *buf, int size, x264_nal_t *nals, int nnal)
+encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, x264_nal_t *nals, int nnal, int skip_sei)
 {
+    X264Context *x4 = ctx->priv_data;
     uint8_t *p = buf;
-    int i;
+    int i, s;
+
+    /* Write the SEI as part of the first frame. */
+    if(x4->sei_size > 0 && nnal > 0)
+    {
+        memcpy(p, x4->sei, x4->sei_size);
+        p += x4->sei_size;
+        x4->sei_size = 0;
+    }
 
     for(i = 0; i < nnal; i++){
-        int s = x264_nal_encode(p, &size, 1, nals + i);
+        /* Don't put the SEI in extradata. */
+        if(skip_sei && nals[i].i_type == NAL_SEI)
+        {
+            x4->sei = av_malloc( 5 + nals[i].i_payload * 4 / 3 );
+            if(x264_nal_encode(x4->sei, &x4->sei_size, 1, nals + i) < 0)
+                return -1;
+            continue;
+        }
+        s = x264_nal_encode(p, &size, 1, nals + i);
         if(s < 0)
             return -1;
         p += s;
@@ -92,7 +111,7 @@
                            &pic_out))
         return -1;
 
-    bufsize = encode_nals(buf, bufsize, nal, nnal);
+    bufsize = encode_nals(ctx, buf, bufsize, nal, nnal, 0);
     if(bufsize < 0)
         return -1;
 
@@ -125,6 +144,7 @@
     X264Context *x4 = avctx->priv_data;
 
     av_freep(&avctx->extradata);
+    av_free(x4->sei);
 
     if(x4->enc)
         x264_encoder_close(x4->enc);
@@ -137,6 +157,7 @@
 {
     X264Context *x4 = avctx->priv_data;
 
+    x4->sei_size = 0;
     x264_param_default(&x4->params);
 
     x4->params.pf_log = X264_log;
@@ -284,7 +305,7 @@
             s += 5 + nal[i].i_payload * 4 / 3;
 
         avctx->extradata = av_malloc(s);
-        avctx->extradata_size = encode_nals(avctx->extradata, s, nal, nnal);
+        avctx->extradata_size = encode_nals(avctx, avctx->extradata, s, nal, nnal, 1);
     }
 
     return 0;