Newer
Older
Patrice Bensoussan
committed
for (i=0;i<nb_meta_data_maps;i++) {
AVFormatContext *out_file;
AVFormatContext *in_file;
Patrice Bensoussan
committed
int out_file_index = meta_data_maps[i].out_file;
int in_file_index = meta_data_maps[i].in_file;
if (out_file_index < 0 || out_file_index >= nb_output_files) {
snprintf(error, sizeof(error), "Invalid output file index %d map_meta_data(%d,%d)",
out_file_index, out_file_index, in_file_index);
ret = AVERROR(EINVAL);
goto dump_format;
Patrice Bensoussan
committed
}
if (in_file_index < 0 || in_file_index >= nb_input_files) {
snprintf(error, sizeof(error), "Invalid input file index %d map_meta_data(%d,%d)",
in_file_index, out_file_index, in_file_index);
ret = AVERROR(EINVAL);
goto dump_format;
Patrice Bensoussan
committed
out_file = output_files[out_file_index];
in_file = input_files[in_file_index];
mtag=NULL;
while((mtag=av_metadata_get(in_file->metadata, "", mtag, AV_METADATA_IGNORE_SUFFIX)))
av_metadata_set(&out_file->metadata, mtag->key, mtag->value);
av_metadata_conv(out_file, out_file->oformat->metadata_conv,
in_file->iformat->metadata_conv);
Patrice Bensoussan
committed
}
/* open files and write file headers */
for(i=0;i<nb_output_files;i++) {
os = output_files[i];
if (av_write_header(os) < 0) {
snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
ret = AVERROR(EINVAL);
goto dump_format;
}
if (strcmp(output_files[i]->oformat->name, "rtp")) {
want_sdp = 0;
}
}
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
dump_format:
/* dump the file output parameters - cannot be done before in case
of stream copy */
for(i=0;i<nb_output_files;i++) {
dump_format(output_files[i], i, output_files[i]->filename, 1);
}
/* dump the stream mapping */
if (verbose >= 0) {
fprintf(stderr, "Stream mapping:\n");
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
fprintf(stderr, " Stream #%d.%d -> #%d.%d",
ist_table[ost->source_index]->file_index,
ist_table[ost->source_index]->index,
ost->file_index,
ost->index);
if (ost->sync_ist != ist_table[ost->source_index])
fprintf(stderr, " [sync #%d.%d]",
ost->sync_ist->file_index,
ost->sync_ist->index);
fprintf(stderr, "\n");
}
}
if (ret) {
fprintf(stderr, "%s\n", error);
goto fail;
}
if (want_sdp) {
print_sdp(output_files, nb_output_files);
if (!using_stdin && verbose >= 0) {
fprintf(stderr, "Press [q] to stop encoding\n");
Leon van Stuivenberg
committed
url_set_interrupt_cb(decode_interrupt_cb);
}
term_init();
timer_start = av_gettime();
for(; received_sigterm == 0;) {
Patrice Bensoussan
committed
double ipts_min;
double opts_min;
Patrice Bensoussan
committed
ipts_min= 1e100;
opts_min= 1e100;
/* if 'q' pressed, exits */
if (!using_stdin) {
Leon van Stuivenberg
committed
if (q_pressed)
break;
/* read_key() returns 0 on EOF */
key = read_key();
if (key == 'q')
break;
}
Fabrice Bellard
committed
/* select the stream that we must read now by looking at the
smallest output pts */
Fabrice Bellard
committed
for(i=0;i<nb_ostreams;i++) {
Fabrice Bellard
committed
ost = ost_table[i];
os = output_files[ost->file_index];
ist = ist_table[ost->source_index];
if(no_packet[ist->file_index])
continue;
Michael Niedermayer
committed
if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO)
opts = ost->sync_opts * av_q2d(ost->st->codec->time_base);
opts = ost->st->pts.val * av_q2d(ost->st->time_base);
ipts = (double)ist->pts;
if (!file_table[ist->file_index].eof_reached){
if(ipts < ipts_min) {
ipts_min = ipts;
if(input_sync ) file_index = ist->file_index;
}
if(opts < opts_min) {
opts_min = opts;
if(!input_sync) file_index = ist->file_index;
}
Michael Niedermayer
committed
if(ost->frame_number >= max_frames[ost->st->codec->codec_type]){
file_index= -1;
break;
}
if (file_index < 0) {
if(no_packet_count){
no_packet_count=0;
memset(no_packet, 0, sizeof(no_packet));
usleep(10000);
continue;
}
Fabrice Bellard
committed
}
if (opts_min >= (recording_time / 1000000.0))
Fabrice Bellard
committed
/* finish if limit size exhausted */
if (limit_filesize != 0 && limit_filesize < url_ftell(output_files[0]->pb))
/* read a frame from it and output it in the fifo */
ret= av_read_frame(is, &pkt);
Baptiste Coudurier
committed
if(ret == AVERROR(EAGAIN)){
no_packet[file_index]=1;
no_packet_count++;
if (opt_shortest)
break;
else
continue;
no_packet_count=0;
memset(no_packet, 0, sizeof(no_packet));
if (do_pkt_dump) {
Panagiotis Issaris
committed
av_pkt_dump_log(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump);
Fabrice Bellard
committed
}
/* the following test is needed in case new streams appear
dynamically in stream : we ignore them */
if (pkt.stream_index >= file_table[file_index].nb_streams)
ist_index = file_table[file_index].ist_index + pkt.stream_index;
ist = ist_table[ist_index];
if (ist->discard)
goto discard_packet;
Michael Niedermayer
committed
if (pkt.dts != AV_NOPTS_VALUE)
pkt.dts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);
if (pkt.pts != AV_NOPTS_VALUE)
pkt.pts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);
if(input_files_ts_scale[file_index][pkt.stream_index]){
if(pkt.pts != AV_NOPTS_VALUE)
pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index];
if(pkt.dts != AV_NOPTS_VALUE)
pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index];
}
// fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);
Michael Niedermayer
committed
if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE
&& (is->iformat->flags & AVFMT_TS_DISCONT)) {
Michael Niedermayer
committed
int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
int64_t delta= pkt_dts - ist->next_pts;
if((FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE || pkt_dts+1<ist->pts)&& !copy_ts){
input_files_ts_offset[ist->file_index]-= delta;
if (verbose > 2)
fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files_ts_offset[ist->file_index]);
Michael Niedermayer
committed
pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
if(pkt.pts != AV_NOPTS_VALUE)
pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
//fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);
Fabrice Bellard
committed
if (output_packet(ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) {
if (verbose >= 0)
fprintf(stderr, "Error while decoding stream #%d.%d\n",
ist->file_index, ist->index);
if (exit_on_error)
av_exit(1);
Fabrice Bellard
committed
av_free_packet(&pkt);
goto redo;
Fabrice Bellard
committed
Fabrice Bellard
committed
/* dump report by using the output first video and audio streams */
print_report(output_files, ost_table, nb_ostreams, 0);
Fabrice Bellard
committed
/* at the end of stream, we must flush the decoder buffers */
for(i=0;i<nb_istreams;i++) {
ist = ist_table[i];
if (ist->decoding_needed) {
output_packet(ist, i, ost_table, nb_ostreams, NULL);
}
}
term_exit();
Michael Niedermayer
committed
/* write the trailer if needed and close file */
for(i=0;i<nb_output_files;i++) {
os = output_files[i];
av_write_trailer(os);
}
/* dump report by using the first video and audio streams */
print_report(output_files, ost_table, nb_ostreams, 1);
/* close each encoder */
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
if (ost->encoding_needed) {
Michael Niedermayer
committed
av_freep(&ost->st->codec->stats_in);
avcodec_close(ost->st->codec);
/* close each decoder */
for(i=0;i<nb_istreams;i++) {
ist = ist_table[i];
if (ist->decoding_needed) {
Michael Niedermayer
committed
avcodec_close(ist->st->codec);
fail:
if (ist_table) {
for(i=0;i<nb_istreams;i++) {
ist = ist_table[i];
}
if (ost_table) {
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
if (ost) {
if (ost->logfile) {
fclose(ost->logfile);
ost->logfile = NULL;
}
Michael Niedermayer
committed
av_fifo_free(ost->fifo); /* works even if fifo is not
initialized but set to zero */
sws_freeContext(ost->img_resample_ctx);
Andreas Öman
committed
if (ost->resample)
if (ost->reformat_ctx)
av_audio_convert_free(ost->reformat_ctx);
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
}
return ret;
}
#if 0
int file_read(const char *filename)
{
URLContext *h;
unsigned char buffer[1024];
int len, i;
if (url_open(&h, filename, O_RDONLY) < 0) {
printf("could not open '%s'\n", filename);
return -1;
}
for(;;) {
len = url_read(h, buffer, sizeof(buffer));
if (len <= 0)
break;
for(i=0;i<len;i++) putchar(buffer[i]);
}
url_close(h);
return 0;
}
#endif
static void opt_format(const char *arg)
Fabrice Bellard
committed
/* compatibility stuff for pgmyuv */
if (!strcmp(arg, "pgmyuv")) {
pgmyuv_compatibility_hack=1;
Michael Niedermayer
committed
// opt_image_format(arg);
fprintf(stderr, "pgmyuv format is deprecated, use image2\n");
Fabrice Bellard
committed
}
file_iformat = av_find_input_format(arg);
file_oformat = guess_format(arg, NULL, NULL);
if (!file_iformat && !file_oformat) {
fprintf(stderr, "Unknown input or output format: %s\n", arg);
static void opt_video_rc_override_string(const char *arg)
{
video_rc_override_string = arg;
}
static int opt_me_threshold(const char *opt, const char *arg)
Michael Niedermayer
committed
{
me_threshold = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
return 0;
Michael Niedermayer
committed
}
static int opt_verbose(const char *opt, const char *arg)
verbose = parse_number_or_die(opt, arg, OPT_INT64, -10, 10);
static int opt_frame_rate(const char *opt, const char *arg)
if (av_parse_video_frame_rate(&frame_rate, arg) < 0) {
fprintf(stderr, "Incorrect value for %s: %s\n", opt, arg);
return 0;
static int opt_bitrate(const char *opt, const char *arg)
{
int codec_type = opt[0]=='a' ? CODEC_TYPE_AUDIO : CODEC_TYPE_VIDEO;
opt_default(opt, arg);
if (av_get_int(avcodec_opts[codec_type], "b", NULL) < 1000)
fprintf(stderr, "WARNING: The bitrate parameter is set too low. It takes bits/s as argument, not kbits/s\n");
return 0;
static void opt_frame_crop_top(const char *arg)
Michael Niedermayer
committed
{
Michael Niedermayer
committed
if (frame_topBand < 0) {
fprintf(stderr, "Incorrect top crop size\n");
Michael Niedermayer
committed
}
if ((frame_topBand) >= frame_height){
fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
Michael Niedermayer
committed
}
frame_height -= frame_topBand;
}
static void opt_frame_crop_bottom(const char *arg)
Michael Niedermayer
committed
{
frame_bottomBand = atoi(arg);
if (frame_bottomBand < 0) {
fprintf(stderr, "Incorrect bottom crop size\n");
Michael Niedermayer
committed
}
if ((frame_bottomBand) >= frame_height){
fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
Michael Niedermayer
committed
}
frame_height -= frame_bottomBand;
}
static void opt_frame_crop_left(const char *arg)
Michael Niedermayer
committed
{
frame_leftBand = atoi(arg);
if (frame_leftBand < 0) {
fprintf(stderr, "Incorrect left crop size\n");
Michael Niedermayer
committed
}
if ((frame_leftBand) >= frame_width){
fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
Michael Niedermayer
committed
}
frame_width -= frame_leftBand;
}
static void opt_frame_crop_right(const char *arg)
Michael Niedermayer
committed
{
frame_rightBand = atoi(arg);
if (frame_rightBand < 0) {
fprintf(stderr, "Incorrect right crop size\n");
Michael Niedermayer
committed
}
if ((frame_rightBand) >= frame_width){
fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n");
Michael Niedermayer
committed
}
frame_width -= frame_rightBand;
}
static void opt_frame_size(const char *arg)
if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) {
}
if ((frame_width % 2) != 0 || (frame_height % 2) != 0) {
fprintf(stderr, "Frame size must be a multiple of 2\n");
Todd Kirby
committed
static void opt_pad_color(const char *arg) {
/* Input is expected to be six hex digits similar to
how colors are expressed in html tags (but without the #) */
int rgb = strtol(arg, NULL, 16);
int r,g,b;
Todd Kirby
committed
g = ((rgb >> 8) & 255);
b = (rgb & 255);
padcolor[0] = RGB_TO_Y(r,g,b);
padcolor[1] = RGB_TO_U(r,g,b,0);
padcolor[2] = RGB_TO_V(r,g,b,0);
}
static void opt_frame_pad_top(const char *arg)
{
Todd Kirby
committed
if (frame_padtop < 0) {
fprintf(stderr, "Incorrect top pad size\n");
Todd Kirby
committed
}
}
static void opt_frame_pad_bottom(const char *arg)
{
frame_padbottom = atoi(arg);
Todd Kirby
committed
if (frame_padbottom < 0) {
fprintf(stderr, "Incorrect bottom pad size\n");
Todd Kirby
committed
}
}
static void opt_frame_pad_left(const char *arg)
{
Todd Kirby
committed
if (frame_padleft < 0) {
fprintf(stderr, "Incorrect left pad size\n");
Todd Kirby
committed
}
}
static void opt_frame_pad_right(const char *arg)
{
Todd Kirby
committed
if (frame_padright < 0) {
fprintf(stderr, "Incorrect right pad size\n");
Todd Kirby
committed
}
}
static void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
{
int i;
char fmt_str[128];
for (i=-1; i < nb_fmts; i++) {
get_fmt_string (fmt_str, sizeof(fmt_str), i);
fprintf(stdout, "%s\n", fmt_str);
}
}
Todd Kirby
committed
static void opt_frame_pix_fmt(const char *arg)
{
if (strcmp(arg, "list")) {
frame_pix_fmt = avcodec_get_pix_fmt(arg);
if (frame_pix_fmt == PIX_FMT_NONE) {
fprintf(stderr, "Unknown pixel format requested: %s\n", arg);
av_exit(1);
}
} else {
list_fmts(avcodec_pix_fmt_string, PIX_FMT_NB);
}
static void opt_frame_aspect_ratio(const char *arg)
{
int x = 0, y = 0;
double ar = 0;
const char *p;
p = strchr(arg, ':');
if (p) {
x = strtol(arg, &end, 10);
if (end == p)
y = strtol(end+1, &end, 10);
if (x > 0 && y > 0)
ar = (double)x / (double)y;
} else
if (!ar) {
fprintf(stderr, "Incorrect aspect ratio specification.\n");
}
frame_aspect_ratio = ar;
}
static int opt_metadata(const char *opt, const char *arg)
{
char *mid= strchr(arg, '=');
if(!mid){
fprintf(stderr, "Missing =\n");
av_exit(1);
}
*mid++= 0;
metadata_count++;
metadata= av_realloc(metadata, sizeof(*metadata)*metadata_count);
metadata[metadata_count-1].key = av_strdup(arg);
metadata[metadata_count-1].value= av_strdup(mid);
return 0;
}
static void opt_qscale(const char *arg)
Michael Niedermayer
committed
video_qscale = atof(arg);
Michael Niedermayer
committed
video_qscale > 255) {
fprintf(stderr, "qscale must be > 0.0 and <= 255\n");
static void opt_top_field_first(const char *arg)
{
top_field_first= atoi(arg);
}
static int opt_thread_count(const char *opt, const char *arg)
thread_count= parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
if (verbose >= 0)
fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
static void opt_audio_sample_fmt(const char *arg)
{
if (strcmp(arg, "list"))
audio_sample_fmt = avcodec_get_sample_fmt(arg);
else {
list_fmts(avcodec_sample_fmt_string, SAMPLE_FMT_NB);
av_exit(0);
}
}
static int opt_audio_rate(const char *opt, const char *arg)
audio_sample_rate = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
return 0;
static int opt_audio_channels(const char *opt, const char *arg)
audio_channels = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
return 0;
static void opt_video_channel(const char *arg)
Fabrice Bellard
committed
{
video_channel = strtol(arg, NULL, 0);
}
static void opt_video_standard(const char *arg)
{
video_standard = av_strdup(arg);
}
static void opt_codec(int *pstream_copy, char **pcodec_name,
Fabrice Bellard
committed
int codec_type, const char *arg)
av_freep(pcodec_name);
if (!strcmp(arg, "copy")) {
Fabrice Bellard
committed
*pstream_copy = 1;
*pcodec_name = av_strdup(arg);
Fabrice Bellard
committed
static void opt_audio_codec(const char *arg)
{
opt_codec(&audio_stream_copy, &audio_codec_name, CODEC_TYPE_AUDIO, arg);
Fabrice Bellard
committed
}
static void opt_audio_tag(const char *arg)
{
char *tail;
audio_codec_tag= strtol(arg, &tail, 0);
if(!tail || *tail)
audio_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24);
}
static void opt_video_tag(const char *arg)
{
char *tail;
video_codec_tag= strtol(arg, &tail, 0);
if(!tail || *tail)
video_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24);
}
static void opt_video_codec(const char *arg)
opt_codec(&video_stream_copy, &video_codec_name, CODEC_TYPE_VIDEO, arg);
Fabrice Bellard
committed
}
Fabrice Bellard
committed
static void opt_subtitle_codec(const char *arg)
{
opt_codec(&subtitle_stream_copy, &subtitle_codec_name, CODEC_TYPE_SUBTITLE, arg);
static void opt_subtitle_tag(const char *arg)
{
char *tail;
subtitle_codec_tag= strtol(arg, &tail, 0);
if(!tail || *tail)
subtitle_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24);
}
static void opt_map(const char *arg)
m->file_index = strtol(arg, &p, 0);
m->stream_index = strtol(p, &p, 0);
if (*p) {
p++;
m->sync_file_index = strtol(p, &p, 0);
if (*p)
p++;
m->sync_stream_index = strtol(p, &p, 0);
} else {
m->sync_file_index = m->file_index;
m->sync_stream_index = m->stream_index;
}
Patrice Bensoussan
committed
static void opt_map_meta_data(const char *arg)
{
AVMetaDataMap *m;
Patrice Bensoussan
committed
m = &meta_data_maps[nb_meta_data_maps++];
m->out_file = strtol(arg, &p, 0);
Patrice Bensoussan
committed
if (*p)
p++;
m->in_file = strtol(p, &p, 0);
Patrice Bensoussan
committed
}
static void opt_input_ts_scale(const char *arg)
{
unsigned int stream;
double scale;
char *p;
stream = strtol(arg, &p, 0);
if (*p)
p++;
scale= strtod(p, &p);
if(stream >= MAX_STREAMS)
av_exit(1);
input_files_ts_scale[nb_input_files][stream]= scale;
}
static int opt_recording_time(const char *opt, const char *arg)
recording_time = parse_time_or_die(opt, arg, 1);
return 0;
static int opt_start_time(const char *opt, const char *arg)
start_time = parse_time_or_die(opt, arg, 1);
return 0;
static int opt_rec_timestamp(const char *opt, const char *arg)
{
rec_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
return 0;
}
static int opt_input_ts_offset(const char *opt, const char *arg)
input_ts_offset = parse_time_or_die(opt, arg, 1);
return 0;
static enum CodecID find_codec_or_die(const char *name, int type, int encoder)
{
const char *codec_string = encoder ? "encoder" : "decoder";
AVCodec *codec;
if(!name)
return CODEC_ID_NONE;
codec = encoder ?
avcodec_find_encoder_by_name(name) :
avcodec_find_decoder_by_name(name);
if(!codec) {
fprintf(stderr, "Unknown %s '%s'\n", codec_string, name);
}
if(codec->type != type) {
fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
}
return codec->id;
}
static void opt_input_file(const char *filename)
{
AVFormatContext *ic;
AVFormatParameters params, *ap = ¶ms;
Michael Niedermayer
committed
int err, i, ret, rfps, rfps_base;
if (!strcmp(filename, "-"))
filename = "pipe:";
using_stdin |= !strncmp(filename, "pipe:", 5) ||
!strcmp(filename, "/dev/stdin");
ic = avformat_alloc_context();
memset(ap, 0, sizeof(*ap));
ap->prealloced_context = 1;
ap->sample_rate = audio_sample_rate;
ap->channels = audio_channels;
ap->time_base.den = frame_rate.num;
ap->time_base.num = frame_rate.den;
Todd Kirby
committed
ap->width = frame_width + frame_padleft + frame_padright;
ap->height = frame_height + frame_padtop + frame_padbottom;
ap->pix_fmt = frame_pix_fmt;
// ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat
ap->channel = video_channel;
ap->standard = video_standard;
ap->video_codec_id = find_codec_or_die(video_codec_name, CODEC_TYPE_VIDEO, 0);
ap->audio_codec_id = find_codec_or_die(audio_codec_name, CODEC_TYPE_AUDIO, 0);
if(pgmyuv_compatibility_hack)
ap->video_codec_id= CODEC_ID_PGMYUV;
set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
ic->video_codec_id = find_codec_or_die(video_codec_name , CODEC_TYPE_VIDEO , 0);
ic->audio_codec_id = find_codec_or_die(audio_codec_name , CODEC_TYPE_AUDIO , 0);
ic->subtitle_codec_id= find_codec_or_die(subtitle_codec_name, CODEC_TYPE_SUBTITLE, 0);
/* open the input file with generic libav function */
err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
print_error(filename, err);
Nico Sabbi
committed
if(opt_programid) {
int i;
for(i=0; i<ic->nb_programs; i++)
if(ic->programs[i]->id != opt_programid)
ic->programs[i]->discard = AVDISCARD_ALL;
}
ic->loop_input = loop_input;
/* If not enough info to get the stream parameters, we decode the
first frames to get it. (used in mpeg case for example) */
ret = av_find_stream_info(ic);
if (ret < 0 && verbose >= 0) {
fprintf(stderr, "%s: could not find codec parameters\n", filename);
timestamp = start_time;
/* add the stream start time */
if (ic->start_time != AV_NOPTS_VALUE)
timestamp += ic->start_time;
/* if seeking requested, we execute it */
if (start_time != 0) {
ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
if (ret < 0) {
fprintf(stderr, "%s: could not seek to position %0.3f\n",
filename, (double)timestamp / AV_TIME_BASE);
}
/* reset seek info */
start_time = 0;
}
/* update the current parameters so that they match the one of the input stream */
for(i=0;i<ic->nb_streams;i++) {
Michael Niedermayer
committed
AVCodecContext *enc = ic->streams[i]->codec;
if(thread_count>1)
avcodec_thread_init(enc, thread_count);
enc->thread_count= thread_count;
set_context_opts(enc, avcodec_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
//fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
channel_layout = enc->channel_layout;
audio_channels = enc->channels;
audio_sample_rate = enc->sample_rate;
audio_sample_fmt = enc->sample_fmt;
input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(audio_codec_name);
ic->streams[i]->discard= AVDISCARD_ALL;
set_context_opts(enc, avcodec_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
if(ic->streams[i]->sample_aspect_ratio.num)
frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio);
else
frame_aspect_ratio=av_q2d(enc->sample_aspect_ratio);
frame_aspect_ratio *= (float) enc->width / enc->height;
frame_pix_fmt = enc->pix_fmt;
rfps = ic->streams[i]->r_frame_rate.num;
rfps_base = ic->streams[i]->r_frame_rate.den;
if(enc->lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
Michael Niedermayer
committed
if(me_threshold)
enc->debug |= FF_DEBUG_MV;
if (enc->time_base.den != rfps || enc->time_base.num != rfps_base) {
if (verbose >= 0)
Baptiste Coudurier
committed
fprintf(stderr,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
i, (float)enc->time_base.den / enc->time_base.num, enc->time_base.den, enc->time_base.num,
(float)rfps / rfps_base, rfps, rfps_base);
/* update the current frame rate to match the stream frame rate */
frame_rate.num = rfps;
frame_rate.den = rfps_base;
Max Krasnyansky
committed
input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(video_codec_name);
ic->streams[i]->discard= AVDISCARD_ALL;
else if(video_discard)
ic->streams[i]->discard= video_discard;
case CODEC_TYPE_DATA:
break;
Fabrice Bellard
committed
case CODEC_TYPE_SUBTITLE:
input_codecs[nb_icodecs++] = avcodec_find_decoder_by_name(subtitle_codec_name);
if(subtitle_disable)
ic->streams[i]->discard = AVDISCARD_ALL;
Fabrice Bellard
committed
break;
case CODEC_TYPE_UNKNOWN:
break;
default:
input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp);
if (verbose >= 0)
dump_format(ic, nb_input_files, filename, 0);
file_iformat = NULL;
file_oformat = NULL;
Max Krasnyansky
committed
Baptiste Coudurier
committed
av_freep(&video_codec_name);
av_freep(&audio_codec_name);
av_freep(&subtitle_codec_name);
static void check_audio_video_sub_inputs(int *has_video_ptr, int *has_audio_ptr,
int *has_subtitle_ptr)
Fabrice Bellard
committed
{
int has_video, has_audio, has_subtitle, i, j;
Fabrice Bellard
committed
AVFormatContext *ic;
has_video = 0;
has_audio = 0;
has_subtitle = 0;
Fabrice Bellard
committed
for(j=0;j<nb_input_files;j++) {
ic = input_files[j];
for(i=0;i<ic->nb_streams;i++) {
Michael Niedermayer
committed
AVCodecContext *enc = ic->streams[i]->codec;
Fabrice Bellard
committed
switch(enc->codec_type) {
case CODEC_TYPE_AUDIO:
has_audio = 1;
break;
case CODEC_TYPE_VIDEO:
has_video = 1;
break;
case CODEC_TYPE_SUBTITLE:
has_subtitle = 1;
break;
Wolfram Gloger
committed
case CODEC_TYPE_DATA:
case CODEC_TYPE_UNKNOWN:
Wolfram Gloger
committed
break;
default:
Fabrice Bellard
committed
}
}
}
*has_video_ptr = has_video;
*has_audio_ptr = has_audio;
*has_subtitle_ptr = has_subtitle;
Fabrice Bellard
committed
}
Fabrice Bellard
committed
static void new_video_stream(AVFormatContext *oc)
Fabrice Bellard
committed
AVCodecContext *video_enc;
int codec_id;
Fabrice Bellard
committed
st = av_new_stream(oc, oc->nb_streams);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
Fabrice Bellard
committed
}
Michael Niedermayer
committed
avcodec_get_context_defaults2(st->codec, CODEC_TYPE_VIDEO);
Michael Niedermayer
committed
bitstream_filters[nb_output_files][oc->nb_streams - 1]= video_bitstream_filters;
video_bitstream_filters= NULL;
Fabrice Bellard
committed
if(thread_count>1)
Michael Niedermayer
committed
avcodec_thread_init(st->codec, thread_count);