Browse code

ffmpeg: port sub2video to AVFrame.

And re-enable the FATE test.

Nicolas George authored on 2013/03/10 19:51:02
Showing 4 changed files
... ...
@@ -168,7 +168,20 @@ static int restore_tty;
168 168
    This is a temporary solution until libavfilter gets real subtitles support.
169 169
  */
170 170
 
171
+static int sub2video_get_blank_frame(InputStream *ist)
172
+{
173
+    int ret;
174
+    AVFrame *frame = ist->sub2video.frame;
171 175
 
176
+    av_frame_unref(frame);
177
+    ist->sub2video.frame->width  = ist->sub2video.w;
178
+    ist->sub2video.frame->height = ist->sub2video.h;
179
+    ist->sub2video.frame->format = AV_PIX_FMT_RGB32;
180
+    if ((ret = av_frame_get_buffer(frame, 32)) < 0)
181
+        return ret;
182
+    memset(frame->data[0], 0, frame->height * frame->linesize[0]);
183
+    return 0;
184
+}
172 185
 
173 186
 static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
174 187
                                 AVSubtitleRect *r)
... ...
@@ -201,28 +214,25 @@ static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
201 201
 
202 202
 static void sub2video_push_ref(InputStream *ist, int64_t pts)
203 203
 {
204
-    AVFilterBufferRef *ref = ist->sub2video.ref;
204
+    AVFrame *frame = ist->sub2video.frame;
205 205
     int i;
206 206
 
207
-    ist->sub2video.last_pts = ref->pts = pts;
207
+    av_assert1(frame->data[0]);
208
+    ist->sub2video.last_pts = frame->pts = pts;
208 209
     for (i = 0; i < ist->nb_filters; i++)
209
-        av_buffersrc_add_ref(ist->filters[i]->filter,
210
-                             avfilter_ref_buffer(ref, ~0),
211
-                             AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
212
-                             AV_BUFFERSRC_FLAG_NO_COPY |
213
-                             AV_BUFFERSRC_FLAG_PUSH);
210
+        av_buffersrc_write_frame(ist->filters[i]->filter, frame);
214 211
 }
215 212
 
216 213
 static void sub2video_update(InputStream *ist, AVSubtitle *sub)
217 214
 {
218 215
     int w = ist->sub2video.w, h = ist->sub2video.h;
219
-    AVFilterBufferRef *ref = ist->sub2video.ref;
216
+    AVFrame *frame = ist->sub2video.frame;
220 217
     int8_t *dst;
221 218
     int     dst_linesize;
222 219
     int num_rects, i;
223 220
     int64_t pts, end_pts;
224 221
 
225
-    if (!ref)
222
+    if (!frame)
226 223
         return;
227 224
     if (sub) {
228 225
         pts       = av_rescale_q(sub->pts + sub->start_display_time * 1000,
... ...
@@ -235,9 +245,13 @@ static void sub2video_update(InputStream *ist, AVSubtitle *sub)
235 235
         end_pts   = INT64_MAX;
236 236
         num_rects = 0;
237 237
     }
238
-    dst          = ref->data    [0];
239
-    dst_linesize = ref->linesize[0];
240
-    memset(dst, 0, h * dst_linesize);
238
+    if (sub2video_get_blank_frame(ist) < 0) {
239
+        av_log(ist->st->codec, AV_LOG_ERROR,
240
+               "Impossible to get a blank canvas.\n");
241
+        return;
242
+    }
243
+    dst          = frame->data    [0];
244
+    dst_linesize = frame->linesize[0];
241 245
     for (i = 0; i < num_rects; i++)
242 246
         sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]);
243 247
     sub2video_push_ref(ist, pts);
... ...
@@ -256,7 +270,7 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts)
256 256
        (possibly overlay) is desperately waiting for a subtitle frame. */
257 257
     for (i = 0; i < infile->nb_streams; i++) {
258 258
         InputStream *ist2 = input_streams[infile->ist_index + i];
259
-        if (!ist2->sub2video.ref)
259
+        if (!ist2->sub2video.frame)
260 260
             continue;
261 261
         /* subtitles seem to be usually muxed ahead of other streams;
262 262
            if not, substracting a larger time here is necessary */
... ...
@@ -264,7 +278,7 @@ static void sub2video_heartbeat(InputStream *ist, int64_t pts)
264 264
         /* do not send the heartbeat frame if the subtitle is already ahead */
265 265
         if (pts2 <= ist2->sub2video.last_pts)
266 266
             continue;
267
-        if (pts2 >= ist2->sub2video.end_pts)
267
+        if (pts2 >= ist2->sub2video.end_pts || !ist2->sub2video.frame->data[0])
268 268
             sub2video_update(ist2, NULL);
269 269
         for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++)
270 270
             nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter);
... ...
@@ -466,7 +480,7 @@ static void exit_program(void)
466 466
         av_dict_free(&input_streams[i]->opts);
467 467
         free_buffer_pool(&input_streams[i]->buffer_pool);
468 468
         avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
469
-        avfilter_unref_bufferp(&input_streams[i]->sub2video.ref);
469
+        avcodec_free_frame(&input_streams[i]->sub2video.frame);
470 470
         av_freep(&input_streams[i]->filters);
471 471
         av_freep(&input_streams[i]);
472 472
     }
... ...
@@ -255,7 +255,7 @@ typedef struct InputStream {
255 255
     struct sub2video {
256 256
         int64_t last_pts;
257 257
         int64_t end_pts;
258
-        AVFilterBufferRef *ref;
258
+        AVFrame *frame;
259 259
         int w, h;
260 260
     } sub2video;
261 261
 
... ...
@@ -501,9 +501,7 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
501 501
 static int sub2video_prepare(InputStream *ist)
502 502
 {
503 503
     AVFormatContext *avf = input_files[ist->file_index]->ctx;
504
-    int i, ret, w, h;
505
-    uint8_t *image[4];
506
-    int linesize[4];
504
+    int i, w, h;
507 505
 
508 506
     /* Compute the size of the canvas for the subtitles stream.
509 507
        If the subtitles codec has set a size, use it. Otherwise use the
... ...
@@ -530,17 +528,9 @@ static int sub2video_prepare(InputStream *ist)
530 530
        palettes for all rectangles are identical or compatible */
531 531
     ist->resample_pix_fmt = ist->st->codec->pix_fmt = AV_PIX_FMT_RGB32;
532 532
 
533
-    ret = av_image_alloc(image, linesize, w, h, AV_PIX_FMT_RGB32, 32);
534
-    if (ret < 0)
535
-        return ret;
536
-    memset(image[0], 0, h * linesize[0]);
537
-    ist->sub2video.ref = avfilter_get_video_buffer_ref_from_arrays(
538
-            image, linesize, AV_PERM_READ | AV_PERM_PRESERVE,
539
-            w, h, AV_PIX_FMT_RGB32);
540
-    if (!ist->sub2video.ref) {
541
-        av_free(image[0]);
533
+    ist->sub2video.frame = av_frame_alloc();
534
+    if (!ist->sub2video.frame)
542 535
         return AVERROR(ENOMEM);
543
-    }
544 536
     return 0;
545 537
 }
546 538
 
... ...
@@ -22,7 +22,7 @@ fate-force_key_frames: CMD = enc_dec \
22 22
   avi "-c mpeg4 -g 240 -qscale 10 -force_key_frames 0.5,0:00:01.5" \
23 23
   framecrc "" "" "-skip_frame nokey"
24 24
 
25
-#FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER OVERLAY_FILTER DVDSUB_ENCODER) += fate-sub2video
25
+FATE_SAMPLES_FFMPEG-$(call ALLYES, VOBSUB_DEMUXER DVDSUB_DECODER AVFILTER OVERLAY_FILTER DVDSUB_ENCODER) += fate-sub2video
26 26
 fate-sub2video: tests/data/vsynth2.yuv
27 27
 fate-sub2video: CMD = framecrc \
28 28
   -f rawvideo -r 5 -s 352x288 -pix_fmt yuv420p -i tests/data/vsynth2.yuv \