comparison libx264.c @ 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 4f555a34e00f
children 38cfe222e1a4
comparison
equal deleted inserted replaced
9898:003d7f830e2a 9899:06ab8ac1a593
28 28
29 typedef struct X264Context { 29 typedef struct X264Context {
30 x264_param_t params; 30 x264_param_t params;
31 x264_t *enc; 31 x264_t *enc;
32 x264_picture_t pic; 32 x264_picture_t pic;
33 uint8_t *sei;
34 int sei_size;
33 AVFrame out_pic; 35 AVFrame out_pic;
34 } X264Context; 36 } X264Context;
35 37
36 static void 38 static void
37 X264_log(void *p, int level, const char *fmt, va_list args) 39 X264_log(void *p, int level, const char *fmt, va_list args)
49 av_vlog(p, level_map[level], fmt, args); 51 av_vlog(p, level_map[level], fmt, args);
50 } 52 }
51 53
52 54
53 static int 55 static int
54 encode_nals(uint8_t *buf, int size, x264_nal_t *nals, int nnal) 56 encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, x264_nal_t *nals, int nnal, int skip_sei)
55 { 57 {
58 X264Context *x4 = ctx->priv_data;
56 uint8_t *p = buf; 59 uint8_t *p = buf;
57 int i; 60 int i, s;
61
62 /* Write the SEI as part of the first frame. */
63 if(x4->sei_size > 0 && nnal > 0)
64 {
65 memcpy(p, x4->sei, x4->sei_size);
66 p += x4->sei_size;
67 x4->sei_size = 0;
68 }
58 69
59 for(i = 0; i < nnal; i++){ 70 for(i = 0; i < nnal; i++){
60 int s = x264_nal_encode(p, &size, 1, nals + i); 71 /* Don't put the SEI in extradata. */
72 if(skip_sei && nals[i].i_type == NAL_SEI)
73 {
74 x4->sei = av_malloc( 5 + nals[i].i_payload * 4 / 3 );
75 if(x264_nal_encode(x4->sei, &x4->sei_size, 1, nals + i) < 0)
76 return -1;
77 continue;
78 }
79 s = x264_nal_encode(p, &size, 1, nals + i);
61 if(s < 0) 80 if(s < 0)
62 return -1; 81 return -1;
63 p += s; 82 p += s;
64 } 83 }
65 84
90 109
91 if(x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, 110 if(x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL,
92 &pic_out)) 111 &pic_out))
93 return -1; 112 return -1;
94 113
95 bufsize = encode_nals(buf, bufsize, nal, nnal); 114 bufsize = encode_nals(ctx, buf, bufsize, nal, nnal, 0);
96 if(bufsize < 0) 115 if(bufsize < 0)
97 return -1; 116 return -1;
98 117
99 /* FIXME: dts */ 118 /* FIXME: dts */
100 x4->out_pic.pts = pic_out.i_pts; 119 x4->out_pic.pts = pic_out.i_pts;
123 X264_close(AVCodecContext *avctx) 142 X264_close(AVCodecContext *avctx)
124 { 143 {
125 X264Context *x4 = avctx->priv_data; 144 X264Context *x4 = avctx->priv_data;
126 145
127 av_freep(&avctx->extradata); 146 av_freep(&avctx->extradata);
147 av_free(x4->sei);
128 148
129 if(x4->enc) 149 if(x4->enc)
130 x264_encoder_close(x4->enc); 150 x264_encoder_close(x4->enc);
131 151
132 return 0; 152 return 0;
135 static av_cold int 155 static av_cold int
136 X264_init(AVCodecContext *avctx) 156 X264_init(AVCodecContext *avctx)
137 { 157 {
138 X264Context *x4 = avctx->priv_data; 158 X264Context *x4 = avctx->priv_data;
139 159
160 x4->sei_size = 0;
140 x264_param_default(&x4->params); 161 x264_param_default(&x4->params);
141 162
142 x4->params.pf_log = X264_log; 163 x4->params.pf_log = X264_log;
143 x4->params.p_log_private = avctx; 164 x4->params.p_log_private = avctx;
144 165
282 /* 5 bytes NAL header + worst case escaping */ 303 /* 5 bytes NAL header + worst case escaping */
283 for(i = 0; i < nnal; i++) 304 for(i = 0; i < nnal; i++)
284 s += 5 + nal[i].i_payload * 4 / 3; 305 s += 5 + nal[i].i_payload * 4 / 3;
285 306
286 avctx->extradata = av_malloc(s); 307 avctx->extradata = av_malloc(s);
287 avctx->extradata_size = encode_nals(avctx->extradata, s, nal, nnal); 308 avctx->extradata_size = encode_nals(avctx, avctx->extradata, s, nal, nnal, 1);
288 } 309 }
289 310
290 return 0; 311 return 0;
291 } 312 }
292 313