Originally committed as revision 25520 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -787,4 +787,26 @@ AVFilter ffsink = {
|
| 787 | 787 |
.outputs = (AVFilterPad[]) {{ .name = NULL }},
|
| 788 | 788 |
}; |
| 789 | 789 |
|
| 790 |
+int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame, |
|
| 791 |
+ AVFilterBufferRef **picref_ptr, AVRational *tb) |
|
| 792 |
+{
|
|
| 793 |
+ int ret; |
|
| 794 |
+ AVFilterBufferRef *picref; |
|
| 795 |
+ |
|
| 796 |
+ if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0) |
|
| 797 |
+ return ret; |
|
| 798 |
+ if (!(picref = ctx->inputs[0]->cur_buf)) |
|
| 799 |
+ return AVERROR(ENOENT); |
|
| 800 |
+ *picref_ptr = picref; |
|
| 801 |
+ ctx->inputs[0]->cur_buf = NULL; |
|
| 802 |
+ *tb = ctx->inputs[0]->time_base; |
|
| 803 |
+ |
|
| 804 |
+ memcpy(frame->data, picref->data, sizeof(frame->data)); |
|
| 805 |
+ memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize)); |
|
| 806 |
+ frame->interlaced_frame = picref->video->interlaced; |
|
| 807 |
+ frame->top_field_first = picref->video->top_field_first; |
|
| 808 |
+ |
|
| 809 |
+ return 1; |
|
| 810 |
+} |
|
| 811 |
+ |
|
| 790 | 812 |
#endif /* CONFIG_AVFILTER */ |
| ... | ... |
@@ -270,6 +270,15 @@ typedef struct {
|
| 270 | 270 |
|
| 271 | 271 |
extern AVFilter ffsink; |
| 272 | 272 |
|
| 273 |
+/** |
|
| 274 |
+ * Extract a frame from sink. |
|
| 275 |
+ * |
|
| 276 |
+ * @return a negative error in case of failure, 1 if one frame has |
|
| 277 |
+ * been extracted successfully. |
|
| 278 |
+ */ |
|
| 279 |
+int get_filtered_video_frame(AVFilterContext *sink, AVFrame *frame, |
|
| 280 |
+ AVFilterBufferRef **picref, AVRational *pts_tb); |
|
| 281 |
+ |
|
| 273 | 282 |
#endif /* CONFIG_AVFILTER */ |
| 274 | 283 |
|
| 275 | 284 |
#endif /* FFMPEG_CMDUTILS_H */ |
| ... | ... |
@@ -324,29 +324,6 @@ static struct termios oldtty; |
| 324 | 324 |
|
| 325 | 325 |
#if CONFIG_AVFILTER |
| 326 | 326 |
|
| 327 |
-static int get_filtered_video_pic(AVFilterContext *ctx, |
|
| 328 |
- AVFilterBufferRef **picref, AVFrame *pic2, |
|
| 329 |
- uint64_t *pts) |
|
| 330 |
-{
|
|
| 331 |
- AVFilterBufferRef *pic; |
|
| 332 |
- |
|
| 333 |
- if(avfilter_request_frame(ctx->inputs[0])) |
|
| 334 |
- return -1; |
|
| 335 |
- if(!(pic = ctx->inputs[0]->cur_buf)) |
|
| 336 |
- return -1; |
|
| 337 |
- *picref = pic; |
|
| 338 |
- ctx->inputs[0]->cur_buf = NULL; |
|
| 339 |
- |
|
| 340 |
- *pts = pic->pts; |
|
| 341 |
- |
|
| 342 |
- memcpy(pic2->data, pic->data, sizeof(pic->data)); |
|
| 343 |
- memcpy(pic2->linesize, pic->linesize, sizeof(pic->linesize)); |
|
| 344 |
- pic2->interlaced_frame = pic->video->interlaced; |
|
| 345 |
- pic2->top_field_first = pic->video->top_field_first; |
|
| 346 |
- |
|
| 347 |
- return 1; |
|
| 348 |
-} |
|
| 349 |
- |
|
| 350 | 327 |
static int configure_filters(AVInputStream *ist, AVOutputStream *ost) |
| 351 | 328 |
{
|
| 352 | 329 |
AVFilterContext *last_filter, *filter; |
| ... | ... |
@@ -1600,8 +1577,11 @@ static int output_packet(AVInputStream *ist, int ist_index, |
| 1600 | 1600 |
if (start_time == 0 || ist->pts >= start_time) |
| 1601 | 1601 |
#if CONFIG_AVFILTER |
| 1602 | 1602 |
while (frame_available) {
|
| 1603 |
+ AVRational ist_pts_tb; |
|
| 1603 | 1604 |
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ist->output_video_filter) |
| 1604 |
- get_filtered_video_pic(ist->output_video_filter, &ist->picref, &picture, &ist->pts); |
|
| 1605 |
+ get_filtered_video_frame(ist->output_video_filter, &picture, &ist->picref, &ist_pts_tb); |
|
| 1606 |
+ if (ist->picref) |
|
| 1607 |
+ ist->pts = ist->picref->pts; |
|
| 1605 | 1608 |
#endif |
| 1606 | 1609 |
for(i=0;i<nb_ostreams;i++) {
|
| 1607 | 1610 |
int frame_size; |
| ... | ... |
@@ -1779,27 +1779,6 @@ static AVFilter input_filter = |
| 1779 | 1779 |
{ .name = NULL }},
|
| 1780 | 1780 |
}; |
| 1781 | 1781 |
|
| 1782 |
-static int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame, |
|
| 1783 |
- int64_t *pts, AVRational *tb, int64_t *pos) |
|
| 1784 |
-{
|
|
| 1785 |
- AVFilterBufferRef *pic; |
|
| 1786 |
- |
|
| 1787 |
- if(avfilter_request_frame(ctx->inputs[0])) |
|
| 1788 |
- return -1; |
|
| 1789 |
- if(!(pic = ctx->inputs[0]->cur_buf)) |
|
| 1790 |
- return -1; |
|
| 1791 |
- ctx->inputs[0]->cur_buf = NULL; |
|
| 1792 |
- |
|
| 1793 |
- frame->opaque = pic; |
|
| 1794 |
- *pts = pic->pts; |
|
| 1795 |
- *pos = pic->pos; |
|
| 1796 |
- *tb = ctx->inputs[0]->time_base; |
|
| 1797 |
- |
|
| 1798 |
- memcpy(frame->data, pic->data, sizeof(frame->data)); |
|
| 1799 |
- memcpy(frame->linesize, pic->linesize, sizeof(frame->linesize)); |
|
| 1800 |
- |
|
| 1801 |
- return 1; |
|
| 1802 |
-} |
|
| 1803 | 1782 |
#endif /* CONFIG_AVFILTER */ |
| 1804 | 1783 |
|
| 1805 | 1784 |
static int video_thread(void *arg) |
| ... | ... |
@@ -1859,12 +1838,18 @@ static int video_thread(void *arg) |
| 1859 | 1859 |
#if !CONFIG_AVFILTER |
| 1860 | 1860 |
AVPacket pkt; |
| 1861 | 1861 |
#else |
| 1862 |
+ AVFilterBufferRef *picref; |
|
| 1862 | 1863 |
AVRational tb; |
| 1863 | 1864 |
#endif |
| 1864 | 1865 |
while (is->paused && !is->videoq.abort_request) |
| 1865 | 1866 |
SDL_Delay(10); |
| 1866 | 1867 |
#if CONFIG_AVFILTER |
| 1867 |
- ret = get_filtered_video_frame(filt_out, frame, &pts_int, &tb, &pos); |
|
| 1868 |
+ ret = get_filtered_video_frame(filt_out, frame, &picref, &tb); |
|
| 1869 |
+ if (picref) {
|
|
| 1870 |
+ pts_int = picref->pts; |
|
| 1871 |
+ pos = picref->pos; |
|
| 1872 |
+ frame->opaque = picref; |
|
| 1873 |
+ } |
|
| 1868 | 1874 |
|
| 1869 | 1875 |
if (av_cmp_q(tb, is->video_st->time_base)) {
|
| 1870 | 1876 |
int64_t pts1 = pts_int; |