Revision 1762d9ce ffmpeg.c
ffmpeg.c | ||
---|---|---|
172 | 172 |
static int qp_hist = 0; |
173 | 173 |
#if CONFIG_AVFILTER |
174 | 174 |
static char *vfilters = NULL; |
175 |
static AVFilterGraph *graph = NULL; |
|
176 | 175 |
#endif |
177 | 176 |
|
178 | 177 |
static int intra_only = 0; |
... | ... | |
303 | 302 |
AVAudioConvert *reformat_ctx; |
304 | 303 |
AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */ |
305 | 304 |
FILE *logfile; |
305 |
|
|
306 |
#if CONFIG_AVFILTER |
|
307 |
AVFilterContext *output_video_filter; |
|
308 |
AVFilterContext *input_video_filter; |
|
309 |
AVFilterBufferRef *picref; |
|
310 |
char *avfilter; |
|
311 |
AVFilterGraph *graph; |
|
312 |
#endif |
|
306 | 313 |
} AVOutputStream; |
307 | 314 |
|
308 | 315 |
static AVOutputStream **output_streams_for_file[MAX_FILES] = { NULL }; |
... | ... | |
324 | 331 |
int showed_multi_packet_warning; |
325 | 332 |
int is_past_recording_time; |
326 | 333 |
#if CONFIG_AVFILTER |
327 |
AVFilterContext *output_video_filter; |
|
328 |
AVFilterContext *input_video_filter; |
|
329 | 334 |
AVFrame *filter_frame; |
330 | 335 |
int has_filter_frame; |
331 |
AVFilterBufferRef *picref; |
|
332 | 336 |
#endif |
333 | 337 |
} AVInputStream; |
334 | 338 |
|
... | ... | |
358 | 362 |
char args[255]; |
359 | 363 |
int ret; |
360 | 364 |
|
361 |
graph = avfilter_graph_alloc(); |
|
365 |
ost->graph = avfilter_graph_alloc();
|
|
362 | 366 |
|
363 | 367 |
if (ist->st->sample_aspect_ratio.num){ |
364 | 368 |
sample_aspect_ratio = ist->st->sample_aspect_ratio; |
... | ... | |
369 | 373 |
ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE, |
370 | 374 |
sample_aspect_ratio.num, sample_aspect_ratio.den); |
371 | 375 |
|
372 |
ret = avfilter_graph_create_filter(&ist->input_video_filter, avfilter_get_by_name("buffer"),
|
|
373 |
"src", args, NULL, graph); |
|
376 |
ret = avfilter_graph_create_filter(&ost->input_video_filter, avfilter_get_by_name("buffer"),
|
|
377 |
"src", args, NULL, ost->graph);
|
|
374 | 378 |
if (ret < 0) |
375 | 379 |
return ret; |
376 |
ret = avfilter_graph_create_filter(&ist->output_video_filter, &ffsink,
|
|
377 |
"out", NULL, &ffsink_ctx, graph); |
|
380 |
ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink,
|
|
381 |
"out", NULL, &ffsink_ctx, ost->graph);
|
|
378 | 382 |
if (ret < 0) |
379 | 383 |
return ret; |
380 |
last_filter = ist->input_video_filter;
|
|
384 |
last_filter = ost->input_video_filter;
|
|
381 | 385 |
|
382 | 386 |
if (codec->width != icodec->width || codec->height != icodec->height) { |
383 | 387 |
snprintf(args, 255, "%d:%d:flags=0x%X", |
... | ... | |
385 | 389 |
codec->height, |
386 | 390 |
(int)av_get_int(sws_opts, "sws_flags", NULL)); |
387 | 391 |
if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"), |
388 |
NULL, args, NULL, graph)) < 0) |
|
392 |
NULL, args, NULL, ost->graph)) < 0)
|
|
389 | 393 |
return ret; |
390 | 394 |
if ((ret = avfilter_link(last_filter, 0, filter, 0)) < 0) |
391 | 395 |
return ret; |
... | ... | |
393 | 397 |
} |
394 | 398 |
|
395 | 399 |
snprintf(args, sizeof(args), "flags=0x%X", (int)av_get_int(sws_opts, "sws_flags", NULL)); |
396 |
graph->scale_sws_opts = av_strdup(args); |
|
400 |
ost->graph->scale_sws_opts = av_strdup(args);
|
|
397 | 401 |
|
398 |
if (vfilters) {
|
|
402 |
if (ost->avfilter) {
|
|
399 | 403 |
AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut)); |
400 | 404 |
AVFilterInOut *inputs = av_malloc(sizeof(AVFilterInOut)); |
401 | 405 |
|
... | ... | |
405 | 409 |
outputs->next = NULL; |
406 | 410 |
|
407 | 411 |
inputs->name = av_strdup("out"); |
408 |
inputs->filter_ctx = ist->output_video_filter;
|
|
412 |
inputs->filter_ctx = ost->output_video_filter;
|
|
409 | 413 |
inputs->pad_idx = 0; |
410 | 414 |
inputs->next = NULL; |
411 | 415 |
|
412 |
if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
|
|
416 |
if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, inputs, outputs, NULL)) < 0)
|
|
413 | 417 |
return ret; |
414 |
av_freep(&vfilters);
|
|
418 |
av_freep(&ost->avfilter);
|
|
415 | 419 |
} else { |
416 |
if ((ret = avfilter_link(last_filter, 0, ist->output_video_filter, 0)) < 0)
|
|
420 |
if ((ret = avfilter_link(last_filter, 0, ost->output_video_filter, 0)) < 0)
|
|
417 | 421 |
return ret; |
418 | 422 |
} |
419 | 423 |
|
420 |
if ((ret = avfilter_graph_config(graph, NULL)) < 0) |
|
424 |
if ((ret = avfilter_graph_config(ost->graph, NULL)) < 0)
|
|
421 | 425 |
return ret; |
422 | 426 |
|
423 |
codec->width = ist->output_video_filter->inputs[0]->w;
|
|
424 |
codec->height = ist->output_video_filter->inputs[0]->h;
|
|
427 |
codec->width = ost->output_video_filter->inputs[0]->w;
|
|
428 |
codec->height = ost->output_video_filter->inputs[0]->h;
|
|
425 | 429 |
codec->sample_aspect_ratio = ost->st->sample_aspect_ratio = |
426 |
ist->output_video_filter->inputs[0]->sample_aspect_ratio;
|
|
430 |
ost->output_video_filter->inputs[0]->sample_aspect_ratio;
|
|
427 | 431 |
|
428 | 432 |
return 0; |
429 | 433 |
} |
... | ... | |
1604 | 1608 |
} |
1605 | 1609 |
|
1606 | 1610 |
#if CONFIG_AVFILTER |
1607 |
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->input_video_filter) { |
|
1608 |
AVRational sar; |
|
1609 |
if (ist->st->sample_aspect_ratio.num) sar = ist->st->sample_aspect_ratio; |
|
1610 |
else sar = ist->st->codec->sample_aspect_ratio; |
|
1611 |
// add it to be filtered |
|
1612 |
av_vsrc_buffer_add_frame(ist->input_video_filter, &picture, |
|
1613 |
ist->pts, |
|
1614 |
sar); |
|
1611 |
if(ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ |
|
1612 |
for(i=0;i<nb_ostreams;i++) { |
|
1613 |
ost = ost_table[i]; |
|
1614 |
if (ost->input_video_filter && ost->source_index == ist_index) { |
|
1615 |
AVRational sar; |
|
1616 |
if (ist->st->sample_aspect_ratio.num) sar = ist->st->sample_aspect_ratio; |
|
1617 |
else sar = ist->st->codec->sample_aspect_ratio; |
|
1618 |
// add it to be filtered |
|
1619 |
av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, |
|
1620 |
ist->pts, |
|
1621 |
sar); |
|
1622 |
} |
|
1623 |
} |
|
1615 | 1624 |
} |
1616 | 1625 |
#endif |
1617 | 1626 |
|
... | ... | |
1636 | 1645 |
if (pts > now) |
1637 | 1646 |
usleep(pts - now); |
1638 | 1647 |
} |
1639 |
#if CONFIG_AVFILTER |
|
1640 |
frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || |
|
1641 |
!ist->output_video_filter || avfilter_poll_frame(ist->output_video_filter->inputs[0]); |
|
1642 |
#endif |
|
1643 | 1648 |
/* if output time reached then transcode raw format, |
1644 | 1649 |
encode packets and output them */ |
1645 | 1650 |
if (start_time == 0 || ist->pts >= start_time) |
1646 |
#if CONFIG_AVFILTER |
|
1647 |
while (frame_available) { |
|
1648 |
AVRational ist_pts_tb; |
|
1649 |
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->output_video_filter) |
|
1650 |
get_filtered_video_frame(ist->output_video_filter, &picture, &ist->picref, &ist_pts_tb); |
|
1651 |
if (ist->picref) |
|
1652 |
ist->pts = av_rescale_q(ist->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); |
|
1653 |
#endif |
|
1654 | 1651 |
for(i=0;i<nb_ostreams;i++) { |
1655 | 1652 |
int frame_size; |
1656 | 1653 |
|
1657 | 1654 |
ost = ost_table[i]; |
1658 | 1655 |
if (ost->source_index == ist_index) { |
1656 |
#if CONFIG_AVFILTER |
|
1657 |
frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || |
|
1658 |
!ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]); |
|
1659 |
while (frame_available) { |
|
1660 |
AVRational ist_pts_tb; |
|
1661 |
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) |
|
1662 |
get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb); |
|
1663 |
if (ost->picref) |
|
1664 |
ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); |
|
1665 |
#endif |
|
1659 | 1666 |
os = output_files[ost->file_index]; |
1660 | 1667 |
|
1661 | 1668 |
/* set the input output pts pairs */ |
... | ... | |
1669 | 1676 |
break; |
1670 | 1677 |
case AVMEDIA_TYPE_VIDEO: |
1671 | 1678 |
#if CONFIG_AVFILTER |
1672 |
if (ist->picref->video)
|
|
1673 |
ost->st->codec->sample_aspect_ratio = ist->picref->video->pixel_aspect;
|
|
1679 |
if (ost->picref->video)
|
|
1680 |
ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect;
|
|
1674 | 1681 |
#endif |
1675 | 1682 |
do_video_out(os, ost, ist, &picture, &frame_size); |
1676 | 1683 |
if (vstats_filename && frame_size) |
... | ... | |
1739 | 1746 |
ost->frame_number++; |
1740 | 1747 |
av_free_packet(&opkt); |
1741 | 1748 |
} |
1749 |
#if CONFIG_AVFILTER |
|
1750 |
frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && |
|
1751 |
ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]); |
|
1752 |
if(ost->picref) |
|
1753 |
avfilter_unref_buffer(ost->picref); |
|
1754 |
} |
|
1755 |
#endif |
|
1742 | 1756 |
} |
1743 | 1757 |
} |
1744 | 1758 |
|
1745 |
#if CONFIG_AVFILTER |
|
1746 |
frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && |
|
1747 |
ist->output_video_filter && avfilter_poll_frame(ist->output_video_filter->inputs[0]); |
|
1748 |
if(ist->picref) |
|
1749 |
avfilter_unref_buffer(ist->picref); |
|
1750 |
} |
|
1751 |
#endif |
|
1752 | 1759 |
av_free(buffer_to_free); |
1753 | 1760 |
/* XXX: allocate the subtitles in the codec ? */ |
1754 | 1761 |
if (subtitle_to_free) { |
... | ... | |
2677 | 2684 |
av_freep(&ost->st->codec->stats_in); |
2678 | 2685 |
avcodec_close(ost->st->codec); |
2679 | 2686 |
} |
2687 |
#if CONFIG_AVFILTER |
|
2688 |
avfilter_graph_free(&ost->graph); |
|
2689 |
#endif |
|
2680 | 2690 |
} |
2681 | 2691 |
|
2682 | 2692 |
/* close each decoder */ |
... | ... | |
2686 | 2696 |
avcodec_close(ist->st->codec); |
2687 | 2697 |
} |
2688 | 2698 |
} |
2689 |
#if CONFIG_AVFILTER |
|
2690 |
avfilter_graph_free(&graph); |
|
2691 |
#endif |
|
2692 | 2699 |
|
2693 | 2700 |
/* finished ! */ |
2694 | 2701 |
ret = 0; |
... | ... | |
2831 | 2838 |
ffmpeg_exit(1); |
2832 | 2839 |
} |
2833 | 2840 |
frame_aspect_ratio = ar; |
2834 |
|
|
2835 |
x = vfilters ? strlen(vfilters) : 0; |
|
2836 |
vfilters = av_realloc(vfilters, x+100); |
|
2837 |
snprintf(vfilters+x, x+100, "%csetdar=%f\n", x?',':' ', ar); |
|
2838 | 2841 |
} |
2839 | 2842 |
|
2840 | 2843 |
static int opt_metadata(const char *opt, const char *arg) |
... | ... | |
3376 | 3379 |
AVCodecContext *video_enc; |
3377 | 3380 |
enum CodecID codec_id = CODEC_ID_NONE; |
3378 | 3381 |
AVCodec *codec= NULL; |
3382 |
int i; |
|
3379 | 3383 |
|
3380 | 3384 |
st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); |
3381 | 3385 |
if (!st) { |
... | ... | |
3395 | 3399 |
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); |
3396 | 3400 |
codec = avcodec_find_encoder(codec_id); |
3397 | 3401 |
} |
3402 |
|
|
3403 |
if(frame_aspect_ratio > 0){ |
|
3404 |
i = vfilters ? strlen(vfilters) : 0; |
|
3405 |
vfilters = av_realloc(vfilters, i+100); |
|
3406 |
snprintf(vfilters+i, i+100, "%csetdar=%f\n", i?',':' ', frame_aspect_ratio); |
|
3407 |
frame_aspect_ratio=0; |
|
3408 |
} |
|
3409 |
|
|
3410 |
ost->avfilter= vfilters; |
|
3411 |
vfilters= NULL; |
|
3398 | 3412 |
} |
3399 | 3413 |
|
3400 | 3414 |
avcodec_get_context_defaults3(st->codec, codec); |
Also available in: Unified diff