diff options
Diffstat (limited to 'xine_input_vdr.c')
-rw-r--r-- | xine_input_vdr.c | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/xine_input_vdr.c b/xine_input_vdr.c index c5f66ce3..8874879a 100644 --- a/xine_input_vdr.c +++ b/xine_input_vdr.c @@ -4,7 +4,7 @@ * See the main source file 'xineliboutput.c' for copyright information and * how to reach the author. * - * $Id: xine_input_vdr.c,v 1.83 2007-05-30 07:05:36 phintuka Exp $ + * $Id: xine_input_vdr.c,v 1.84 2007-05-30 08:13:24 phintuka Exp $ * */ @@ -58,6 +58,12 @@ /***************************** DEFINES *********************************/ +/* Support for ffmpeg mpeg2 decoder. + Priority must be increased in $HOME/.xine/config_xineliboutput: + engine.decoder_priorities.ffmpegvideo:1 +*/ +#define FFMPEG_DEC + /*#define LOG_UDP*/ /*#define LOG_OSD*/ /*#define LOG_CMD*/ @@ -244,6 +250,7 @@ typedef struct vdr_input_plugin_s { int audio_stream_id; /* ((PES PID) << 8) | (SUBSTREAM ID) */ int prev_audio_stream_id; int sw_volume_control; + int ffmpeg_video_decoder; /* SCR */ pvrscr_t *scr; @@ -4694,7 +4701,7 @@ static off_t vdr_plugin_read (input_plugin_t *this_gen, # include "cache_iframe.c" #endif -static void update_frames(vdr_input_plugin_t *this, uint8_t *data, int len) +static int update_frames(vdr_input_plugin_t *this, uint8_t *data, int len) { int Length = len; int i = 8; @@ -4704,14 +4711,17 @@ static void update_frames(vdr_input_plugin_t *this, uint8_t *data, int len) i += data[i] + 1; /* possible additional header bytes */ for (; i < Length-5; i++) { if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 1 && data[i + 3] == 0) { - switch ((data[i + 5] >> 3) & 0x07) { + uint8_t type = ((data[i + 5] >> 3) & 0x07); + switch (type) { case 1: this->I_frames++; LOGSCR("I"); break; case 2: this->P_frames++; LOGSCR("P"); break; case 3: this->B_frames++; LOGSCR("B"); break; - default: return; + default: return 0; } + return type; } } + return 0; } static buf_element_t *vdr_plugin_read_block (input_plugin_t *this_gen, @@ -4946,9 +4956,30 @@ static buf_element_t *vdr_plugin_read_block (input_plugin_t *this_gen, } } - if(this->live_mode && this->I_frames < 4 && - buf->content[3] == 0xe0 && buf->size > 32) - update_frames(this, buf->content, buf->size); +#ifndef FFMPEG_DEC + if(this->live_mode && this->I_frames < 4) + if(buf->content[3] == 0xe0 && buf->size > 32) + update_frames(this, buf->content, buf->size); +#else /* FFMPEG_DEC */ + if(this->ffmpeg_video_decoder || (this->live_mode && this->I_frames < 4)) + if(buf->content[3] == 0xe0 && buf->size > 32) { + int type = update_frames(this, buf->content, buf->size); + if(type && this->ffmpeg_video_decoder) { + buf_element_t *cbuf = get_buf_element(this, 0, 1); + /* signal FRAME_END to decoder */ + if(cbuf) { + cbuf->type = BUF_VIDEO_MPEG; + cbuf->decoder_flags = BUF_FLAG_FRAME_END; + this->stream->video_fifo->put (this->stream->video_fifo, cbuf); + } + /* for some reason ffmpeg mpeg2 decoder does not understand pts'es in B frames ? + * (B-frame pts's are smaller than in previous P-frame) + * Anyway, without this block of code B frames with pts are dropped. */ + if(type == 3 && pts_from_pes(buf->content, buf->size) > INT64_C(0)) + pes_strip_pts(buf->content, buf->size); + } + } +#endif TRACE("vdr_plugin_read_block: return data, pos end = %" PRIu64, this->curpos); return buf; @@ -5931,6 +5962,7 @@ static input_plugin_t *vdr_class_get_instance (input_class_t *cls_gen, this->still_mode = 0; this->stream_start = 1; this->send_pts = 0; + this->ffmpeg_video_decoder = -1; this->rescale_osd = 0; this->unscaled_osd = 0; @@ -6003,6 +6035,23 @@ static input_plugin_t *vdr_class_get_instance (input_class_t *cls_gen, this->udp_data = NULL; +#ifdef FFMPEG_DEC + if(this->ffmpeg_video_decoder < 0) { + xine_cfg_entry_t ffmpegprio, mpeg2prio; + this->ffmpeg_video_decoder = 0; + if (xine_config_lookup_entry(this->stream->xine, "engine.decoder_priorities.ffmpegvideo", &ffmpegprio)) { + LOGMSG("ffmpeg video decoder priority: %d", ffmpegprio.num_value); + this->ffmpeg_video_decoder = 1; + if (xine_config_lookup_entry(this->stream->xine, "engine.decoder_priorities.mpeg2", &mpeg2prio)) { + LOGMSG("libmpeg2 video decoder priority: %d", mpeg2prio.num_value); + if (mpeg2prio.num_value > ffmpegprio.num_value) + this->ffmpeg_video_decoder = 0; + } + LOGMSG(" --> using %s mpeg2 video decoder", this->ffmpeg_video_decoder?"ffmpeg":"libmpeg2"); + } + } +#endif + LOGDBG("vdr_class_get_instance done."); return &this->input_plugin; } |