summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinhard Nißl <rnissl@gmx.de>2007-10-23 22:36:34 +0200
committerReinhard Nißl <rnissl@gmx.de>2007-10-23 22:36:34 +0200
commit558b641ae448f94e238f01a945fb892e8b4cde4e (patch)
tree9144b3c967150ba18ccc997f1d16a4dcde828439
parent1205d480e42125d78b1d987c639e49371a35d5fe (diff)
downloadxine-lib-558b641ae448f94e238f01a945fb892e8b4cde4e.tar.gz
xine-lib-558b641ae448f94e238f01a945fb892e8b4cde4e.tar.bz2
Generate video_step from stream and work around wrong field duration.
When demux_mpeg_pes uses FFmpeg for H.264 streams, it doesn't set video_step as it doesn't know it. But FFmpeg provides it deriveable from time_base. So let's use the derived value as long as it isn't set explicitly. Furthermore, demux_mpeg_pes set's BUF_FLAG_FRAME_END whenever it encounters a H.264 access unit delimiter, which appears between fields or frames, but it doesn't know, whether it deals with fields or frames. avcodec_decode_video() on the other hand sets got_picture even when the decoded data specifies just a field. But it also sets the flag interlaced_frame. So let's use this flag to halve video_step in order to show the decoded images just for a field duration. --HG-- extra : transplant_source : %40Q%E3fO%3C%E7%A0%02%BA%9D%1D%BD%81%F0f-%EAs%87
-rw-r--r--src/libffmpeg/ff_video_decoder.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c
index 9ab4f9daf..83c3f2945 100644
--- a/src/libffmpeg/ff_video_decoder.c
+++ b/src/libffmpeg/ff_video_decoder.c
@@ -1156,6 +1156,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
int got_one_picture = 0;
int offset = 0;
int codec_type = buf->type & 0xFFFF0000;
+ int video_step_to_use;
/* pad input data */
/* note: bitstream, alt bitstream reader or something will cause
@@ -1196,6 +1197,9 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
}
}
+ /* use externally provided video_step or fall back to stream's time_base otherwise */
+ video_step_to_use = (this->video_step || !this->context->time_base.den) ? this->video_step : (int)(90000ll * this->context->time_base.num / this->context->time_base.den);
+
/* aspect ratio provided by ffmpeg, override previous setting */
if ((this->aspect_ratio_prio < 2) &&
av_cmp_q(this->context->sample_aspect_ratio, avr00)) {
@@ -1285,16 +1289,20 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
img->pts = this->pts;
this->pts = 0;
+ /* workaround for demux_mpeg_pes sending fields as frames */
+ if (!this->video_step && this->av_frame->interlaced_frame)
+ video_step_to_use /= 2;
+
/* workaround for weird 120fps streams */
- if( this->video_step == 750 ) {
+ if( video_step_to_use == 750 ) {
/* fallback to the VIDEO_PTS_MODE */
- this->video_step = 0;
+ video_step_to_use = 0;
}
if (this->av_frame->repeat_pict)
- img->duration = this->video_step * 3 / 2;
+ img->duration = video_step_to_use * 3 / 2;
else
- img->duration = this->video_step;
+ img->duration = video_step_to_use;
img->crop_right = this->crop_right;
img->crop_bottom = this->crop_bottom;
@@ -1318,7 +1326,7 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
img->pts = this->pts;
this->pts = 0;
- img->duration = this->video_step;
+ img->duration = video_step_to_use;
img->bad_frame = 1;
this->skipframes = img->draw(img, this->stream);
img->free(img);