#include <errno.h>
#include <signal.h>
#include <limits.h>
+#include <stdint.h>
+
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
bsfc = next;
}
output_streams[i]->bitstream_filters = NULL;
- avcodec_free_frame(&output_streams[i]->filtered_frame);
+ av_frame_free(&output_streams[i]->filtered_frame);
+
+ av_parser_close(output_streams[i]->parser);
av_freep(&output_streams[i]->forced_keyframes);
av_freep(&output_streams[i]->avfilter);
av_frame_free(&input_streams[i]->filter_frame);
av_dict_free(&input_streams[i]->opts);
av_freep(&input_streams[i]->filters);
+ av_freep(&input_streams[i]->hwaccel_device);
av_freep(&input_streams[i]);
}
AVFrame *filtered_frame = NULL;
int frame_size, ret;
- if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
+ if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) {
return AVERROR(ENOMEM);
- } else
- avcodec_get_frame_defaults(ost->filtered_frame);
+ }
filtered_frame = ost->filtered_frame;
if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
return ret;
if (filtered_frame->pts != AV_NOPTS_VALUE) {
+ int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
filtered_frame->pts = av_rescale_q(filtered_frame->pts,
ost->filter->filter->inputs[0]->time_base,
ost->st->codec->time_base) -
- av_rescale_q(of->start_time,
+ av_rescale_q(start_time,
AV_TIME_BASE_Q,
ost->st->codec->time_base);
}
if (ost->source_index != ist_index)
return 0;
- if (of->start_time && ist->last_dts < of->start_time)
+ if (of->start_time != AV_NOPTS_VALUE && ist->last_dts < of->start_time)
return 0;
return 1;
static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
{
OutputFile *of = output_files[ost->file_index];
- int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
+ InputFile *f = input_files [ist->file_index];
+ int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
+ int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
AVPacket opkt;
av_init_packet(&opkt);
return;
if (of->recording_time != INT64_MAX &&
- ist->last_dts >= of->recording_time + of->start_time) {
+ ist->last_dts >= of->recording_time + start_time) {
ost->finished = 1;
return;
}
+ if (f->recording_time != INT64_MAX) {
+ start_time = f->ctx->start_time;
+ if (f->start_time != AV_NOPTS_VALUE)
+ start_time += f->start_time;
+ if (ist->last_dts >= f->recording_time + start_time) {
+ ost->finished = 1;
+ return;
+ }
+ }
+
/* force the input stream PTS */
if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
audio_size += pkt->size;
&& ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
&& ost->st->codec->codec_id != AV_CODEC_ID_VC1
) {
- if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) {
+ if (av_parser_change(ost->parser, ost->st->codec,
+ &opkt.data, &opkt.size,
+ pkt->data, pkt->size,
+ pkt->flags & AV_PKT_FLAG_KEY)) {
opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
if (!opkt.buf)
exit_program(1);
AVCodecContext *avctx = ist->st->codec;
int i, ret, err = 0, resample_changed;
- if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+ if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
return AVERROR(ENOMEM);
if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc()))
return AVERROR(ENOMEM);
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
{
AVFrame *decoded_frame, *f;
- void *buffer_to_free = NULL;
int i, ret = 0, err = 0, resample_changed;
if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
return ret;
}
+ if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) {
+ err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame);
+ if (err < 0)
+ goto fail;
+ }
+ ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
+
decoded_frame->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pkt_pts,
decoded_frame->pkt_dts);
pkt->size = 0;
break;
}
+fail:
av_frame_unref(ist->filter_frame);
av_frame_unref(decoded_frame);
- av_free(buffer_to_free);
return err < 0 ? err : ret;
}
av_freep(&avc);
}
+static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt)
+{
+ int i;
+ for (i = 0; hwaccels[i].name; i++)
+ if (hwaccels[i].pix_fmt == pix_fmt)
+ return &hwaccels[i];
+ return NULL;
+}
+
+static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
+{
+ InputStream *ist = s->opaque;
+ const enum AVPixelFormat *p;
+ int ret;
+
+ for (p = pix_fmts; *p != -1; p++) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
+ const HWAccel *hwaccel;
+
+ if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
+ break;
+
+ hwaccel = get_hwaccel(*p);
+ if (!hwaccel ||
+ (ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) ||
+ (ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id))
+ continue;
+
+ ret = hwaccel->init(s);
+ if (ret < 0) {
+ if (ist->hwaccel_id == hwaccel->id) {
+ av_log(NULL, AV_LOG_FATAL,
+ "%s hwaccel requested for input stream #%d:%d, "
+ "but cannot be initialized.\n", hwaccel->name,
+ ist->file_index, ist->st->index);
+ exit_program(1);
+ }
+ continue;
+ }
+ ist->active_hwaccel_id = hwaccel->id;
+ ist->hwaccel_pix_fmt = *p;
+ break;
+ }
+
+ return *p;
+}
+
+static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
+{
+ InputStream *ist = s->opaque;
+
+ if (ist->hwaccel_get_buffer && frame->format == ist->hwaccel_pix_fmt)
+ return ist->hwaccel_get_buffer(s, frame, flags);
+
+ return avcodec_default_get_buffer2(s, frame, flags);
+}
+
static int init_input_stream(int ist_index, char *error, int error_len)
{
int i, ret;
}
}
+ ist->st->codec->opaque = ist;
+ ist->st->codec->get_format = get_format;
+ ist->st->codec->get_buffer2 = get_buffer;
+ ist->st->codec->thread_safe_callbacks = 1;
+
av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0);
if (!av_dict_get(ist->opts, "threads", NULL, 0))
} else
codec->time_base = ist->st->time_base;
+ ost->parser = av_parser_init(codec->codec_id);
+
switch (codec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if (audio_volume != 256) {
av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
"It takes bits/s as argument, not kbits/s\n");
extra_size += ost->st->codec->extradata_size;
-
- 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);
}
ist = input_streams[i];
if (ist->decoding_needed) {
avcodec_close(ist->st->codec);
+ if (ist->hwaccel_uninit)
+ ist->hwaccel_uninit(ist->st->codec);
}
}