#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
-#include "libavformat/framehook.h"
#include "libavcodec/opt.h"
#include "libavcodec/audioconvert.h"
#include "libavutil/fifo.h"
static int subtitle_disable = 0;
static char *subtitle_codec_name = NULL;
static char *subtitle_language = NULL;
+static int subtitle_codec_tag = 0;
static float mux_preload= 0.5;
static float mux_max_delay= 0.7;
static int64_t rec_timestamp = 0;
static int64_t input_ts_offset = 0;
static int file_overwrite = 0;
-static char *str_title = NULL;
-static char *str_author = NULL;
-static char *str_copyright = NULL;
-static char *str_comment = NULL;
-static char *str_genre = NULL;
-static char *str_album = NULL;
+static int metadata_count;
+static AVMetadataTag *metadata;
static int do_benchmark = 0;
static int do_hex_dump = 0;
static int do_pkt_dump = 0;
static int exit_on_error = 0;
static int using_stdin = 0;
-static int using_vhook = 0;
static int verbose = 1;
static int thread_count= 1;
static int q_pressed = 0;
static int64_t timer_start;
+static uint8_t *audio_buf;
+static uint8_t *audio_out;
+static uint8_t *audio_out2;
+
+static short *samples;
+
static AVBitStreamFilterContext *video_bitstream_filters=NULL;
static AVBitStreamFilterContext *audio_bitstream_filters=NULL;
static AVBitStreamFilterContext *subtitle_bitstream_filters=NULL;
ReSampleContext *resample; /* for audio resampling */
int reformat_pair;
AVAudioConvert *reformat_ctx;
- AVFifoBuffer fifo; /* for compression: one audio fifo per codec */
+ AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */
FILE *logfile;
} AVOutputStream;
powerpc_display_perf_report();
#endif /* CONFIG_POWERPC_PERF */
+ for (i=0;i<CODEC_TYPE_NB;i++)
+ av_free(avcodec_opts[i]);
+ av_free(avformat_opts);
+ av_free(sws_opts);
+ av_free(audio_buf);
+ av_free(audio_out);
+ av_free(audio_out2);
+ av_free(samples);
+
if (received_sigterm) {
fprintf(stderr,
"Received signal %d: terminating.\n",
unsigned char *buf, int size)
{
uint8_t *buftmp;
- static uint8_t *audio_buf = NULL;
- static uint8_t *audio_out = NULL;
- static uint8_t *audio_out2 = NULL;
const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE;
int size_out, frame_bytes, ret;
if(audio_sync_method){
double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts
- - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);
+ - av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2);
double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate;
int byte_delta= ((int)idelta)*2*ist->st->codec->channels;
assert(ost->audio_resample);
if(verbose > 2)
fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
-// fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2));
+// fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
}
}
}else
ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate)
- - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong
+ - av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong
if (ost->audio_resample) {
buftmp = audio_buf;
/* now encode as many frames as possible */
if (enc->frame_size > 1) {
/* output resampled raw samples */
- if (av_fifo_realloc2(&ost->fifo, av_fifo_size(&ost->fifo) + size_out) < 0) {
+ if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {
fprintf(stderr, "av_fifo_realloc2() failed\n");
av_exit(1);
}
- av_fifo_generic_write(&ost->fifo, buftmp, size_out, NULL);
+ av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);
frame_bytes = enc->frame_size * osize * enc->channels;
- while (av_fifo_size(&ost->fifo) >= frame_bytes) {
+ while (av_fifo_size(ost->fifo) >= frame_bytes) {
AVPacket pkt;
av_init_packet(&pkt);
- av_fifo_read(&ost->fifo, audio_buf, frame_bytes);
+ av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);
//FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
dec = ist->st->codec;
/* deinterlace : must be done before any resize */
- if (do_deinterlace || using_vhook) {
+ if (do_deinterlace) {
int size;
/* create temporary picture */
picture2 = picture;
}
- if (CONFIG_VHOOK)
- frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height,
- 1000000 * ist->pts / AV_TIME_BASE);
-
if (picture != picture2)
*picture = *picture2;
*bufp = buf;
//FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
if (vdelta < -1.1)
nb_frames = 0;
- else if (video_sync_method == 2 || (video_sync_method<0 && (s->oformat->flags & AVFMT_VARIABLE_FPS)))
+ else if (video_sync_method == 2 || (video_sync_method<0 && (s->oformat->flags & AVFMT_VARIABLE_FPS))){
+ if(vdelta<=-0.6){
+ nb_frames=0;
+ }else if(vdelta>0.6)
ost->sync_opts= lrintf(get_sync_ipts(ost) / av_q2d(enc->time_base));
- else if (vdelta > 1.1)
+ }else if (vdelta > 1.1)
nb_frames = lrintf(vdelta);
//fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, get_sync_ipts(ost), nb_frames);
if (nb_frames == 0){
/* better than nothing: use input picture interlaced
settings */
big_picture.interlaced_frame = in_picture->interlaced_frame;
- if(avctx_opts[CODEC_TYPE_VIDEO]->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)){
+ if(avcodec_opts[CODEC_TYPE_VIDEO]->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)){
if(top_field_first == -1)
big_picture.top_field_first = in_picture->top_field_first;
else
{
char buf[1024];
AVOutputStream *ost;
- AVFormatContext *oc, *os;
+ AVFormatContext *oc;
int64_t total_size;
AVCodecContext *enc;
int frame_number, vid, i;
vid = 0;
for(i=0;i<nb_ostreams;i++) {
ost = ost_table[i];
- os = output_files[ost->file_index];
enc = ost->st->codec;
if (vid && enc->codec_type == CODEC_TYPE_VIDEO) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ",
{
AVFormatContext *os;
AVOutputStream *ost;
- uint8_t *ptr;
- int len, ret, i;
+ int ret, i;
uint8_t *data_buf;
int data_size, got_picture;
AVFrame picture;
void *buffer_to_free;
static unsigned int samples_size= 0;
- static short *samples= NULL;
AVSubtitle subtitle, *subtitle_to_free;
int got_subtitle;
+ AVPacket avpkt;
if(ist->next_pts == AV_NOPTS_VALUE)
ist->next_pts= ist->pts;
if (pkt == NULL) {
/* EOF handling */
- ptr = NULL;
- len = 0;
+ av_init_packet(&avpkt);
+ avpkt.data = NULL;
+ avpkt.size = 0;
goto handle_eof;
+ } else {
+ avpkt = *pkt;
}
if(pkt->dts != AV_NOPTS_VALUE)
ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
- len = pkt->size;
- ptr = pkt->data;
-
//while we have more to decode or while the decoder did output something on EOF
- while (len > 0 || (!pkt && ist->next_pts != ist->pts)) {
+ while (avpkt.size > 0 || (!pkt && ist->next_pts != ist->pts)) {
handle_eof:
ist->pts= ist->next_pts;
- if(len && len != pkt->size && verbose>0)
+ if(avpkt.size && avpkt.size != pkt->size && verbose>0)
fprintf(stderr, "Multiple frames in a packet from stream %d\n", pkt->stream_index);
/* decode the packet if needed */
data_size= samples_size;
/* XXX: could avoid copy if PCM 16 bits with same
endianness as CPU */
- ret = avcodec_decode_audio2(ist->st->codec, samples, &data_size,
- ptr, len);
+ ret = avcodec_decode_audio3(ist->st->codec, samples, &data_size,
+ &avpkt);
if (ret < 0)
goto fail_decode;
- ptr += ret;
- len -= ret;
+ avpkt.data += ret;
+ avpkt.size -= ret;
/* Some bug in mpeg audio decoder gives */
/* data_size < 0, it seems they are overflows */
if (data_size <= 0) {
/* XXX: allocate picture correctly */
avcodec_get_frame_defaults(&picture);
- ret = avcodec_decode_video(ist->st->codec,
- &picture, &got_picture, ptr, len);
+ ret = avcodec_decode_video2(ist->st->codec,
+ &picture, &got_picture, &avpkt);
ist->st->quality= picture.quality;
if (ret < 0)
goto fail_decode;
ist->st->codec->time_base.num * ticks) /
ist->st->codec->time_base.den;
}
- len = 0;
+ avpkt.size = 0;
break;
case CODEC_TYPE_SUBTITLE:
- ret = avcodec_decode_subtitle(ist->st->codec,
- &subtitle, &got_subtitle, ptr, len);
+ ret = avcodec_decode_subtitle2(ist->st->codec,
+ &subtitle, &got_subtitle, &avpkt);
if (ret < 0)
goto fail_decode;
if (!got_subtitle) {
goto discard_packet;
}
subtitle_to_free = &subtitle;
- len = 0;
+ avpkt.size = 0;
break;
default:
goto fail_decode;
}
break;
}
- data_buf = ptr;
- data_size = len;
- ret = len;
- len = 0;
+ data_buf = avpkt.data;
+ data_size = avpkt.size;
+ ret = avpkt.size;
+ avpkt.size = 0;
}
buffer_to_free = NULL;
} else {
AVFrame avframe; //FIXME/XXX remove this
AVPacket opkt;
+ int64_t ost_tb_start_time= av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
+
av_init_packet(&opkt);
if ((!ost->frame_number && !(pkt->flags & PKT_FLAG_KEY)) && !copy_initial_nonkeyframes)
opkt.stream_index= ost->index;
if(pkt->pts != AV_NOPTS_VALUE)
- opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base);
+ opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
else
opkt.pts= AV_NOPTS_VALUE;
opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base);
else
opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
+ opkt.dts -= ost_tb_start_time;
opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
opkt.flags= pkt->flags;
switch(ost->st->codec->codec_type) {
case CODEC_TYPE_AUDIO:
- fifo_bytes = av_fifo_size(&ost->fifo);
+ fifo_bytes = av_fifo_size(ost->fifo);
ret = 0;
/* encode any samples remaining in fifo */
if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
+ int osize = av_get_bits_per_sample_format(enc->sample_fmt) >> 3;
int fs_tmp = enc->frame_size;
- enc->frame_size = fifo_bytes / (2 * enc->channels);
- av_fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes);
- ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+ enc->frame_size = fifo_bytes / (osize * enc->channels);
+ av_fifo_generic_read(ost->fifo, samples, fifo_bytes, NULL);
+ ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
+ pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
+ ost->st->time_base.num, enc->sample_rate);
enc->frame_size = fs_tmp;
}
if(ret <= 0) {
int nb_input_files,
AVStreamMap *stream_maps, int nb_stream_maps)
{
- int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;
+ int ret = 0, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;
AVFormatContext *is, *os;
AVCodecContext *codec, *icodec;
AVOutputStream *ost, **ost_table = NULL;
AVInputStream *ist, **ist_table = NULL;
AVInputFile *file_table;
+ char error[1024];
int key;
int want_sdp = 1;
+ uint8_t no_packet[MAX_FILES]={0};
+ int no_packet_count=0;
file_table= av_mallocz(nb_input_files * sizeof(AVInputFile));
if (!file_table)
/* for each output stream, we compute the right encoding parameters */
for(i=0;i<nb_ostreams;i++) {
+ AVMetadataTag *lang;
ost = ost_table[i];
os = output_files[ost->file_index];
ist = ist_table[ost->source_index];
codec = ost->st->codec;
icodec = ist->st->codec;
- if (!ost->st->language[0])
- av_strlcpy(ost->st->language, ist->st->language,
- sizeof(ost->st->language));
+ if ((lang=av_metadata_get(ist->st->metadata, "language", NULL, 0))
+ && !av_metadata_get(ost->st->metadata, "language", NULL, 0))
+ av_metadata_set(&ost->st->metadata, "language", lang->value);
ost->st->disposition = ist->st->disposition;
codec->block_align= 0;
break;
case CODEC_TYPE_VIDEO:
- if(using_vhook) {
- fprintf(stderr,"-vcodec copy and -vhook are incompatible (frames are not decoded)\n");
- av_exit(1);
- }
codec->pix_fmt = icodec->pix_fmt;
codec->width = icodec->width;
codec->height = icodec->height;
} else {
switch(codec->codec_type) {
case CODEC_TYPE_AUDIO:
- if (av_fifo_init(&ost->fifo, 1024))
+ ost->fifo= av_fifo_alloc(1024);
+ if(!ost->fifo)
goto fail;
ost->reformat_pair = MAKE_SFMT_PAIR(SAMPLE_FMT_NONE,SAMPLE_FMT_NONE);
ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
if (!bit_buffer)
bit_buffer = av_malloc(bit_buffer_size);
- if (!bit_buffer)
+ if (!bit_buffer) {
+ ret = AVERROR(ENOMEM);
goto fail;
-
- /* 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");
- }
}
/* open each encoder */
if (!codec)
codec = avcodec_find_encoder(ost->st->codec->codec_id);
if (!codec) {
- fprintf(stderr, "Unsupported codec for output stream #%d.%d\n",
+ snprintf(error, sizeof(error), "Unsupported codec for output stream #%d.%d",
ost->file_index, ost->index);
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto dump_format;
}
if (avcodec_open(ost->st->codec, codec) < 0) {
- fprintf(stderr, "Error while opening codec for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height\n",
+ snprintf(error, sizeof(error), "Error while opening codec for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",
ost->file_index, ost->index);
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto dump_format;
}
extra_size += ost->st->codec->extradata_size;
}
if (!codec)
codec = avcodec_find_decoder(ist->st->codec->codec_id);
if (!codec) {
- fprintf(stderr, "Unsupported codec (id=%d) for input stream #%d.%d\n",
+ snprintf(error, sizeof(error), "Unsupported codec (id=%d) for input stream #%d.%d",
ist->st->codec->codec_id, ist->file_index, ist->index);
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto dump_format;
}
if (avcodec_open(ist->st->codec, codec) < 0) {
- fprintf(stderr, "Error while opening codec for input stream #%d.%d\n",
+ snprintf(error, sizeof(error), "Error while opening codec for input stream #%d.%d",
ist->file_index, ist->index);
- av_exit(1);
+ ret = AVERROR(EINVAL);
+ goto dump_format;
}
//if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO)
// ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD;
/* init pts */
for(i=0;i<nb_istreams;i++) {
ist = ist_table[i];
- is = input_files[ist->file_index];
ist->pts = 0;
ist->next_pts = AV_NOPTS_VALUE;
ist->is_start = 1;
for (i=0;i<nb_meta_data_maps;i++) {
AVFormatContext *out_file;
AVFormatContext *in_file;
+ AVMetadataTag *mtag;
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) {
- fprintf(stderr, "Invalid output file index %d map_meta_data(%d,%d)\n", out_file_index, out_file_index, in_file_index);
+ 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 fail;
+ goto dump_format;
}
if (in_file_index < 0 || in_file_index >= nb_input_files) {
- fprintf(stderr, "Invalid input file index %d map_meta_data(%d,%d)\n", in_file_index, out_file_index, in_file_index);
+ 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 fail;
+ goto dump_format;
}
out_file = output_files[out_file_index];
in_file = input_files[in_file_index];
- strcpy(out_file->title, in_file->title);
- strcpy(out_file->author, in_file->author);
- strcpy(out_file->copyright, in_file->copyright);
- strcpy(out_file->comment, in_file->comment);
- strcpy(out_file->album, in_file->album);
- out_file->year = in_file->year;
- out_file->track = in_file->track;
- strcpy(out_file->genre, in_file->genre);
+
+ 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);
}
/* open files and write file headers */
for(i=0;i<nb_output_files;i++) {
os = output_files[i];
if (av_write_header(os) < 0) {
- fprintf(stderr, "Could not write header for output file #%d (incorrect codec parameters ?)\n", i);
+ snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
ret = AVERROR(EINVAL);
- goto fail;
+ goto dump_format;
}
if (strcmp(output_files[i]->oformat->name, "rtp")) {
want_sdp = 0;
}
}
+
+ 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);
}
}
term_init();
- key = -1;
timer_start = av_gettime();
for(; received_sigterm == 0;) {
ost = ost_table[i];
os = output_files[ost->file_index];
ist = ist_table[ost->source_index];
+ if(no_packet[ist->file_index])
+ continue;
if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO)
opts = ost->sync_opts * av_q2d(ost->st->codec->time_base);
else
}
/* if none, if is finished */
if (file_index < 0) {
+ if(no_packet_count){
+ no_packet_count=0;
+ memset(no_packet, 0, sizeof(no_packet));
+ usleep(10000);
+ continue;
+ }
break;
}
/* read a frame from it and output it in the fifo */
is = input_files[file_index];
ret= av_read_frame(is, &pkt);
- if(ret == AVERROR(EAGAIN) && strcmp(is->iformat->name, "ffm"))
+ if(ret == AVERROR(EAGAIN)){
+ no_packet[file_index]=1;
+ no_packet_count++;
continue;
+ }
if (ret < 0) {
file_table[file_index].eof_reached = 1;
if (opt_shortest)
continue;
}
+ no_packet_count=0;
+ memset(no_packet, 0, sizeof(no_packet));
+
if (do_pkt_dump) {
av_pkt_dump_log(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump);
}
}
/* finished ! */
-
ret = 0;
- fail1:
+
+ fail:
av_freep(&bit_buffer);
av_free(file_table);
fclose(ost->logfile);
ost->logfile = NULL;
}
- av_fifo_free(&ost->fifo); /* works even if fifo is not
+ av_fifo_free(ost->fifo); /* works even if fifo is not
initialized but set to zero */
av_free(ost->pict_tmp.data[0]);
if (ost->video_resample)
av_free(ost_table);
}
return ret;
- fail:
- ret = AVERROR(ENOMEM);
- goto fail1;
}
#if 0
return 0;
}
+static void opt_loglevel(const char *opt, const char *arg)
+{
+ int level = parse_number_or_die(opt, arg, OPT_INT, INT_MIN, INT_MAX);
+ av_log_set_level(level);
+}
+
static int opt_verbose(const char *opt, const char *arg)
{
verbose = parse_number_or_die(opt, arg, OPT_INT64, -10, 10);
- av_log_set_level(verbose);
return 0;
}
opt_default(opt, arg);
- if (av_get_int(avctx_opts[codec_type], "b", NULL) < 1000)
+ 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_pix_fmt(const char *arg)
{
- if (strcmp(arg, "list"))
+ if (strcmp(arg, "list")) {
frame_pix_fmt = avcodec_get_pix_fmt(arg);
- else {
+ 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);
av_exit(0);
}
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)
{
video_qscale = atof(arg);
video_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24);
}
-#if CONFIG_VHOOK
-static void add_frame_hooker(const char *arg)
-{
- int argc = 0;
- char *argv[64];
- int i;
- char *args = av_strdup(arg);
-
- 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);
- av_exit(1);
- }
-}
-#endif
-
static void opt_video_codec(const char *arg)
{
opt_codec(&video_stream_copy, &video_codec_name, CODEC_TYPE_VIDEO, 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)
{
AVStreamMap *m;
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);
+ ic->flags |= AVFMT_FLAG_NONBLOCK;
/* open the input file with generic libav function */
err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
enc->thread_count= thread_count;
switch(enc->codec_type) {
case CODEC_TYPE_AUDIO:
- set_context_opts(enc, avctx_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
+ 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;
ic->streams[i]->discard= AVDISCARD_ALL;
break;
case CODEC_TYPE_VIDEO:
- set_context_opts(enc, avctx_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
+ set_context_opts(enc, avcodec_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM);
frame_height = enc->height;
frame_width = enc->width;
if(ic->streams[i]->sample_aspect_ratio.num)
if( (video_global_header&1)
|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
- avctx_opts[CODEC_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
+ avcodec_opts[CODEC_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
}
if(video_global_header&2){
video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER;
- avctx_opts[CODEC_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER;
+ avcodec_opts[CODEC_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER;
}
if (video_stream_copy) {
video_enc->codec_id = codec_id;
- set_context_opts(video_enc, avctx_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
+ set_context_opts(video_enc, avcodec_opts[CODEC_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
if (codec && codec->supported_framerates && !force_fps)
fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)];
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
- avctx_opts[CODEC_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
+ avcodec_opts[CODEC_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
}
if (audio_stream_copy) {
st->stream_copy = 1;
} else {
AVCodec *codec;
- set_context_opts(audio_enc, avctx_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
+ set_context_opts(audio_enc, avcodec_opts[CODEC_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
if (audio_codec_name) {
codec_id = find_codec_or_die(audio_codec_name, CODEC_TYPE_AUDIO, 1);
audio_enc->channels = audio_channels;
audio_enc->sample_fmt = audio_sample_fmt;
audio_enc->channel_layout = channel_layout;
+ if (avcodec_channel_layout_num_channels(channel_layout) != audio_channels)
+ audio_enc->channel_layout = 0;
if(codec && codec->sample_fmts){
const enum SampleFormat *p= codec->sample_fmts;
audio_enc->sample_rate = audio_sample_rate;
audio_enc->time_base= (AVRational){1, audio_sample_rate};
if (audio_language) {
- av_strlcpy(st->language, audio_language, sizeof(st->language));
+ av_metadata_set(&st->metadata, "language", audio_language);
av_free(audio_language);
audio_language = NULL;
}
subtitle_enc = st->codec;
subtitle_enc->codec_type = CODEC_TYPE_SUBTITLE;
+
+ if(subtitle_codec_tag)
+ subtitle_enc->codec_tag= subtitle_codec_tag;
+
if (subtitle_stream_copy) {
st->stream_copy = 1;
} else {
- set_context_opts(avctx_opts[CODEC_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
+ set_context_opts(avcodec_opts[CODEC_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM);
subtitle_enc->codec_id = find_codec_or_die(subtitle_codec_name, CODEC_TYPE_SUBTITLE, 1);
output_codecs[nb_ocodecs] = avcodec_find_encoder_by_name(subtitle_codec_name);
}
nb_ocodecs++;
if (subtitle_language) {
- av_strlcpy(st->language, subtitle_language, sizeof(st->language));
+ av_metadata_set(&st->metadata, "language", subtitle_language);
av_free(subtitle_language);
subtitle_language = NULL;
}
oc->timestamp = rec_timestamp;
- if (str_title)
- av_strlcpy(oc->title, str_title, sizeof(oc->title));
- if (str_author)
- av_strlcpy(oc->author, str_author, sizeof(oc->author));
- if (str_copyright)
- av_strlcpy(oc->copyright, str_copyright, sizeof(oc->copyright));
- if (str_comment)
- av_strlcpy(oc->comment, str_comment, sizeof(oc->comment));
- if (str_album)
- av_strlcpy(oc->album, str_album, sizeof(oc->album));
- if (str_genre)
- av_strlcpy(oc->genre, str_genre, sizeof(oc->genre));
+ for(; metadata_count>0; metadata_count--){
+ av_metadata_set(&oc->metadata, metadata[metadata_count-1].key,
+ metadata[metadata_count-1].value);
+ }
+ av_metadata_conv(oc, oc->oformat->metadata_conv, NULL);
}
output_files[nb_output_files++] = oc;
filename[1] == ':' ||
av_strstart(filename, "file:", NULL))) {
if (url_exist(filename)) {
- int c;
-
if (!using_stdin) {
fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
fflush(stderr);
- c = getchar();
- if (toupper(c) != 'Y') {
+ if (!read_yesno()) {
fprintf(stderr, "Not overwriting - exiting\n");
av_exit(1);
}
oc->preload= (int)(mux_preload*AV_TIME_BASE);
oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
oc->loop_output = loop_output;
+ oc->flags |= AVFMT_FLAG_NONBLOCK;
set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM);
OPT_GRAB,
OPT_GRAB);
printf("\n");
- av_opt_show(avctx_opts[0], NULL);
+ av_opt_show(avcodec_opts[0], NULL);
printf("\n");
av_opt_show(avformat_opts, NULL);
printf("\n");
{ "ss", OPT_FUNC2 | HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
{ "itsoffset", OPT_FUNC2 | HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
{ "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "stream:scale" },
- { "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" },
{ "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)&opt_rec_timestamp}, "set the timestamp ('now' to set the current time)", "time" },
- { "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
- { "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "string" },
- { "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" },
- { "genre", HAS_ARG | OPT_STRING, {(void*)&str_genre}, "set the genre", "string" },
- { "album", HAS_ARG | OPT_STRING, {(void*)&str_album}, "set the album", "string" },
+ { "metadata", OPT_FUNC2 | HAS_ARG, {(void*)&opt_metadata}, "add metadata", "string=string" },
{ "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" },
{ "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
"add timings for benchmarking" },
{ "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
{ "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
{ "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "number of times to loop output in formats that support looping (0 loops forever)", "" },
- { "v", HAS_ARG | OPT_FUNC2, {(void*)opt_verbose}, "set the logging verbosity level", "number" },
+ { "v", HAS_ARG | OPT_FUNC2, {(void*)opt_verbose}, "set ffmpeg verbosity level", "number" },
+ { "loglevel", HAS_ARG | OPT_FUNC2, {(void*)opt_loglevel}, "set libav* logging level", "number" },
{ "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
{ "threads", OPT_FUNC2 | HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
{ "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
{ "psnr", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
{ "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
{ "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" },
-#if CONFIG_VHOOK
- { "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
-#endif
{ "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
{ "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },
{ "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" },
{ "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" },
{ "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" },
{ "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" },
+ { "stag", HAS_ARG | OPT_EXPERT | OPT_SUBTITLE, {(void*)opt_subtitle_tag}, "force subtitle tag/fourcc", "fourcc/tag" },
/* grab options */
{ "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" },
url_set_interrupt_cb(decode_interrupt_cb);
for(i=0; i<CODEC_TYPE_NB; i++){
- avctx_opts[i]= avcodec_alloc_context2(i);
+ avcodec_opts[i]= avcodec_alloc_context2(i);
}
avformat_opts = avformat_alloc_context();
sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);