* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define HAVE_AV_CONFIG_H
-#include "common.h"
#include "avformat.h"
#include "framehook.h"
-/* usleep() */
-#include "os_support.h"
#ifndef CONFIG_WIN32
#include <unistd.h>
#include <stdlib.h>
#endif
#include <time.h>
-#include <ctype.h>
#include "cmdutils.h"
static int b_frames = 0;
static int mb_decision = FF_MB_DECISION_SIMPLE;
static int use_4mv = 0;
-/* Fx */
static int use_aic = 0;
static int use_umv = 0;
-/* /Fx */
static int do_deinterlace = 0;
static int workaround_bugs = FF_BUG_AUTODETECT;
static int error_resilience = 2;
static int packet_size = 0;
static int strict = 0;
static int debug = 0;
+extern int loop_input; /* currently a hack */
static int gop_size = 12;
static int intra_only = 0;
static char *audio_grab_format = "audio_device";
static char *audio_device = NULL;
+static int using_stdin = 0;
+static int using_vhook = 0;
+static int verbose = 1;
+
#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
typedef struct AVOutputStream {
#else
+static volatile int received_sigterm = 0;
+
/* no interactive support */
static void term_exit(void)
{
dec = &ist->st->codec;
/* deinterlace : must be done before any resize */
- if (do_deinterlace) {
+ if (do_deinterlace || using_vhook) {
int size;
/* create temporary picture */
picture2 = &picture_tmp;
avpicture_fill(picture2, buf, 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 */
- av_free(buf);
- buf = NULL;
- picture2 = picture;
+ if (do_deinterlace){
+ if(avpicture_deinterlace(picture2, picture,
+ dec->pix_fmt, dec->width, dec->height) < 0) {
+ /* if error, do not deinterlace */
+ av_free(buf);
+ buf = NULL;
+ picture2 = picture;
+ }
+ } else {
+ if (img_convert(picture2, dec->pix_fmt, picture,
+ dec->pix_fmt, dec->width, dec->height) < 0) {
+ /* if error, do not copy */
+ av_free(buf);
+ buf = NULL;
+ picture2 = picture;
+ }
}
} else {
picture2 = picture;
static uint8_t *video_buffer;
uint8_t *buf = NULL, *buf1 = NULL;
AVCodecContext *enc, *dec;
+ enum PixelFormat target_pixfmt;
#define VIDEO_BUFFER_SIZE (1024*1024)
return;
/* convert pixel format if needed */
- if (enc->pix_fmt != dec->pix_fmt) {
+ target_pixfmt = ost->video_resample ? PIX_FMT_YUV420P : enc->pix_fmt;
+ if (dec->pix_fmt != target_pixfmt) {
int size;
/* create temporary picture */
formatted_picture = &picture_format_temp;
avpicture_fill(formatted_picture, buf, enc->pix_fmt, dec->width, dec->height);
- if (img_convert(formatted_picture, enc->pix_fmt,
+ if (img_convert(formatted_picture, target_pixfmt,
in_picture, dec->pix_fmt,
dec->width, dec->height) < 0) {
fprintf(stderr, "pixel format conversion not handled\n");
if (ost->video_resample) {
final_picture = &ost->pict_tmp;
img_resample(ost->img_resample_ctx, final_picture, formatted_picture);
+ if (enc->pix_fmt != PIX_FMT_YUV420P) {
+ int size;
+
+ av_free(buf);
+ /* create temporary picture */
+ size = avpicture_get_size(enc->pix_fmt, enc->width, enc->height);
+ buf = av_malloc(size);
+ if (!buf)
+ return;
+ final_picture = &picture_format_temp;
+ avpicture_fill(final_picture, buf, enc->pix_fmt, enc->width, enc->height);
+
+ if (img_convert(final_picture, enc->pix_fmt,
+ &ost->pict_tmp, PIX_FMT_YUV420P,
+ enc->width, enc->height) < 0) {
+ fprintf(stderr, "pixel format conversion not handled\n");
+ goto the_end;
+ }
+ }
} else if (ost->video_crop) {
picture_crop_temp.data[0] = formatted_picture->data[0] +
(ost->topBand * formatted_picture->linesize[0]) + ost->leftBand;
}
if (ti1 < 0.01)
ti1 = 0.01;
- bitrate = (double)(total_size * 8) / ti1 / 1000.0;
- sprintf(buf + strlen(buf),
+ if (verbose || is_last_report) {
+ bitrate = (double)(total_size * 8) / ti1 / 1000.0;
+
+ sprintf(buf + strlen(buf),
"size=%8.0fkB time=%0.1f bitrate=%6.1fkbits/s",
(double)total_size / 1024, ti1, bitrate);
-
- fprintf(stderr, "%s ", buf);
-
- if (is_last_report) {
- fprintf(stderr, "\n");
- } else {
- fprintf(stderr, "\r");
+
+ fprintf(stderr, "%s \r", buf);
fflush(stderr);
}
+
+ if (is_last_report)
+ fprintf(stderr, "\n");
}
/*
ist = ist_table[i];
is = input_files[ist->file_index];
ist->pts = 0;
- switch (ist->st->codec.codec_type) {
- case CODEC_TYPE_AUDIO:
- av_frac_init(&ist->next_pts,
- 0, 0, is->pts_num * ist->st->codec.sample_rate);
- break;
- case CODEC_TYPE_VIDEO:
- av_frac_init(&ist->next_pts,
- 0, 0, is->pts_num * ist->st->codec.frame_rate);
- break;
- default:
- break;
- }
+ if (ist->decoding_needed) {
+ switch (ist->st->codec.codec_type) {
+ case CODEC_TYPE_AUDIO:
+ av_frac_init(&ist->next_pts,
+ 0, 0, (uint64_t)is->pts_num * ist->st->codec.sample_rate);
+ break;
+ case CODEC_TYPE_VIDEO:
+ av_frac_init(&ist->next_pts,
+ 0, 0, (uint64_t)is->pts_num * ist->st->codec.frame_rate);
+ break;
+ default:
+ break;
+ }
+ }
}
/* compute buffer size max (should use a complete heuristic) */
}
#ifndef CONFIG_WIN32
- fprintf(stderr, "Press [q] to stop encoding\n");
+ if ( !using_stdin )
+ fprintf(stderr, "Press [q] to stop encoding\n");
#endif
term_init();
stream_no_data = 0;
key = -1;
- for(;;) {
+ for(; received_sigterm == 0;) {
int file_index, ist_index;
AVPacket pkt;
uint8_t *ptr;
redo:
/* if 'q' pressed, exits */
- if (key) {
+ if (!using_stdin) {
/* read_key() returns 0 on EOF */
key = read_key();
if (key == 'q')
}
data_buf = (uint8_t *)samples;
av_frac_add(&ist->next_pts,
- is->pts_den * data_size / (2 * ist->st->codec.channels));
+ (uint64_t)is->pts_den * data_size / (2 * ist->st->codec.channels));
break;
case CODEC_TYPE_VIDEO:
{
continue;
}
av_frac_add(&ist->next_pts,
- is->pts_den * ist->st->codec.frame_rate_base);
+ (uint64_t)is->pts_den * ist->st->codec.frame_rate_base);
}
break;
default:
debug = atoi(arg);
}
+static void opt_verbose(const char *arg)
+{
+ verbose = atoi(arg);
+}
+
static void opt_frame_rate(const char *arg)
{
if (parse_frame_rate(&frame_rate, &frame_rate_base, arg) < 0) {
int i;
char *args = av_strdup(arg);
+ using_vhook = 1;
+
argv[0] = strtok(args, " ");
while (argc < 62 && (argv[++argc] = strtok(NULL, " "))) {
}
if (!strcmp(filename, "-"))
filename = "pipe:";
+ using_stdin |= !strcmp(filename, "pipe:" ) ||
+ !strcmp( filename, "/dev/stdin" );
+
/* get default parameters from command line */
memset(ap, 0, sizeof(*ap));
ap->sample_rate = audio_sample_rate;
avcodec_get_context_defaults(&st->codec);
video_enc = &st->codec;
+
+ if(!strcmp(file_oformat->name, "mp4") || !strcmp(file_oformat->name, "mov") || !strcmp(file_oformat->name, "3gp"))
+ video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
if (video_stream_copy) {
st->stream_copy = 1;
video_enc->codec_type = CODEC_TYPE_VIDEO;
video_enc->mb_decision = mb_decision;
- /* Fx */
if (use_umv) {
video_enc->flags |= CODEC_FLAG_H263P_UMV;
}
if (use_aic) {
video_enc->flags |= CODEC_FLAG_H263P_AIC;
}
- /* /Fx */
if (use_4mv) {
video_enc->mb_decision = FF_MB_DECISION_BITS; //FIXME remove
video_enc->flags |= CODEC_FLAG_4MV;
if (url_exist(filename)) {
int c;
- printf("File '%s' already exists. Overwrite ? [y/N] ", filename);
- fflush(stdout);
- c = getchar();
- if (toupper(c) != 'Y') {
- fprintf(stderr, "Not overwriting - exiting\n");
+ if ( !using_stdin ) {
+ fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
+ fflush(stderr);
+ c = getchar();
+ if (toupper(c) != 'Y') {
+ fprintf(stderr, "Not overwriting - exiting\n");
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
exit(1);
- }
+ }
}
}
printf(" %s:", up->name);
printf("\n");
- printf("Frame size, frame rate abbreviations: ntsc pal film ntsc-film sqcif qcif cif 4cif\n");
+ printf("Frame size, frame rate abbreviations: ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
printf("Motion estimation methods:");
pp = motion_str;
while (*pp) {
{ "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump},
"dump each input packet" },
{ "bitexact", OPT_EXPERT, {(void*)opt_bitexact}, "only use bit exact algorithms (for codec testing)" },
-
+ { "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" },
+ { "loop", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" },
+ { "v", HAS_ARG, {(void*)opt_verbose}, "control amount of logging", "verbose" },
/* video options */
{ "b", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
{ "r", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_rate}, "set frame rate (Hz value, fraction or abbreviation)", "rate" },
- { "re", OPT_BOOL|OPT_EXPERT | OPT_VIDEO, {(void*)&rate_emu}, "read input at native frame rate" },
{ "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
{ "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
{ "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" },
{ "i_qoffset", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_i_qoffset}, "qp offset between p and i frames", "offset" },
// { "b_strategy", HAS_ARG | OPT_EXPERT, {(void*)opt_b_strategy}, "dynamic b frame selection strategy", "strategy" },
{ "rc_eq", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_eq}, "set rate control equation", "equation" },
- { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific internals", "override_string" },
+ { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" },
{ "bt", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_tolerance}, "set video bitrate tolerance (in kbit/s)", "tolerance" },
{ "maxrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_max}, "set max video bitrate tolerance (in kbit/s)", "bitrate" },
{ "minrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" },
{ "dct_algo", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_dct_algo}, "set dct algo", "algo" },
{ "idct_algo", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_idct_algo}, "set idct algo", "algo" },
{ "er", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_error_resilience}, "set error resilience", "n" },
- { "ec", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_error_concealment}, "set error concealment", "n" },
- { "bf", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_frames}, "use 'frames' B frames (only MPEG-4)", "frames" },
+ { "ec", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_error_concealment}, "set error concealment", "bit_mask" },
+ { "bf", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_frames}, "use 'frames' B frames", "frames" },
{ "hq", OPT_BOOL, {(void*)&mb_decision}, "activate high quality settings" },
{ "mbd", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_decision}, "macroblock decision", "mode" },
{ "4mv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_4mv}, "use four motion vector by macroblock (only MPEG-4)" },
{ "psnr", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
{ "vstats", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_vstats}, "dump video coding statistics to file" },
{ "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
- /* Fx */
{ "aic", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_aic}, "enable Advanced intra coding (h263+)" },
{ "umv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_umv}, "enable Unlimited Motion Vector (h263+)" },
- /* /Fx */
/* audio options */
{ "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", },