static void do_video_stats(OutputStream *ost, int frame_size);
static int64_t getutime(void);
+static int64_t getmaxrss(void);
static int run_as_daemon = 0;
static int64_t video_size = 0;
This is a temporary solution until libavfilter gets real subtitles support.
*/
+static int sub2video_get_blank_frame(InputStream *ist)
+{
+ int ret;
+ AVFrame *frame = ist->sub2video.frame;
+ av_frame_unref(frame);
+ ist->sub2video.frame->width = ist->sub2video.w;
+ ist->sub2video.frame->height = ist->sub2video.h;
+ ist->sub2video.frame->format = AV_PIX_FMT_RGB32;
+ if ((ret = av_frame_get_buffer(frame, 32)) < 0)
+ return ret;
+ memset(frame->data[0], 0, frame->height * frame->linesize[0]);
+ return 0;
+}
static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
AVSubtitleRect *r)
static void sub2video_push_ref(InputStream *ist, int64_t pts)
{
- AVFilterBufferRef *ref = ist->sub2video.ref;
+ AVFrame *frame = ist->sub2video.frame;
int i;
- ist->sub2video.last_pts = ref->pts = pts;
+ av_assert1(frame->data[0]);
+ ist->sub2video.last_pts = frame->pts = pts;
for (i = 0; i < ist->nb_filters; i++)
- av_buffersrc_add_ref(ist->filters[i]->filter,
- avfilter_ref_buffer(ref, ~0),
- AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
- AV_BUFFERSRC_FLAG_NO_COPY |
- AV_BUFFERSRC_FLAG_PUSH);
+ av_buffersrc_add_frame_flags(ist->filters[i]->filter, frame,
+ AV_BUFFERSRC_FLAG_KEEP_REF |
+ AV_BUFFERSRC_FLAG_PUSH);
}
static void sub2video_update(InputStream *ist, AVSubtitle *sub)
{
int w = ist->sub2video.w, h = ist->sub2video.h;
- AVFilterBufferRef *ref = ist->sub2video.ref;
+ AVFrame *frame = ist->sub2video.frame;
int8_t *dst;
int dst_linesize;
int num_rects, i;
int64_t pts, end_pts;
- if (!ref)
+ if (!frame)
return;
if (sub) {
pts = av_rescale_q(sub->pts + sub->start_display_time * 1000,
end_pts = INT64_MAX;
num_rects = 0;
}
- dst = ref->data [0];
- dst_linesize = ref->linesize[0];
- memset(dst, 0, h * dst_linesize);
+ if (sub2video_get_blank_frame(ist) < 0) {
+ av_log(ist->st->codec, AV_LOG_ERROR,
+ "Impossible to get a blank canvas.\n");
+ return;
+ }
+ dst = frame->data [0];
+ dst_linesize = frame->linesize[0];
for (i = 0; i < num_rects; i++)
sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]);
sub2video_push_ref(ist, pts);
(possibly overlay) is desperately waiting for a subtitle frame. */
for (i = 0; i < infile->nb_streams; i++) {
InputStream *ist2 = input_streams[infile->ist_index + i];
- if (!ist2->sub2video.ref)
+ if (!ist2->sub2video.frame)
continue;
/* subtitles seem to be usually muxed ahead of other streams;
if not, substracting a larger time here is necessary */
/* do not send the heartbeat frame if the subtitle is already ahead */
if (pts2 <= ist2->sub2video.last_pts)
continue;
- if (pts2 >= ist2->sub2video.end_pts)
+ if (pts2 >= ist2->sub2video.end_pts || !ist2->sub2video.frame->data[0])
sub2video_update(ist2, NULL);
for (j = 0, nb_reqs = 0; j < ist2->nb_filters; j++)
nb_reqs += av_buffersrc_get_nb_failed_requests(ist2->filters[j]->filter);
{
int i, j;
+ if (do_benchmark) {
+ int maxrss = getmaxrss() / 1024;
+ printf("bench: maxrss=%ikB\n", maxrss);
+ }
+
for (i = 0; i < nb_filtergraphs; i++) {
avfilter_graph_free(&filtergraphs[i]->graph);
for (j = 0; j < filtergraphs[i]->nb_inputs; j++) {
avcodec_free_frame(&input_streams[i]->decoded_frame);
av_dict_free(&input_streams[i]->opts);
free_buffer_pool(&input_streams[i]->buffer_pool);
- avfilter_unref_bufferp(&input_streams[i]->sub2video.ref);
+ avsubtitle_free(&input_streams[i]->prev_sub.subtitle);
+ avcodec_free_frame(&input_streams[i]->sub2video.frame);
av_freep(&input_streams[i]->filters);
av_freep(&input_streams[i]);
}
memcpy(t, new_pkt.data, new_pkt.size);
memset(t + new_pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
new_pkt.data = t;
+ new_pkt.buf = NULL;
a = 1;
} else
a = AVERROR(ENOMEM);
}
}
+#if FF_API_DEINTERLACE
static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void **bufp)
{
AVCodecContext *dec;
dec = ist->st->codec;
/* deinterlace : must be done before any resize */
- if (do_deinterlace) {
+ if (FF_API_DEINTERLACE && do_deinterlace) {
int size;
/* create temporary picture */
*picture = *picture2;
*bufp = buf;
}
+#endif
static void do_subtitle_out(AVFormatContext *s,
OutputStream *ost,
p = psnr(error / scale);
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], p);
av_bprintf(&buf_script, "stream_%d_%d_psnr_%c=%2.2f\n",
- ost->file_index, ost->index, type[i] | 32, p);
+ ost->file_index, ost->index, type[j] | 32, p);
}
p = psnr(error_sum / scale_sum);
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));
av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop);
if (print_stats || is_last_report) {
- av_log(NULL, AV_LOG_INFO, "%s \r", buf);
+ if (print_stats==1 && AV_LOG_INFO > av_log_get_level()) {
+ fprintf(stderr, "%s \r", buf);
+ } else
+ av_log(NULL, AV_LOG_INFO, "%s \r", buf);
fflush(stderr);
}
(AVRational){1, ist->st->codec->sample_rate}, decoded_frame->nb_samples, &ist->filter_in_rescale_delta_last,
(AVRational){1, ist->st->codec->sample_rate});
for (i = 0; i < ist->nb_filters; i++)
- av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame,
- AV_BUFFERSRC_FLAG_PUSH);
+ av_buffersrc_add_frame_flags(ist->filters[i]->filter, decoded_frame,
+ AV_BUFFERSRC_FLAG_KEEP_REF |
+ AV_BUFFERSRC_FLAG_PUSH);
decoded_frame->pts = AV_NOPTS_VALUE;
}
pkt->size = 0;
+#if FF_API_DEINTERLACE
pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free);
+#endif
rate_emu_sleep(ist);
AV_BUFFERSRC_FLAG_NO_COPY |
AV_BUFFERSRC_FLAG_PUSH);
} else
- if(av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame, AV_BUFFERSRC_FLAG_PUSH)<0) {
+ if(av_buffersrc_add_frame_flags(ist->filters[i]->filter, decoded_frame,
+ AV_BUFFERSRC_FLAG_KEEP_REF |
+ AV_BUFFERSRC_FLAG_PUSH)<0) {
av_log(NULL, AV_LOG_FATAL, "Failed to inject frame into filter network\n");
exit(1);
}
return AVERROR(EINVAL);
}
- ist->dr1 = (codec->capabilities & CODEC_CAP_DR1) && !do_deinterlace;
+ ist->dr1 = (codec->capabilities & CODEC_CAP_DR1) && !(FF_API_DEINTERLACE && do_deinterlace);
if (codec->type == AVMEDIA_TYPE_VIDEO && ist->dr1) {
ist->st->codec->get_buffer = codec_get_buffer;
ist->st->codec->release_buffer = codec_release_buffer;
if (ost->st->codec->me_threshold)
input_streams[ost->source_index]->st->codec->debug |= FF_DEBUG_MV;
+ } else {
+ av_opt_set_dict(ost->st->codec, &ost->opts);
}
}
/* init input streams */
for (i = 0; i < nb_input_streams; i++)
- if ((ret = init_input_stream(i, error, sizeof(error))) < 0)
+ if ((ret = init_input_stream(i, error, sizeof(error))) < 0) {
+ for (i = 0; i < nb_output_streams; i++) {
+ ost = output_streams[i];
+ avcodec_close(ost->st->codec);
+ }
goto dump_format;
+ }
/* discard unused programs */
for (i = 0; i < nb_input_files; i++) {
av_freep(&ost->st->codec->subtitle_header);
av_free(ost->forced_kf_pts);
av_dict_free(&ost->opts);
+ av_dict_free(&ost->swr_opts);
+ av_dict_free(&ost->resample_opts);
}
}
}
exit(1);
ti = getutime() - ti;
if (do_benchmark) {
- int maxrss = getmaxrss() / 1024;
- printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
+ printf("bench: utime=%0.3fs\n", ti / 1000000.0);
}
exit(received_nb_signals ? 255 : 0);