X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=2988419267041e68dc0ea500607c1632527e98b0;hb=930aa451321c4e44fb3663f34dfee024001d0aff;hp=5181d614f99b302b0f41c4a608ea066ab720106e;hpb=fdf119062e21547fbd9c3bb465cf6b2a276359ae;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index 5181d614f99..29884192670 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -36,6 +36,7 @@ #include "libswscale/swscale.h" #include "libavcodec/opt.h" #include "libavcodec/audioconvert.h" +#include "libavcodec/colorspace.h" #include "libavutil/fifo.h" #include "libavutil/avstring.h" #include "libavformat/os_support.h" @@ -129,11 +130,6 @@ static AVRational frame_rate; static float video_qscale = 0; static uint16_t *intra_matrix = NULL; static uint16_t *inter_matrix = NULL; -#if 0 //experimental, (can be removed) -static float video_rc_qsquish=1.0; -static float video_rc_qmod_amp=0; -static int video_rc_qmod_freq=0; -#endif static const char *video_rc_override_string=NULL; static int video_disable = 0; static int video_discard = 0; @@ -162,6 +158,7 @@ static char *audio_language = NULL; 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; @@ -221,6 +218,12 @@ static unsigned int sws_flags = SWS_BICUBIC; 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; @@ -247,13 +250,29 @@ typedef struct AVOutputStream { AVFrame pict_tmp; /* temporary image for resampling */ struct SwsContext *img_resample_ctx; /* for image resampling */ int resample_height; + int resample_width; + int resample_pix_fmt; + /* full frame size of first frame */ + int original_height; + int original_width; + + /* cropping area sizes */ int video_crop; - int topBand; /* cropping area sizes */ + int topBand; + int bottomBand; int leftBand; + int rightBand; + + /* cropping area of first frame */ + int original_topBand; + int original_bottomBand; + int original_leftBand; + int original_rightBand; + /* padding area sizes */ int video_pad; - int padtop; /* padding area sizes */ + int padtop; int padbottom; int padleft; int padright; @@ -263,7 +282,7 @@ typedef struct AVOutputStream { 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; @@ -302,7 +321,7 @@ static void term_exit(void) #endif } -static volatile sig_atomic_t received_sigterm = 0; +static volatile int received_sigterm = 0; static void sigterm_handler(int sig) @@ -426,6 +445,15 @@ static int av_exit(int ret) powerpc_display_perf_report(); #endif /* CONFIG_POWERPC_PERF */ + for (i=0;istreams[i], sizeof(AVStream)); st->codec = avcodec_alloc_context(); + if (!st->codec) { + print_error(filename, AVERROR(ENOMEM)); + av_exit(1); + } memcpy(st->codec, ic->streams[i]->codec, sizeof(AVCodecContext)); s->streams[i] = st; @@ -526,9 +558,6 @@ static void do_audio_out(AVFormatContext *s, 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; @@ -585,7 +614,7 @@ static void do_audio_out(AVFormatContext *s, 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; @@ -622,13 +651,13 @@ static void do_audio_out(AVFormatContext *s, 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; @@ -660,19 +689,19 @@ static void do_audio_out(AVFormatContext *s, /* 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() @@ -746,17 +775,13 @@ static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void picture2 = &picture_tmp; avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height); - if (do_deinterlace){ - if(avpicture_deinterlace(picture2, picture, - dec->pix_fmt, dec->width, dec->height) < 0) { - /* if error, do not deinterlace */ - fprintf(stderr, "Deinterlacing failed\n"); - av_free(buf); - buf = NULL; - picture2 = picture; - } - } else { - av_picture_copy(picture2, picture, dec->pix_fmt, dec->width, dec->height); + if(avpicture_deinterlace(picture2, picture, + dec->pix_fmt, dec->width, dec->height) < 0) { + /* if error, do not deinterlace */ + fprintf(stderr, "Deinterlacing failed\n"); + av_free(buf); + buf = NULL; + picture2 = picture; } } else { picture2 = picture; @@ -777,7 +802,7 @@ static void do_subtitle_out(AVFormatContext *s, int64_t pts) { static uint8_t *subtitle_out = NULL; - int subtitle_out_max_size = 65536; + int subtitle_out_max_size = 1024 * 1024; int subtitle_out_size, nb, i; AVCodecContext *enc; AVPacket pkt; @@ -804,14 +829,23 @@ static void do_subtitle_out(AVFormatContext *s, nb = 1; for(i = 0; i < nb; i++) { + sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q); + // start_display_time is required to be 0 + sub->pts += av_rescale_q(sub->start_display_time, (AVRational){1, 1000}, AV_TIME_BASE_Q); + sub->end_display_time -= sub->start_display_time; + sub->start_display_time = 0; subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out, subtitle_out_max_size, sub); + if (subtitle_out_size < 0) { + fprintf(stderr, "Subtitle encoding failed\n"); + av_exit(1); + } av_init_packet(&pkt); pkt.stream_index = ost->index; pkt.data = subtitle_out; pkt.size = subtitle_out_size; - pkt.pts = av_rescale_q(pts, ist->st->time_base, ost->st->time_base); + pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base); if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) { /* XXX: the pts correction is handled here. Maybe handling it in the codec would be better */ @@ -834,6 +868,7 @@ static void do_video_out(AVFormatContext *s, int *frame_size) { int nb_frames, i, ret; + int64_t topBand, bottomBand, leftBand, rightBand; AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src; AVFrame picture_crop_temp, picture_pad_temp; AVCodecContext *enc, *dec; @@ -910,6 +945,48 @@ static void do_video_out(AVFormatContext *s, if (ost->video_resample) { padding_src = NULL; final_picture = &ost->pict_tmp; + if( (ost->resample_height != (ist->st->codec->height - (ost->topBand + ost->bottomBand))) + || (ost->resample_width != (ist->st->codec->width - (ost->leftBand + ost->rightBand))) + || (ost->resample_pix_fmt!= ist->st->codec->pix_fmt) ) { + + fprintf(stderr,"Input Stream #%d.%d frame size changed to %dx%d, %s\n", ist->file_index, ist->index, ist->st->codec->width, ist->st->codec->height,avcodec_get_pix_fmt_name(ist->st->codec->pix_fmt)); + /* keep bands proportional to the frame size */ + topBand = ((int64_t)ist->st->codec->height * ost->original_topBand / ost->original_height) & ~1; + bottomBand = ((int64_t)ist->st->codec->height * ost->original_bottomBand / ost->original_height) & ~1; + leftBand = ((int64_t)ist->st->codec->width * ost->original_leftBand / ost->original_width) & ~1; + rightBand = ((int64_t)ist->st->codec->width * ost->original_rightBand / ost->original_width) & ~1; + + /* sanity check to ensure no bad band sizes sneak in */ + assert(topBand <= INT_MAX && topBand >= 0); + assert(bottomBand <= INT_MAX && bottomBand >= 0); + assert(leftBand <= INT_MAX && leftBand >= 0); + assert(rightBand <= INT_MAX && rightBand >= 0); + + ost->topBand = topBand; + ost->bottomBand = bottomBand; + ost->leftBand = leftBand; + ost->rightBand = rightBand; + + ost->resample_height = ist->st->codec->height - (ost->topBand + ost->bottomBand); + ost->resample_width = ist->st->codec->width - (ost->leftBand + ost->rightBand); + ost->resample_pix_fmt= ist->st->codec->pix_fmt; + + /* initialize a new scaler context */ + sws_freeContext(ost->img_resample_ctx); + sws_flags = av_get_int(sws_opts, "sws_flags", NULL); + ost->img_resample_ctx = sws_getContext( + ist->st->codec->width - (ost->leftBand + ost->rightBand), + ist->st->codec->height - (ost->topBand + ost->bottomBand), + ist->st->codec->pix_fmt, + ost->st->codec->width - (ost->padleft + ost->padright), + ost->st->codec->height - (ost->padtop + ost->padbottom), + ost->st->codec->pix_fmt, + sws_flags, NULL, NULL, NULL); + if (ost->img_resample_ctx == NULL) { + fprintf(stderr, "Cannot get resampling context\n"); + av_exit(1); + } + } sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize, 0, ost->resample_height, resampling_dst->data, resampling_dst->linesize); } @@ -946,7 +1023,7 @@ static void do_video_out(AVFormatContext *s, /* 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 @@ -972,7 +1049,7 @@ static void do_video_out(AVFormatContext *s, fprintf(stderr, "Video encoding failed\n"); av_exit(1); } - //enc->frame_number = enc->real_pict_num; + if(ret>0){ pkt.data= bit_buffer; pkt.size= ret; @@ -987,9 +1064,8 @@ static void do_video_out(AVFormatContext *s, write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]); *frame_size = ret; video_size += ret; - //fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d", - // enc->frame_number-1, enc->real_pict_num, ret, - // enc->pict_type); + //fprintf(stderr,"\nFrame: %3d size: %5d type: %d", + // enc->frame_number-1, ret, enc->pict_type); /* if two pass, output log */ if (ost->logfile && enc->stats_out) { fprintf(ost->logfile, "%s", enc->stats_out); @@ -1048,7 +1124,7 @@ static void print_report(AVFormatContext **output_files, { char buf[1024]; AVOutputStream *ost; - AVFormatContext *oc, *os; + AVFormatContext *oc; int64_t total_size; AVCodecContext *enc; int frame_number, vid, i; @@ -1081,7 +1157,6 @@ static void print_report(AVFormatContext **output_files, vid = 0; for(i=0;ifile_index]; enc = ost->st->codec; if (vid && enc->codec_type == CODEC_TYPE_VIDEO) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", @@ -1173,39 +1248,40 @@ static int output_packet(AVInputStream *ist, int ist_index, { 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; + int bps = av_get_bits_per_sample_format(ist->st->codec->sample_fmt)>>3; 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 && + !(ist->st->codec->codec->capabilities & CODEC_CAP_SUBFRAMES) && verbose>0) fprintf(stderr, "Multiple frames in a packet from stream %d\n", pkt->stream_index); /* decode the packet if needed */ @@ -1223,12 +1299,12 @@ static int output_packet(AVInputStream *ist, int ist_index, 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) { @@ -1236,7 +1312,7 @@ static int output_packet(AVInputStream *ist, int ist_index, continue; } data_buf = (uint8_t *)samples; - ist->next_pts += ((int64_t)AV_TIME_BASE/2 * data_size) / + ist->next_pts += ((int64_t)AV_TIME_BASE/bps * data_size) / (ist->st->codec->sample_rate * ist->st->codec->channels); break;} case CODEC_TYPE_VIDEO: @@ -1244,8 +1320,8 @@ static int output_packet(AVInputStream *ist, int ist_index, /* 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; @@ -1259,18 +1335,18 @@ static int output_packet(AVInputStream *ist, int ist_index, 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; @@ -1290,10 +1366,10 @@ static int output_packet(AVInputStream *ist, int ist_index, } 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; @@ -1334,12 +1410,6 @@ static int output_packet(AVInputStream *ist, int ist_index, if (ost->source_index == ist_index) { os = output_files[ost->file_index]; -#if 0 - printf("%d: got pts=%0.3f %0.3f\n", i, - (double)pkt->pts / AV_TIME_BASE, - ((double)ist->pts / AV_TIME_BASE) - - ((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den)); -#endif /* set the input output pts pairs */ //ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE; @@ -1363,6 +1433,8 @@ static int output_packet(AVInputStream *ist, int ist_index, } 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) @@ -1384,7 +1456,7 @@ static int output_packet(AVInputStream *ist, int ist_index, 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; @@ -1392,13 +1464,19 @@ static int output_packet(AVInputStream *ist, int ist_index, 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; //FIXME remove the following 2 lines they shall be replaced by the bitstream filters + if(ost->st->codec->codec_id != CODEC_ID_H264) { if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY)) opkt.destruct= av_destruct_packet; + } else { + opkt.data = data_buf; + opkt.size = data_size; + } write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][opkt.stream_index]); ost->st->codec->frame_number++; @@ -1446,14 +1524,26 @@ static int output_packet(AVInputStream *ist, int ist_index, 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) { + if (fifo_bytes > 0) { + 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); + + av_fifo_generic_read(ost->fifo, samples, fifo_bytes, NULL); + if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { + enc->frame_size = fifo_bytes / (osize * enc->channels); + } else { /* pad */ + int frame_bytes = enc->frame_size*osize*enc->channels; + if (samples_size < frame_bytes) + av_exit(1); + memset((uint8_t*)samples+fifo_bytes, 0, frame_bytes - fifo_bytes); + } + + 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) { @@ -1545,14 +1635,17 @@ static int av_encode(AVFormatContext **output_files, 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) @@ -1728,6 +1821,8 @@ static int av_encode(AVFormatContext **output_files, av_metadata_set(&ost->st->metadata, "language", lang->value); ost->st->disposition = ist->st->disposition; + codec->bits_per_raw_sample= icodec->bits_per_raw_sample; + codec->chroma_sample_location = icodec->chroma_sample_location; if (ost->st->stream_copy) { /* if stream_copy is selected, no need to decode or encode */ @@ -1781,7 +1876,8 @@ static int av_encode(AVFormatContext **output_files, } 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; @@ -1790,6 +1886,10 @@ static int av_encode(AVFormatContext **output_files, ost->encoding_needed = 1; break; case CODEC_TYPE_VIDEO: + if (ost->st->codec->pix_fmt == PIX_FMT_NONE) { + fprintf(stderr, "Video pixel format is unknown, stream cannot be decoded\n"); + av_exit(1); + } ost->video_crop = ((frame_leftBand + frame_rightBand + frame_topBand + frame_bottomBand) != 0); ost->video_pad = ((frame_padleft + frame_padright + frame_padtop + frame_padbottom) != 0); ost->video_resample = ((codec->width != icodec->width - @@ -1800,8 +1900,10 @@ static int av_encode(AVFormatContext **output_files, (frame_padtop + frame_padbottom)) || (codec->pix_fmt != icodec->pix_fmt)); if (ost->video_crop) { - ost->topBand = frame_topBand; - ost->leftBand = frame_leftBand; + ost->topBand = ost->original_topBand = frame_topBand; + ost->bottomBand = ost->original_bottomBand = frame_bottomBand; + ost->leftBand = ost->original_leftBand = frame_leftBand; + ost->rightBand = ost->original_rightBand = frame_rightBand; } if (ost->video_pad) { ost->padtop = frame_padtop; @@ -1835,7 +1937,14 @@ static int av_encode(AVFormatContext **output_files, fprintf(stderr, "Cannot get resampling context\n"); av_exit(1); } - ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand); + + ost->original_height = icodec->height; + ost->original_width = icodec->width; + + ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand); + ost->resample_width = icodec->width - (frame_leftBand + frame_rightBand); + ost->resample_pix_fmt= icodec->pix_fmt; + codec->bits_per_raw_sample= 0; } ost->encoding_needed = 1; ist->decoding_needed = 1; @@ -1896,31 +2005,11 @@ static int av_encode(AVFormatContext **output_files, if (!bit_buffer) bit_buffer = av_malloc(bit_buffer_size); - if (!bit_buffer) + if (!bit_buffer) { + fprintf(stderr, "Cannot allocate %d bytes output buffer\n", + bit_buffer_size); + ret = AVERROR(ENOMEM); goto fail; - - /* dump the file output parameters - cannot be done before in case - of stream copy */ - for(i=0;ifilename, 1); - } - - /* dump the stream mapping */ - if (verbose >= 0) { - fprintf(stderr, "Stream mapping:\n"); - for(i=0;i #%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 */ @@ -1931,14 +2020,16 @@ static int av_encode(AVFormatContext **output_files, if (!codec) codec = avcodec_find_encoder(ost->st->codec->codec_id); if (!codec) { - fprintf(stderr, "Unsupported codec for output stream #%d.%d\n", - ost->file_index, ost->index); - av_exit(1); + snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d", + ost->st->codec->codec_id, ost->file_index, ost->index); + 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 encoder 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; } @@ -1952,14 +2043,16 @@ static int av_encode(AVFormatContext **output_files, 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), "Decoder (codec id %d) not found 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 decoder 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; @@ -1969,7 +2062,6 @@ static int av_encode(AVFormatContext **output_files, /* init pts */ for(i=0;ifile_index]; ist->pts = 0; ist->next_pts = AV_NOPTS_VALUE; ist->is_start = 1; @@ -1984,14 +2076,16 @@ static int av_encode(AVFormatContext **output_files, 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]; @@ -2009,14 +2103,45 @@ static int av_encode(AVFormatContext **output_files, for(i=0;ioformat->name, "rtp")) { want_sdp = 0; } } + + dump_format: + /* dump the file output parameters - cannot be done before in case + of stream copy */ + for(i=0;ifilename, 1); + } + + /* dump the stream mapping */ + if (verbose >= 0) { + fprintf(stderr, "Stream mapping:\n"); + for(i=0;i #%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); } @@ -2027,7 +2152,6 @@ static int av_encode(AVFormatContext **output_files, } term_init(); - key = -1; timer_start = av_gettime(); for(; received_sigterm == 0;) { @@ -2057,6 +2181,8 @@ static int av_encode(AVFormatContext **output_files, 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 @@ -2079,6 +2205,12 @@ static int av_encode(AVFormatContext **output_files, } /* 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; } @@ -2093,8 +2225,11 @@ static int av_encode(AVFormatContext **output_files, /* 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) @@ -2103,6 +2238,9 @@ static int av_encode(AVFormatContext **output_files, 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); } @@ -2198,9 +2336,9 @@ static int av_encode(AVFormatContext **output_files, } /* finished ! */ - ret = 0; - fail1: + + fail: av_freep(&bit_buffer); av_free(file_table); @@ -2219,7 +2357,7 @@ static int av_encode(AVFormatContext **output_files, 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) @@ -2234,32 +2372,7 @@ static int av_encode(AVFormatContext **output_files, av_free(ost_table); } return ret; - fail: - ret = AVERROR(ENOMEM); - 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= frame_height){ fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n"); av_exit(1); @@ -2343,10 +2451,6 @@ static void opt_frame_crop_bottom(const char *arg) fprintf(stderr, "Incorrect bottom crop size\n"); av_exit(1); } - if ((frame_bottomBand % 2) != 0) { - fprintf(stderr, "Bottom crop size must be a multiple of 2\n"); - av_exit(1); - } 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"); av_exit(1); @@ -2361,10 +2465,6 @@ static void opt_frame_crop_left(const char *arg) fprintf(stderr, "Incorrect left crop size\n"); av_exit(1); } - if ((frame_leftBand % 2) != 0) { - fprintf(stderr, "Left crop size must be a multiple of 2\n"); - av_exit(1); - } 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"); av_exit(1); @@ -2379,10 +2479,6 @@ static void opt_frame_crop_right(const char *arg) fprintf(stderr, "Incorrect right crop size\n"); av_exit(1); } - if ((frame_rightBand % 2) != 0) { - fprintf(stderr, "Right crop size must be a multiple of 2\n"); - av_exit(1); - } 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"); av_exit(1); @@ -2402,23 +2498,6 @@ static void opt_frame_size(const char *arg) } } - -#define SCALEBITS 10 -#define ONE_HALF (1 << (SCALEBITS - 1)) -#define FIX(x) ((int) ((x) * (1<> 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 #) */ @@ -2441,10 +2520,6 @@ static void opt_frame_pad_top(const char *arg) fprintf(stderr, "Incorrect top pad size\n"); av_exit(1); } - if ((frame_padtop % 2) != 0) { - fprintf(stderr, "Top pad size must be a multiple of 2\n"); - av_exit(1); - } } static void opt_frame_pad_bottom(const char *arg) @@ -2454,10 +2529,6 @@ static void opt_frame_pad_bottom(const char *arg) fprintf(stderr, "Incorrect bottom pad size\n"); av_exit(1); } - if ((frame_padbottom % 2) != 0) { - fprintf(stderr, "Bottom pad size must be a multiple of 2\n"); - av_exit(1); - } } @@ -2468,10 +2539,6 @@ static void opt_frame_pad_left(const char *arg) fprintf(stderr, "Incorrect left pad size\n"); av_exit(1); } - if ((frame_padleft % 2) != 0) { - fprintf(stderr, "Left pad size must be a multiple of 2\n"); - av_exit(1); - } } @@ -2482,10 +2549,6 @@ static void opt_frame_pad_right(const char *arg) fprintf(stderr, "Incorrect right pad size\n"); av_exit(1); } - if ((frame_padright % 2) != 0) { - fprintf(stderr, "Right pad size must be a multiple of 2\n"); - av_exit(1); - } } static void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts) @@ -2500,9 +2563,13 @@ static void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), 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); } @@ -2651,6 +2718,15 @@ 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) { AVStreamMap *m; @@ -2766,6 +2842,10 @@ static void opt_input_file(const char *filename) /* get default parameters from command line */ ic = avformat_alloc_context(); + if (!ic) { + print_error(filename, AVERROR(ENOMEM)); + av_exit(1); + } memset(ap, 0, sizeof(*ap)); ap->prealloced_context = 1; @@ -2789,6 +2869,7 @@ static void opt_input_file(const char *filename) 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); @@ -2837,7 +2918,7 @@ static void opt_input_file(const char *filename) 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; @@ -2848,7 +2929,7 @@ static void opt_input_file(const char *filename) 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) @@ -2955,7 +3036,7 @@ static void new_video_stream(AVFormatContext *oc) { AVStream *st; AVCodecContext *video_enc; - int codec_id; + enum CodecID codec_id; st = av_new_stream(oc, oc->nb_streams); if (!st) { @@ -2977,11 +3058,11 @@ static void new_video_stream(AVFormatContext *oc) 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) { @@ -3006,7 +3087,7 @@ static void new_video_stream(AVFormatContext *oc) 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)]; @@ -3097,7 +3178,7 @@ static void new_audio_stream(AVFormatContext *oc) { AVStream *st; AVCodecContext *audio_enc; - int codec_id; + enum CodecID codec_id; st = av_new_stream(oc, oc->nb_streams); if (!st) { @@ -3120,7 +3201,7 @@ static void new_audio_stream(AVFormatContext *oc) 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; @@ -3128,7 +3209,7 @@ static void new_audio_stream(AVFormatContext *oc) } 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); @@ -3148,6 +3229,8 @@ static void new_audio_stream(AVFormatContext *oc) 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; @@ -3191,10 +3274,14 @@ static void new_subtitle_stream(AVFormatContext *oc) 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); } @@ -3255,6 +3342,10 @@ static void opt_output_file(const char *filename) filename = "pipe:"; oc = avformat_alloc_context(); + if (!oc) { + print_error(filename, AVERROR(ENOMEM)); + av_exit(1); + } if (!file_oformat) { file_oformat = guess_format(NULL, filename, NULL); @@ -3344,13 +3435,10 @@ static void opt_output_file(const char *filename) 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); } @@ -3379,6 +3467,7 @@ static void opt_output_file(const char *filename) 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); @@ -3485,7 +3574,7 @@ static void show_help(void) 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"); @@ -3556,7 +3645,7 @@ static void opt_target(const char *arg) opt_frame_size(norm ? "352x240" : "352x288"); opt_frame_rate(NULL, frame_rates[norm]); - opt_default("gop", norm ? "18" : "15"); + opt_default("g", norm ? "18" : "15"); opt_default("b", "1150000"); opt_default("maxrate", "1150000"); @@ -3584,7 +3673,7 @@ static void opt_target(const char *arg) opt_frame_size(norm ? "480x480" : "480x576"); opt_frame_rate(NULL, frame_rates[norm]); - opt_default("gop", norm ? "18" : "15"); + opt_default("g", norm ? "18" : "15"); opt_default("b", "2040000"); opt_default("maxrate", "2516000"); @@ -3606,7 +3695,7 @@ static void opt_target(const char *arg) opt_frame_size(norm ? "720x480" : "720x576"); opt_frame_rate(NULL, frame_rates[norm]); - opt_default("gop", norm ? "18" : "15"); + opt_default("g", norm ? "18" : "15"); opt_default("b", "6000000"); opt_default("maxrate", "9000000"); @@ -3748,8 +3837,8 @@ static const OptionDef options[] = { { "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" }, - { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)&opt_rec_timestamp}, "set the timestamp ('now' to set the current time)", "time" }, - { "metadata", OPT_FUNC2 | HAS_ARG, {(void*)&opt_metadata}, "add metadata", "string=string" }, + { "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)opt_rec_timestamp}, "set the timestamp ('now' to set the current time)", "time" }, + { "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" }, @@ -3760,7 +3849,8 @@ static const OptionDef options[] = { { "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", "loglevel" }, { "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", "" }, @@ -3835,6 +3925,7 @@ static const OptionDef options[] = { { "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" }, @@ -3866,11 +3957,13 @@ int main(int argc, char **argv) avdevice_register_all(); av_register_all(); +#if HAVE_ISATTY if(isatty(STDIN_FILENO)) url_set_interrupt_cb(decode_interrupt_cb); +#endif for(i=0; i