You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
Frame rate emulation patch by (Max Krasnyansky <maxk at qualcomm dot com>)
Originally committed as revision 1641 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
committed by
Michael Niedermayer
parent
6486396546
commit
bdfcbbed79
27
ffmpeg.c
27
ffmpeg.c
@@ -89,7 +89,6 @@ static int frame_bottomBand = 0;
|
|||||||
static int frame_leftBand = 0;
|
static int frame_leftBand = 0;
|
||||||
static int frame_rightBand = 0;
|
static int frame_rightBand = 0;
|
||||||
static int frame_rate = 25 * FRAME_RATE_BASE;
|
static int frame_rate = 25 * FRAME_RATE_BASE;
|
||||||
extern int emulate_frame_rate;
|
|
||||||
static int video_bit_rate = 200*1000;
|
static int video_bit_rate = 200*1000;
|
||||||
static int video_bit_rate_tolerance = 4000*1000;
|
static int video_bit_rate_tolerance = 4000*1000;
|
||||||
static int video_qscale = 0;
|
static int video_qscale = 0;
|
||||||
@@ -164,6 +163,8 @@ static char *pass_logfilename = NULL;
|
|||||||
static int audio_stream_copy = 0;
|
static int audio_stream_copy = 0;
|
||||||
static int video_stream_copy = 0;
|
static int video_stream_copy = 0;
|
||||||
|
|
||||||
|
static int rate_emu = 0;
|
||||||
|
|
||||||
static char *video_grab_format = "video4linux";
|
static char *video_grab_format = "video4linux";
|
||||||
static char *video_device = NULL;
|
static char *video_device = NULL;
|
||||||
static int video_channel = 0;
|
static int video_channel = 0;
|
||||||
@@ -209,6 +210,9 @@ typedef struct AVInputStream {
|
|||||||
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
|
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
|
||||||
int64_t sample_index; /* current sample */
|
int64_t sample_index; /* current sample */
|
||||||
int frame_decoded; /* true if a video or audio frame has been decoded */
|
int frame_decoded; /* true if a video or audio frame has been decoded */
|
||||||
|
|
||||||
|
int64_t start; /* time when read started */
|
||||||
|
unsigned long frame; /* current frame */
|
||||||
} AVInputStream;
|
} AVInputStream;
|
||||||
|
|
||||||
typedef struct AVInputFile {
|
typedef struct AVInputFile {
|
||||||
@@ -873,6 +877,11 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
ist->index = k;
|
ist->index = k;
|
||||||
ist->discard = 1; /* the stream is discarded by default
|
ist->discard = 1; /* the stream is discarded by default
|
||||||
(changed later) */
|
(changed later) */
|
||||||
|
|
||||||
|
if (ist->st->codec.rate_emu) {
|
||||||
|
ist->start = av_gettime();
|
||||||
|
ist->frame = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,6 +1357,16 @@ static int av_encode(AVFormatContext **output_files,
|
|||||||
|
|
||||||
ist->frame_decoded = 1;
|
ist->frame_decoded = 1;
|
||||||
|
|
||||||
|
/* frame rate emulation */
|
||||||
|
if (ist->st->codec.rate_emu) {
|
||||||
|
int64_t pts = ((int64_t) ist->frame * FRAME_RATE_BASE * 1000000) / (ist->st->codec.frame_rate);
|
||||||
|
int64_t now = av_gettime() - ist->start;
|
||||||
|
if (pts > now)
|
||||||
|
usleep(pts - now);
|
||||||
|
|
||||||
|
ist->frame++;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* mpeg PTS deordering : if it is a P or I frame, the PTS
|
/* mpeg PTS deordering : if it is a P or I frame, the PTS
|
||||||
is the one of the next displayed one */
|
is the one of the next displayed one */
|
||||||
@@ -2092,6 +2111,8 @@ static void opt_input_file(const char *filename)
|
|||||||
}
|
}
|
||||||
/* update the current frame rate to match the stream frame rate */
|
/* update the current frame rate to match the stream frame rate */
|
||||||
frame_rate = rfps;
|
frame_rate = rfps;
|
||||||
|
|
||||||
|
enc->rate_emu = rate_emu;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
av_abort();
|
av_abort();
|
||||||
@@ -2105,6 +2126,8 @@ static void opt_input_file(const char *filename)
|
|||||||
file_iformat = NULL;
|
file_iformat = NULL;
|
||||||
file_oformat = NULL;
|
file_oformat = NULL;
|
||||||
image_format = NULL;
|
image_format = NULL;
|
||||||
|
|
||||||
|
rate_emu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
|
static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
|
||||||
@@ -2715,7 +2738,7 @@ const OptionDef options[] = {
|
|||||||
/* video options */
|
/* video options */
|
||||||
{ "b", HAS_ARG, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
|
{ "b", HAS_ARG, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" },
|
||||||
{ "r", HAS_ARG, {(void*)opt_frame_rate}, "set frame rate (in Hz)", "rate" },
|
{ "r", HAS_ARG, {(void*)opt_frame_rate}, "set frame rate (in Hz)", "rate" },
|
||||||
{ "em_rate", OPT_BOOL|OPT_EXPERT, {(void*)&emulate_frame_rate}, "makes img reading happen at nominal frame rate" },
|
{ "re", OPT_BOOL|OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate" },
|
||||||
{ "s", HAS_ARG, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
|
{ "s", HAS_ARG, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
|
||||||
{ "croptop", HAS_ARG, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" },
|
{ "croptop", HAS_ARG, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" },
|
||||||
{ "cropbottom", HAS_ARG, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
|
{ "cropbottom", HAS_ARG, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" },
|
||||||
|
@@ -408,7 +408,15 @@ typedef struct AVCodecContext {
|
|||||||
* - decoding: set by lavc.
|
* - decoding: set by lavc.
|
||||||
*/
|
*/
|
||||||
enum PixelFormat pix_fmt;
|
enum PixelFormat pix_fmt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frame rate emulation. If not zero lower layer (i.e. format handler)
|
||||||
|
* has to read frames at native frame rate.
|
||||||
|
* - encoding: set by user.
|
||||||
|
* - decoding: unused.
|
||||||
|
*/
|
||||||
|
int rate_emu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if non NULL, 'draw_horiz_band' is called by the libavcodec
|
* if non NULL, 'draw_horiz_band' is called by the libavcodec
|
||||||
* decoder to draw an horizontal band. It improve cache usage. Not
|
* decoder to draw an horizontal band. It improve cache usage. Not
|
||||||
|
@@ -47,8 +47,6 @@ typedef struct {
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
} VideoData;
|
} VideoData;
|
||||||
|
|
||||||
int emulate_frame_rate;
|
|
||||||
|
|
||||||
static int image_probe(AVProbeData *p)
|
static int image_probe(AVProbeData *p)
|
||||||
{
|
{
|
||||||
if (filename_number_test(p->filename) >= 0 && guess_image_format(p->filename))
|
if (filename_number_test(p->filename) >= 0 && guess_image_format(p->filename))
|
||||||
@@ -157,23 +155,6 @@ static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
|
|||||||
char filename[1024];
|
char filename[1024];
|
||||||
int ret;
|
int ret;
|
||||||
ByteIOContext f1, *f;
|
ByteIOContext f1, *f;
|
||||||
static int64_t first_frame; // BUG -> to context FIXME
|
|
||||||
|
|
||||||
if (emulate_frame_rate) {
|
|
||||||
if (!first_frame) {
|
|
||||||
first_frame = av_gettime();
|
|
||||||
} else {
|
|
||||||
int64_t pts;
|
|
||||||
int64_t nowus;
|
|
||||||
|
|
||||||
nowus = av_gettime() - first_frame;
|
|
||||||
|
|
||||||
pts = ((int64_t)s->img_number * FRAME_RATE_BASE * 1000000) / (s1->streams[0]->codec.frame_rate);
|
|
||||||
|
|
||||||
if (pts > nowus)
|
|
||||||
usleep(pts - nowus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s->is_pipe) {
|
if (!s->is_pipe) {
|
||||||
if (get_frame_filename(filename, sizeof(filename),
|
if (get_frame_filename(filename, sizeof(filename),
|
||||||
|
Reference in New Issue
Block a user