Newer
Older
/* 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 */
if (av_read_frame(is, &pkt) < 0) {
if (opt_shortest)
break;
else
continue;
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);
// 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);
if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) {
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);
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);
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;
}
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)
ret = AVERROR(ENOMEM);
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
goto fail1;
}
#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);
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
extern int ffm_nopts;
static int opt_default(const char *opt, const char *arg){
int type;
const AVOption *o= NULL;
int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
for(type=0; type<CODEC_TYPE_NB; type++){
const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);
if(o2)
o = av_set_string(avctx_opts[type], opt, arg);
}
if(!o)
o = av_set_string(avformat_opts, opt, arg);
if(!o)
o = av_set_string(sws_opts, opt, arg);
if(!o){
if(opt[0] == 'a')
o = av_set_string(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg);
else if(opt[0] == 'v')
o = av_set_string(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg);
else if(opt[0] == 's')
o = av_set_string(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg);
}
if(!o)
return -1;
// av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avctx_opts, opt, NULL), (int)av_get_int(avctx_opts, opt, NULL));
//FIXME we should always use avctx_opts, ... for storing options so there wont be any need to keep track of whats set over this
opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
opt_names[opt_name_count++]= o->name;
#if defined(CONFIG_FFM_DEMUXER) || defined(CONFIG_FFM_MUXER)
/* disable generate of real time pts in ffm (need to be supressed anyway) */
if(avctx_opts[0]->flags & CODEC_FLAG_BITEXACT)
ffm_nopts = 1;
#endif
if(avctx_opts[0]->debug)
return 0;
}
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, AV_LOG_QUIET, AV_LOG_DEBUG);
av_log_set_level(verbose);
static void opt_frame_rate(const char *arg)
if (av_parse_video_frame_rate(&frame_rate, arg) < 0) {
fprintf(stderr, "Incorrect frame rate\n");
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(avctx_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 % 2) != 0) {
fprintf(stderr, "Top crop size must be a multiple of 2\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 % 2) != 0) {
fprintf(stderr, "Bottom crop size must be a multiple of 2\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 % 2) != 0) {
fprintf(stderr, "Left crop size must be a multiple of 2\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 % 2) != 0) {
fprintf(stderr, "Right crop size must be a multiple of 2\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
#define SCALEBITS 10
#define ONE_HALF (1 << (SCALEBITS - 1))
#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
Todd Kirby
committed
#define RGB_TO_Y(r, g, b) \
((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
#define RGB_TO_U(r1, g1, b1, shift)\
(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \
FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
#define RGB_TO_V(r1, g1, b1, shift)\
(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \
FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
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
}
if ((frame_padtop % 2) != 0) {
fprintf(stderr, "Top pad size must be a multiple of 2\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
}
if ((frame_padbottom % 2) != 0) {
fprintf(stderr, "Bottom pad size must be a multiple of 2\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
}
if ((frame_padleft % 2) != 0) {
fprintf(stderr, "Left pad size must be a multiple of 2\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
}
if ((frame_padright % 2) != 0) {
fprintf(stderr, "Right pad size must be a multiple of 2\n");
Todd Kirby
committed
}
}
Diego Pettenò
committed
static void list_pix_fmts(void)
{
int i;
char pix_fmt_str[128];
for (i=-1; i < PIX_FMT_NB; i++) {
avcodec_pix_fmt_string (pix_fmt_str, sizeof(pix_fmt_str), i);
fprintf(stdout, "%s\n", pix_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);
else {
list_pix_fmts();
}
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 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_qdiff(const char *arg)
{
video_qdiff = atoi(arg);
if (video_qdiff < 0 ||
video_qdiff > 31) {
fprintf(stderr, "qdiff must be >= 1 and <= 31\n");
static void opt_strict(const char *arg)
static void opt_top_field_first(const char *arg)
{
top_field_first= atoi(arg);
}
static void opt_thread_count(const char *arg)
{
thread_count= atoi(arg);
François Revol
committed
#if !defined(HAVE_THREADS)
if (verbose >= 0)
fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n");
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);
}
#ifdef CONFIG_VHOOK
static void add_frame_hooker(const char *arg)
{
int argc = 0;
char *argv[64];
int i;
using_vhook = 1;
argv[0] = strtok(args, " ");
while (argc < 62 && (argv[++argc] = strtok(NULL, " "))) {
}
i = frame_hook_add(argc, argv);
if (i != 0) {
fprintf(stderr, "Failed to add video hook function: %s\n", arg);
}
}
#endif
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_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 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) {
av_log(NULL, AV_LOG_ERROR, "Unknown %s '%s'\n", codec_string, name);
}
if(codec->type != type) {
av_log(NULL, AV_LOG_ERROR, "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 = av_alloc_format_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->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;
for(i=0; i<opt_name_count; i++){
const AVOption *opt;
Baptiste Coudurier
committed
const char *str= av_get_string(avformat_opts, opt_names[i], &opt, buf, sizeof(buf));
if(str && (opt->flags & AV_OPT_FLAG_DECODING_PARAM))
av_set_string(ic, opt_names[i], str);
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;
for(j=0; j<opt_name_count; j++){
const AVOption *opt;
Baptiste Coudurier
committed
const char *str= av_get_string(avctx_opts[CODEC_TYPE_AUDIO], opt_names[j], &opt, buf, sizeof(buf));
if(str && (opt->flags & AV_OPT_FLAG_AUDIO_PARAM) && (opt->flags & AV_OPT_FLAG_DECODING_PARAM))
av_set_string(enc, opt_names[j], str);
//fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
audio_channels = enc->channels;
audio_sample_rate = enc->sample_rate;
ic->streams[i]->discard= AVDISCARD_ALL;
for(j=0; j<opt_name_count; j++){
const AVOption *opt;
Baptiste Coudurier
committed
const char *str= av_get_string(avctx_opts[CODEC_TYPE_VIDEO], opt_names[j], &opt, buf, sizeof(buf));
if(str && (opt->flags & AV_OPT_FLAG_VIDEO_PARAM) && (opt->flags & AV_OPT_FLAG_DECODING_PARAM))
av_set_string(enc, opt_names[j], str);
frame_aspect_ratio = av_q2d(enc->sample_aspect_ratio) * 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
enc->rate_emu = rate_emu;
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:
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
Max Krasnyansky
committed
rate_emu = 0;
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);
Michael Niedermayer
committed
video_enc = st->codec;
Fabrice Bellard
committed
if(video_codec_tag)
video_enc->codec_tag= video_codec_tag;
Michael Niedermayer
committed
if( (video_global_header&1)
|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){
Fabrice Bellard
committed
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
avctx_opts[CODEC_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
}
if(video_global_header&2){
Michael Niedermayer
committed
video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER;
avctx_opts[CODEC_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER;
Michael Niedermayer
committed
Fabrice Bellard
committed
if (video_stream_copy) {
st->stream_copy = 1;
video_enc->codec_type = CODEC_TYPE_VIDEO;
} else {
Fabrice Bellard
committed
int i;
AVCodec *codec;
AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
Fabrice Bellard
committed
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
if (video_codec_name)
codec_id = find_codec_or_die(video_codec_name, CODEC_TYPE_VIDEO, 1);
Fabrice Bellard
committed
video_enc->codec_id = codec_id;
codec = avcodec_find_encoder(codec_id);
char buf[256];
const AVOption *opt;
Baptiste Coudurier
committed
const char *str= av_get_string(avctx_opts[CODEC_TYPE_VIDEO], opt_names[i], &opt, buf, sizeof(buf));
if(str && (opt->flags & AV_OPT_FLAG_VIDEO_PARAM) && (opt->flags & AV_OPT_FLAG_ENCODING_PARAM))
av_set_string(video_enc, opt_names[i], str);
video_enc->time_base.den = fps.num;
video_enc->time_base.num = fps.den;
Fabrice Bellard
committed
if(codec && codec->supported_framerates){
const AVRational *p= codec->supported_framerates;
const AVRational *best=NULL;
AVRational best_error= (AVRational){INT_MAX, 1};
for(; p->den!=0; p++){
AVRational error= av_sub_q(fps, *p);
Fabrice Bellard
committed
if(error.num <0) error.num *= -1;
if(av_cmp_q(error, best_error) < 0){
best_error= error;
best= p;
}
}
video_enc->time_base.den= best->num;
video_enc->time_base.num= best->den;
}
Fabrice Bellard
committed
video_enc->width = frame_width + frame_padright + frame_padleft;
video_enc->height = frame_height + frame_padtop + frame_padbottom;
video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255);
Fabrice Bellard
committed
video_enc->pix_fmt = frame_pix_fmt;
if(codec && codec->pix_fmts){
const enum PixelFormat *p= codec->pix_fmts;
for(; *p!=-1; p++){
if(*p == video_enc->pix_fmt)
break;
}
if(*p == -1)
video_enc->pix_fmt = codec->pix_fmts[0];
}
if (intra_only)
Fabrice Bellard
committed
video_enc->gop_size = 0;
if (video_qscale || same_quality) {
video_enc->flags |= CODEC_FLAG_QSCALE;
Fabrice Bellard
committed
st->quality = FF_QP2LAMBDA * video_qscale;
}
if(intra_matrix)
video_enc->intra_matrix = intra_matrix;
if(inter_matrix)
video_enc->inter_matrix = inter_matrix;
video_enc->max_qdiff = video_qdiff;