From 58ffcac8e15ec0e095a091226507da5f960e5fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Sat, 10 Nov 2007 10:19:12 +0100 Subject: Fix interfacing FFmpeg especially for interlaced content. For H.264 content, VO_INTERLACED_FLAG must be set all the time and not only for interlaced frames. Frames should be allocated so that size is a multiple of a marcoblock (16x16). Any excess pixels are cropped away. top_field_first and progressive_frame can be transferred always, not just in demux_mpeg_pes context. But for bad frames it doesn't make sense to transfer those fields as the information would be from the previous frame and could be incorrect for the current frame. Thus, the workaround for demux_mpeg_pes cannot rely on these fields either and needs to use a separate variable to detect fields being sent as frames. --HG-- extra : transplant_source : %A8%25%B9I%A4%5B%E5%AE%DD%EF_c%E35%CBSRn%22%A4 --- src/libffmpeg/ff_video_decoder.c | 57 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 29 deletions(-) (limited to 'src/libffmpeg') diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index fcd0722ab..59c68bd29 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -88,6 +88,7 @@ struct ff_video_decoder_s { uint8_t yuv_init:1; uint8_t is_direct_rendering_disabled:1; uint8_t cs_convert_init:1; + uint8_t assume_bad_field_picture:1; xine_bmiheader bih; unsigned char *buf; @@ -425,6 +426,9 @@ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) case BUF_VIDEO_HUFFYUV: this->frame_flags |= VO_INTERLACED_FLAG; break; + case BUF_VIDEO_H264: + this->frame_flags |= VO_INTERLACED_FLAG; + break; } } @@ -1157,7 +1161,6 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int offset = 0; int codec_type = buf->type & 0xFFFF0000; int video_step_to_use; - int frame_flags_to_use; /* pad input data */ /* note: bitstream, alt bitstream reader or something will cause @@ -1201,12 +1204,6 @@ 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); - frame_flags_to_use = this->frame_flags; - - /* adjust frame flags for interlaced frames when running in demux_mpeg_pes context */ - if (!this->video_step && this->av_frame->interlaced_frame) - frame_flags_to_use |= VO_INTERLACED_FLAG; - /* aspect ratio provided by ffmpeg, override previous setting */ if ((this->aspect_ratio_prio < 2) && av_cmp_q(this->context->sample_aspect_ratio, avr00)) { @@ -1251,12 +1248,13 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { set_stream_info(this); } + /* xine-lib expects the framesize to be a multiple of 16x16 (macroblock) */ img = this->stream->video_out->get_frame (this->stream->video_out, - this->bih.biWidth, - (this->bih.biHeight + 31) & ~31, + (this->bih.biWidth + 15) & ~15, + (this->bih.biHeight + 15) & ~15, this->aspect_ratio, this->output_format, - VO_BOTH_FIELDS|frame_flags_to_use); + VO_BOTH_FIELDS|this->frame_flags); free_img = 1; } else { /* DR1 */ @@ -1273,11 +1271,11 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { if(this->av_frame->opaque) { /* DR1 */ img = this->stream->video_out->get_frame (this->stream->video_out, - img->width, - (img->height + 31) & ~31, + (img->width + 15) & ~15, + (img->height + 15) & ~15, this->aspect_ratio, this->output_format, - VO_BOTH_FIELDS|frame_flags_to_use); + VO_BOTH_FIELDS|this->frame_flags); free_img = 1; } @@ -1307,14 +1305,13 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { else img->duration = video_step_to_use; - img->crop_right = this->crop_right; + /* additionally crop away the extra pixels due to adjusting frame size above */ + img->crop_right = this->crop_right + (img->width - this->bih.biWidth); img->crop_bottom = this->crop_bottom + (img->height - this->bih.biHeight); - /* transfer some more frame settings when running in demux_mpeg_pes context */ - if (!this->video_step) { - img->progressive_frame = !this->av_frame->interlaced_frame; - img->top_field_first = this->av_frame->top_field_first; - } + /* transfer some more frame settings for deinterlacing */ + img->progressive_frame = !this->av_frame->interlaced_frame; + img->top_field_first = this->av_frame->top_field_first; this->skipframes = img->draw(img, this->stream); @@ -1326,28 +1323,30 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { /* workaround for demux_mpeg_pes sending fields as frames: * do not generate a bad frame for the first field picture */ - if (!got_one_picture && (this->size || this->video_step || !this->av_frame->interlaced_frame)) { - /* skipped frame, output a bad frame (of size 1x1 when size still uninitialized) */ + if (!got_one_picture && (this->size || this->video_step || this->assume_bad_field_picture)) { + /* skipped frame, output a bad frame (use size 16x16, when size still uninitialized) */ img = this->stream->video_out->get_frame (this->stream->video_out, - (this->bih.biWidth <= 0) ? 16 : this->bih.biWidth, - (this->bih.biHeight <= 0) ? 32 : this->bih.biHeight, + (this->bih.biWidth <= 0) ? 16 : ((this->bih.biWidth + 15) & ~15), + (this->bih.biHeight <= 0) ? 16 : ((this->bih.biHeight + 15) & ~15), this->aspect_ratio, this->output_format, - VO_BOTH_FIELDS|frame_flags_to_use); + VO_BOTH_FIELDS|this->frame_flags); /* set PTS to allow early syncing */ img->pts = this->pts; this->pts = 0; img->duration = video_step_to_use; - /* transfer some more frame settings when running in demux_mpeg_pes context */ - if (!this->video_step) { - img->progressive_frame = !this->av_frame->interlaced_frame; - img->top_field_first = this->av_frame->top_field_first; - } + + /* additionally crop away the extra pixels due to adjusting frame size above */ + img->crop_right = ((this->bih.biWidth <= 0) ? 0 : this->crop_right) + (img->width - this->bih.biWidth); + img->crop_bottom = ((this->bih.biHeight <= 0) ? 0 : this->crop_bottom) + (img->height - this->bih.biHeight); + img->bad_frame = 1; this->skipframes = img->draw(img, this->stream); img->free(img); } + + this->assume_bad_field_picture = !got_one_picture; } } -- cgit v1.2.3 From 3c175fd21df04c5c0afa160f81aea0c305f69dc5 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sat, 10 Nov 2007 22:06:10 +0000 Subject: Delete most of the CVS $Id$/$Log$ lines. --HG-- extra : transplant_source : %E0%D0%C5%8B%BEU%DD%24%5D7%1F%ADV%AD%EB%23%CBU%80%EB --- src/libffmpeg/ff_audio_decoder.c | 3 --- src/libffmpeg/ff_dvaudio_decoder.c | 3 --- src/libffmpeg/ff_mpeg_parser.c | 2 -- src/libffmpeg/ff_mpeg_parser.h | 2 -- src/libffmpeg/ff_video_decoder.c | 3 --- src/libffmpeg/ffmpeg_decoder.c | 3 --- src/libffmpeg/ffmpeg_decoder.h | 3 --- src/libffmpeg/ffmpeg_encoder.c | 2 -- 8 files changed, 21 deletions(-) (limited to 'src/libffmpeg') diff --git a/src/libffmpeg/ff_audio_decoder.c b/src/libffmpeg/ff_audio_decoder.c index 1de334486..5f197bed5 100644 --- a/src/libffmpeg/ff_audio_decoder.c +++ b/src/libffmpeg/ff_audio_decoder.c @@ -17,10 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * - * $Id: audio_decoder.c,v 1.33 2007/01/28 18:38:33 miguelfreitas Exp $ - * * xine audio decoder plugin using ffmpeg - * */ #ifdef HAVE_CONFIG_H diff --git a/src/libffmpeg/ff_dvaudio_decoder.c b/src/libffmpeg/ff_dvaudio_decoder.c index 84517bd1c..0796b3862 100644 --- a/src/libffmpeg/ff_dvaudio_decoder.c +++ b/src/libffmpeg/ff_dvaudio_decoder.c @@ -17,10 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * - * $Id: dvaudio_decoder.c,v 1.12 2006/12/04 22:25:13 miguelfreitas Exp $ - * * dv audio decoder based on patch by Dan Dennedy - * */ #ifdef HAVE_CONFIG_H diff --git a/src/libffmpeg/ff_mpeg_parser.c b/src/libffmpeg/ff_mpeg_parser.c index 795dee646..70901d93b 100644 --- a/src/libffmpeg/ff_mpeg_parser.c +++ b/src/libffmpeg/ff_mpeg_parser.c @@ -19,8 +19,6 @@ * * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) * based on libmpeg2 decoder. - * - * $Id: mpeg_parser.c,v 1.7 2007/03/29 18:52:45 dgp85 Exp $ */ #define LOG_MODULE "mpeg_parser" #define LOG_VERBOSE diff --git a/src/libffmpeg/ff_mpeg_parser.h b/src/libffmpeg/ff_mpeg_parser.h index 8644b2379..ea43a6ce4 100644 --- a/src/libffmpeg/ff_mpeg_parser.h +++ b/src/libffmpeg/ff_mpeg_parser.h @@ -19,8 +19,6 @@ * * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) * based on libmpeg2 decoder. - * - * $Id: mpeg_parser.h,v 1.5 2007/03/29 18:52:45 dgp85 Exp $ */ #ifndef HAVE_MPEG_PARSER_H #define HAVE_MPEG_PARSER_H diff --git a/src/libffmpeg/ff_video_decoder.c b/src/libffmpeg/ff_video_decoder.c index 59c68bd29..8fc9cc8cb 100644 --- a/src/libffmpeg/ff_video_decoder.c +++ b/src/libffmpeg/ff_video_decoder.c @@ -17,10 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * - * $Id: video_decoder.c,v 1.73 2007/03/29 18:41:02 dgp85 Exp $ - * * xine video decoder plugin using ffmpeg - * */ #ifdef HAVE_CONFIG_H diff --git a/src/libffmpeg/ffmpeg_decoder.c b/src/libffmpeg/ffmpeg_decoder.c index 2746c28a3..d0175184f 100644 --- a/src/libffmpeg/ffmpeg_decoder.c +++ b/src/libffmpeg/ffmpeg_decoder.c @@ -17,10 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * - * $Id: xine_decoder.c,v 1.173 2007/01/13 21:19:52 miguelfreitas Exp $ - * * xine decoder plugin using ffmpeg - * */ #ifdef HAVE_CONFIG_H diff --git a/src/libffmpeg/ffmpeg_decoder.h b/src/libffmpeg/ffmpeg_decoder.h index 8c4f120bc..14788cf29 100644 --- a/src/libffmpeg/ffmpeg_decoder.h +++ b/src/libffmpeg/ffmpeg_decoder.h @@ -16,9 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * $Id: xine_decoder.h,v 1.7 2006/08/02 07:15:27 tmmm Exp $ - * */ #ifndef HAVE_XINE_DECODER_H diff --git a/src/libffmpeg/ffmpeg_encoder.c b/src/libffmpeg/ffmpeg_encoder.c index 3aaf3c9ea..35c47db28 100644 --- a/src/libffmpeg/ffmpeg_encoder.c +++ b/src/libffmpeg/ffmpeg_encoder.c @@ -16,8 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * $Id: xine_encoder.c,v 1.25 2006/07/10 22:08:29 dgp85 Exp $ */ /* mpeg encoders for the dxr3 video out plugin. */ -- cgit v1.2.3