diff options
author | Michael Roitzsch <mroi@users.sourceforge.net> | 2004-07-20 16:37:44 +0000 |
---|---|---|
committer | Michael Roitzsch <mroi@users.sourceforge.net> | 2004-07-20 16:37:44 +0000 |
commit | ca9cba8dc3ad0c31e919e502a2d57143b9ff7180 (patch) | |
tree | e65f521d915b118343c703213d58ad39e8e36db1 | |
parent | 78b4e8e89551df1812446d827cf9374fa6d4de4f (diff) | |
download | xine-lib-ca9cba8dc3ad0c31e919e502a2d57143b9ff7180.tar.gz xine-lib-ca9cba8dc3ad0c31e919e502a2d57143b9ff7180.tar.bz2 |
small DXR3 code cleanup:
* make some helper functions non-inline that Bastien had to move because of
their inlining (I realized that some helpers are a bit too large for inlining,
so they might worsen the I-cache usage.)
* properly use logging macros in all DXR3 code
* prepare SPU decoder for new (and hopefully correct) SPU forcing; this
should fix some longstanding DXR3 SPU problems, but the code needs more testing
so it is disabled for now
CVS patchset: 6824
CVS date: 2004/07/20 16:37:44
-rw-r--r-- | src/dxr3/dxr3_decode_spu.c | 170 | ||||
-rw-r--r-- | src/dxr3/dxr3_decode_video.c | 287 | ||||
-rw-r--r-- | src/dxr3/dxr3_mpeg_encoders.c | 40 | ||||
-rw-r--r-- | src/dxr3/dxr3_scr.c | 26 | ||||
-rw-r--r-- | src/dxr3/dxr3_spu_encoder.c | 8 | ||||
-rw-r--r-- | src/dxr3/video_out_dxr3.c | 129 | ||||
-rw-r--r-- | src/libffmpeg/xine_encoder.c | 61 |
7 files changed, 343 insertions, 378 deletions
diff --git a/src/dxr3/dxr3_decode_spu.c b/src/dxr3/dxr3_decode_spu.c index d8de66ee9..236982065 100644 --- a/src/dxr3/dxr3_decode_spu.c +++ b/src/dxr3/dxr3_decode_spu.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dxr3_decode_spu.c,v 1.48 2004/07/11 11:47:10 hadess Exp $ + * $Id: dxr3_decode_spu.c,v 1.49 2004/07/20 16:37:44 mroi Exp $ */ /* dxr3 spu decoder plugin. @@ -37,10 +37,8 @@ #include <errno.h> #define LOG_MODULE "dxr3_decode_spu" -#define LOG_VERBOSE -/* -#define LOG -*/ +/* #define LOG_VERBOSE */ +/* #define LOG */ #define LOG_PTS 0 #define LOG_SPU 0 @@ -101,7 +99,7 @@ typedef struct dxr3_spu_stream_state_s { int spu_length; int spu_ctrl; int spu_end; - int end_found; + int parse; int bytes_passed; /* used to parse the spu */ } dxr3_spu_stream_state_t; @@ -140,12 +138,15 @@ typedef struct dxr3_spudec_s { } dxr3_spudec_t; /* helper functions */ +static inline int dxr3_present(xine_stream_t *stream); /* the NAV functions must be called with the pci_lock held */ static inline void dxr3_spudec_clear_nav_list(dxr3_spudec_t *this); static inline void dxr3_spudec_update_nav(dxr3_spudec_t *this); static void dxr3_spudec_process_nav(dxr3_spudec_t *this); static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300_button_t *btn); +static inline void dxr3_swab_clut(int* clut); +/* inline helper implementations */ static inline int dxr3_present(xine_stream_t *stream) { plugin_node_t *node; @@ -164,27 +165,6 @@ static inline int dxr3_present(xine_stream_t *stream) return present; } -static inline void dxr3_spudec_handle_event(dxr3_spudec_t *this) -{ - xine_event_t *event; - - while ((event = xine_event_get(this->event_queue))) { - llprintf(LOG_SPU, "event caught: SPU_FD = %i\n",this->fd_spu); - - switch (event->type) { - case XINE_EVENT_FRAME_FORMAT_CHANGE: - /* we are in anamorphic mode, if the frame is 16:9, but not pan&scan'ed */ - this->anamorphic = - (((xine_format_change_data_t *)event->data)->aspect == 3) && - (((xine_format_change_data_t *)event->data)->pan_scan == 0); - llprintf(LOG_BTN, "anamorphic mode %s\n", this->anamorphic ? "on" : "off"); - break; - } - - xine_event_free(event); - } -} - static inline void dxr3_spudec_clear_nav_list(dxr3_spudec_t *this) { while (this->pci_cur.next) { @@ -215,6 +195,7 @@ static inline void dxr3_swab_clut(int *clut) clut[i] = bswap_32(clut[i]); } + static void *dxr3_spudec_init_plugin(xine_t *xine, void* data) { dxr3_spudec_class_t *this; @@ -238,7 +219,6 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi dxr3_spudec_t *this; dxr3_spudec_class_t *class = (dxr3_spudec_class_t *)class_gen; char tmpstr[128]; - int i; if (class->instance) return NULL; if (!dxr3_present(stream)) return NULL; @@ -282,9 +262,6 @@ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xi } pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); - for (i = 0; i < MAX_SPU_STREAMS; i++) - this->spu_stream_state[i].spu_length = 0; - this->menu = 0; this->button_filter = 1; this->pci_cur.pci.hli.hl_gi.hli_ss = 0; @@ -323,8 +300,24 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) uint32_t stream_id = buf->type & 0x1f; dxr3_spu_stream_state_t *state = &this->spu_stream_state[stream_id]; uint32_t spu_channel = this->stream->spu_channel; + xine_event_t *event; + + /* handle queued events */ + while ((event = xine_event_get(this->event_queue))) { + llprintf(LOG_SPU, "event caught: SPU_FD = %i\n",this->fd_spu); + + switch (event->type) { + case XINE_EVENT_FRAME_FORMAT_CHANGE: + /* we are in anamorphic mode, if the frame is 16:9, but not pan&scan'ed */ + this->anamorphic = + (((xine_format_change_data_t *)event->data)->aspect == 3) && + (((xine_format_change_data_t *)event->data)->pan_scan == 0); + llprintf(LOG_BTN, "anamorphic mode %s\n", this->anamorphic ? "on" : "off"); + break; + } - dxr3_spudec_handle_event(this); + xine_event_free(event); + } if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || !(buf->decoder_flags & BUF_FLAG_SPECIAL) || @@ -419,44 +412,87 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) dxr3_spudec_update_nav(this); pthread_mutex_unlock(&this->pci_lock); - /* Look for the display duration entry in the spu packets. - * If the spu is a menu button highlight pane, this entry must not exist, - * because the spu is hidden, when the menu is left, not by timeout. - * Some broken dvds do not respect this and therefore confuse the spu - * decoding pipeline of the card. We fix this here. + /* We parse the SPUs command and end sequence here for two reasons: + * 1. Look for the display duration entry in the spu packets. + * If the spu is a menu button highlight pane, this entry must not exist, + * because the spu is hidden, when the menu is left, not by timeout. + * Some broken dvds do not respect this and therefore confuse the spu + * decoding pipeline of the card. We fix this here. + * 2. We need to handle SPU forcing here. When we only display forced + * SPUs, we have to prevent normal unforced SPUs from being displayed. + * But since that decision is only possible after parts of the SPU + * have already been written to the card, we have to manipulate the + * SPU's command sequence to prevent it from being displayed. */ if (!state->spu_length) { - state->spu_length = buf->content[0] << 8 | buf->content[1]; - state->spu_ctrl = (buf->content[2] << 8 | buf->content[3]) + 2; - state->spu_end = 0; - state->end_found = 0; + state->spu_length = buf->content[0] << 8 | buf->content[1]; + state->spu_ctrl = (buf->content[2] << 8 | buf->content[3]) + 2; + state->spu_end = 0; + state->parse = 0; state->bytes_passed = 0; } - if (!state->end_found) { - int offset_in_buffer = state->spu_ctrl - state->bytes_passed; - if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) - state->spu_end = buf->content[offset_in_buffer] << 8; - offset_in_buffer++; - if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) { - state->spu_end |= buf->content[offset_in_buffer]; - state->end_found = 1; + if (state->spu_length) { + if (!state->parse) { + int offset_in_buffer = state->spu_ctrl - state->bytes_passed; + if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) + state->spu_end = buf->content[offset_in_buffer] << 8; + offset_in_buffer++; + if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) { + state->spu_end |= buf->content[offset_in_buffer]; + state->parse = 2; + } } +#if 0 /* TODO: this needs testing */ + if (state->parse > 1) { + int offset_in_buffer; + do { + offset_in_buffer = state->spu_ctrl + state->parse - state->bytes_passed; + if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) { + switch (buf->content[offset_in_buffer]) { + case 0x00: /* force display */ + state->parse++; + break; + case 0x01: /* show */ + case 0x02: /* hide */ + /* when only forced SPUs are allowed, change show to hide */ + if (spu_channel & 0x80) buf->content[offset_in_buffer] = 0x02; + state->parse++; + break; + case 0x03: /* colour lookup table */ + case 0x04: /* transparency palette */ + state->parse += 3; + break; + case 0x05: /* position and size */ + state->parse += 7; + break; + case 0x06: /* field offsets */ + state->parse += 5; + break; + case 0x07: /* wipe */ + case 0xff: /* end */ + default: + state->parse = 1; /* bail out */ + } + } + } while (offset_in_buffer < buf->size && state->parse > 1); + } +#endif + if (state->parse && this->menu) { + int offset_in_buffer = state->spu_end - state->bytes_passed; + if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) + buf->content[offset_in_buffer] = 0x00; + offset_in_buffer++; + if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) + buf->content[offset_in_buffer] = 0x00; + offset_in_buffer += 3; + if (offset_in_buffer >= 0 && offset_in_buffer < buf->size && + buf->content[offset_in_buffer] == 0x02) + buf->content[offset_in_buffer] = 0x00; + } + state->spu_length -= buf->size; + if (state->spu_length < 0) state->spu_length = 0; + state->bytes_passed += buf->size; } - if (state->end_found && this->menu) { - int offset_in_buffer = state->spu_end - state->bytes_passed; - if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) - buf->content[offset_in_buffer] = 0x00; - offset_in_buffer++; - if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) - buf->content[offset_in_buffer] = 0x00; - offset_in_buffer += 3; - if (offset_in_buffer >= 0 && offset_in_buffer < buf->size && - buf->content[offset_in_buffer] == 0x02) - buf->content[offset_in_buffer] = 0x00; - } - state->spu_length -= buf->size; - if (state->spu_length < 0) state->spu_length = 0; - state->bytes_passed += buf->size; /* filter unwanted streams */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) { @@ -472,10 +508,16 @@ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) llprintf(LOG_SPU, "Dropping SPU channel %d. Not selected stream_id\n", stream_id); return; } +#if 0 + /* We used to filter for SPU forcing here as well, but this does not work + * this way with the DXR3, because we have to evaluate the SPU command sequence + * to detect, if a particular SPU is forced or not. See the parsing code above. */ +#else if ((this->menu == 0) && (spu_channel & 0x80)) { llprintf(LOG_SPU, "Dropping SPU channel %d. Only allow forced display SPUs\n", stream_id); return; } +#endif pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); diff --git a/src/dxr3/dxr3_decode_video.c b/src/dxr3/dxr3_decode_video.c index 9364499dc..3a5cc002c 100644 --- a/src/dxr3/dxr3_decode_video.c +++ b/src/dxr3/dxr3_decode_video.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dxr3_decode_video.c,v 1.56 2004/07/11 11:47:10 hadess Exp $ + * $Id: dxr3_decode_video.c,v 1.57 2004/07/20 16:37:44 mroi Exp $ */ /* dxr3 video decoder plugin. @@ -35,14 +35,18 @@ #include <fcntl.h> #include <errno.h> +#define LOG_MODULE "dxr3_decode_video" +/* #define LOG_VERBOSE */ +/* #define LOG */ + +#define LOG_VID 0 +#define LOG_PTS 0 + #include "xine_internal.h" #include "buffer.h" #include "video_out_dxr3.h" #include "dxr3.h" -#define LOG_VID 0 -#define LOG_PTS 0 - /* once activated, we wait for this amount of missing pan&scan info * before disabling it again */ #define PAN_SCAN_WINDOW_SIZE 50 @@ -144,6 +148,10 @@ typedef struct dxr3_decoder_s { } dxr3_decoder_t; /* helper functions */ +static inline int dxr3_present(xine_stream_t *stream); +static inline int dxr3_mvcommand(int fd_control, int command); +static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t *buffer); +static int get_duration(dxr3_decoder_t *this); static void frame_format_change(dxr3_decoder_t *this); /* config callbacks */ @@ -152,6 +160,7 @@ static void dxr3_update_sync_mode(void *this_gen, xine_cfg_entry_t *entry); static void dxr3_update_enhanced_mode(void *this_gen, xine_cfg_entry_t *entry); static void dxr3_update_correct_durations(void *this_gen, xine_cfg_entry_t *entry); +/* inline helper implementations */ static inline int dxr3_present(xine_stream_t *stream) { plugin_node_t *node; @@ -166,9 +175,7 @@ static inline int dxr3_present(xine_stream_t *stream) present = (strcmp(vo_class->get_identifier(vo_class), DXR3_VO_ID) == 0); } } -#if LOG_VID - printf("dxr3_decode_video: dxr3 %s\n", present ? "present" : "not present"); -#endif + llprintf(LOG_VID, "dxr3 %s\n", present ? "present" : "not present"); return present; } @@ -183,116 +190,6 @@ static inline int dxr3_mvcommand(int fd_control, int command) return ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®); } -static inline void parse_mpeg_header(dxr3_decoder_t *this, uint8_t * buffer) -{ - this->frame_rate_code = buffer[3] & 15; - this->height = (buffer[0] << 16) | - (buffer[1] << 8) | - (buffer[2] << 0); - this->width = ((this->height >> 12) + 15) & ~15; - this->height = ((this->height & 0xfff) + 15) & ~15; - this->aspect_code = buffer[3] >> 4; - - this->have_header_info = 1; - - if (this->force_aspect) this->aspect_code = this->force_aspect; - - /* when width, height or aspect changes, - * we have to send an event for dxr3 spu decoder */ - if (!this->last_width || !this->last_height || !this->last_aspect_code || - (this->last_width != this->width) || - (this->last_height != this->height) || - (this->last_aspect_code != this->aspect_code)) { - frame_format_change(this); - this->last_width = this->width; - this->last_height = this->height; - this->last_aspect_code = this->aspect_code; - } -} - -static inline int get_duration(dxr3_decoder_t *this) -{ - int duration; - - switch (this->frame_rate_code) { - case 1: /* 23.976 */ - duration = 3754; /* actually it's 3753.75 */ - break; - case 2: /* 24.000 */ - duration = 3750; - break; - case 3: /* 25.000 */ - duration = this->repeat_first_field ? 5400 : 3600; - break; - case 4: /* 29.970 */ - duration = this->repeat_first_field ? 4505 : 3003; - break; - case 5: /* 30.000 */ - duration = 3000; - break; - case 6: /* 50.000 */ - duration = 1800; - break; - case 7: /* 59.940 */ - duration = 1502; /* actually it's 1501.5 */ - break; - case 8: /* 60.000 */ - duration = 1500; - break; - default: - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("dxr3_decode_video: WARNING: unknown frame rate code %d\n"), this->frame_rate_code); - duration = 0; - break; - } - - /* update stream metadata */ - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, duration); - - if (this->correct_durations && duration) { - /* we set an initial average frame duration here */ - if (!this->avg_duration) this->avg_duration = duration; - - /* Apply a correction to the framerate-code if metronom - * insists on a different frame duration. - * The code below is for NTCS streams labeled as PAL streams. - * (I have seen such things even on dvds!) - */ - if (this->avg_duration && this->avg_duration < 3300 && duration == 3600) { - if (this->force_duration_window > 0) { - /* we are already in a force_duration window, so we force duration */ - this->force_duration_window = FORCE_DURATION_WINDOW_SIZE; - return 3000; - } - if (this->force_duration_window <= 0 && (this->force_duration_window += 10) > 0) { - /* we just entered a force_duration window, so we start the correction */ - metronom_t *metronom = this->stream->metronom; - int64_t cur_offset; - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - _("dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n")); - /* those weird streams need an offset, too */ - cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET); - metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset - 28800); - this->force_duration_window = FORCE_DURATION_WINDOW_SIZE; - return 3000; - } - } - - if (this->force_duration_window == -FORCE_DURATION_WINDOW_SIZE) - /* we are far from a force_duration window */ - return duration; - if (--this->force_duration_window == 0) { - /* we have just left a force_duration window */ - metronom_t *metronom = this->stream->metronom; - int64_t cur_offset; - cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET); - metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset + 28800); - this->force_duration_window = -FORCE_DURATION_WINDOW_SIZE; - } - } - - return duration; -} static void *dxr3_init_plugin(xine_t *xine, void *data) { @@ -343,9 +240,7 @@ static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_ this->devnum = cfg->register_num(cfg, CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL); snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300-%d", this->devnum); -#if LOG_VID - printf("dxr3_decode_video: Entering video init, devname=%s.\n",tmpstr); -#endif + llprintf(LOG_VID, "Entering video init, devname=%s.\n",tmpstr); /* open later, because dxr3_video_out might have it open until we request a frame */ this->fd_video = -1; @@ -515,10 +410,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (this->repeat_first_field && this->sync_retry) /* reset counter */ this->sync_retry = 500; if (this->repeat_first_field && this->sync_every_frame) { -#if LOG_VID - printf("dxr3: non-progressive video detected. " - "disabling sync_every_frame.\n"); -#endif + llprintf(LOG_VID, "non-progressive video detected. disabling sync_every_frame.\n"); this->sync_every_frame = 0; this->sync_retry = 500; /* see you later */ } @@ -573,9 +465,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (this->correct_durations) { /* calculate an average frame duration from metronom's vpts values */ this->avg_duration = this->avg_duration * 0.9 + (vpts - this->last_vpts) * 0.1; -#if LOG_PTS - printf("dxr3_decode_video: average frame duration %d\n", this->avg_duration); -#endif + llprintf(LOG_PTS, "average frame duration %d\n", this->avg_duration); } if (this->skip_count) this->skip_count--; @@ -583,9 +473,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (this->resync_window == 0 && this->scr && this->enhanced_mode && !this->scr->scanning) { /* we are in sync, so we can lock the stream now */ -#if LOG_VID - printf("dxr3_decode_video: in sync, stream locked\n"); -#endif + llprintf(LOG_VID, "in sync, stream locked\n"); dxr3_mvcommand(this->fd_control, MVCOMMAND_SYNC); this->resync_window = -RESYNC_WINDOW_SIZE; pthread_mutex_lock(&this->scr->mutex); @@ -595,9 +483,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (this->resync_window != 0 && this->resync_window > -RESYNC_WINDOW_SIZE) this->resync_window--; } else { /* metronom says skip, so don't set vpts */ -#if LOG_VID - printf("dxr3_decode_video: %d frames to skip\n", skip); -#endif + llprintf(LOG_VID, "%d frames to skip\n", skip); vpts = 0; this->avg_duration = 0; @@ -617,9 +503,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (this->resync_window == 0 && this->scr && this->enhanced_mode && !this->scr->scanning) { /* switch off sync mode in the card to allow resyncing */ -#if LOG_VID - printf("dxr3_decode_video: out of sync, allowing stream resync\n"); -#endif + llprintf(LOG_VID, "out of sync, allowing stream resync\n"); dxr3_mvcommand(this->fd_control, MVCOMMAND_START); this->resync_window = RESYNC_WINDOW_SIZE; pthread_mutex_lock(&this->scr->mutex); @@ -639,9 +523,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) */ if (this->sync_retry) { if (!--this->sync_retry) { -#if LOG_VID - printf("dxr3_decode_video: retrying sync_every_frame"); -#endif + llprintf(LOG_VID, "retrying sync_every_frame"); this->sync_every_frame = 1; } } @@ -695,17 +577,13 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) this->dts_offset[1] = this->dts_offset[0]; this->dts_offset[0] = buf->decoder_info[0]; } -#if LOG_PTS - printf("dxr3_decode_video: PTS to DTS correction: %d\n", this->dts_offset[1]); -#endif + llprintf(LOG_PTS, "PTS to DTS correction: %d\n", this->dts_offset[1]); } vpts -= this->dts_offset[2]; delay = vpts - this->class->clock->get_current_time( this->class->clock); -#if LOG_PTS - printf("dxr3_decode_video: SETPTS got %lld\n", vpts); -#endif + llprintf(LOG_PTS, "SETPTS got %lld\n", vpts); /* SETPTS only if less then one second in the future and * either buffer has pts or sync_every_frame is set */ if ((delay > 0) && (delay < 90000) && @@ -724,11 +602,8 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (delay < 0) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_video: WARNING: overdue frame.\n"); } -#if LOG_PTS - else if (buf->pts) { - printf("dxr3_decode_video: skip buf->pts = %lld (no vpts)\n", buf->pts); - } -#endif + else if (buf->pts) + llprintf(LOG_PTS, "skip buf->pts = %lld (no vpts)\n", buf->pts); /* now write the content to the dxr3 mpeg device and, in a dramatic * break with open source tradition, check the return value @@ -797,6 +672,118 @@ static void dxr3_dispose(video_decoder_t *this_gen) free(this); } + +static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t * buffer) +{ + this->frame_rate_code = buffer[3] & 15; + this->height = (buffer[0] << 16) | + (buffer[1] << 8) | + (buffer[2] << 0); + this->width = ((this->height >> 12) + 15) & ~15; + this->height = ((this->height & 0xfff) + 15) & ~15; + this->aspect_code = buffer[3] >> 4; + + this->have_header_info = 1; + + if (this->force_aspect) this->aspect_code = this->force_aspect; + + /* when width, height or aspect changes, + * we have to send an event for dxr3 spu decoder */ + if (!this->last_width || !this->last_height || !this->last_aspect_code || + (this->last_width != this->width) || + (this->last_height != this->height) || + (this->last_aspect_code != this->aspect_code)) { + frame_format_change(this); + this->last_width = this->width; + this->last_height = this->height; + this->last_aspect_code = this->aspect_code; + } +} + +static int get_duration(dxr3_decoder_t *this) +{ + int duration; + + switch (this->frame_rate_code) { + case 1: /* 23.976 */ + duration = 3754; /* actually it's 3753.75 */ + break; + case 2: /* 24.000 */ + duration = 3750; + break; + case 3: /* 25.000 */ + duration = this->repeat_first_field ? 5400 : 3600; + break; + case 4: /* 29.970 */ + duration = this->repeat_first_field ? 4505 : 3003; + break; + case 5: /* 30.000 */ + duration = 3000; + break; + case 6: /* 50.000 */ + duration = 1800; + break; + case 7: /* 59.940 */ + duration = 1502; /* actually it's 1501.5 */ + break; + case 8: /* 60.000 */ + duration = 1500; + break; + default: + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("dxr3_decode_video: WARNING: unknown frame rate code %d\n"), this->frame_rate_code); + duration = 0; + break; + } + + /* update stream metadata */ + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, duration); + + if (this->correct_durations && duration) { + /* we set an initial average frame duration here */ + if (!this->avg_duration) this->avg_duration = duration; + + /* Apply a correction to the framerate-code if metronom + * insists on a different frame duration. + * The code below is for NTCS streams labeled as PAL streams. + * (I have seen such things even on dvds!) + */ + if (this->avg_duration && this->avg_duration < 3300 && duration == 3600) { + if (this->force_duration_window > 0) { + /* we are already in a force_duration window, so we force duration */ + this->force_duration_window = FORCE_DURATION_WINDOW_SIZE; + return 3000; + } + if (this->force_duration_window <= 0 && (this->force_duration_window += 10) > 0) { + /* we just entered a force_duration window, so we start the correction */ + metronom_t *metronom = this->stream->metronom; + int64_t cur_offset; + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + _("dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n")); + /* those weird streams need an offset, too */ + cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET); + metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset - 28800); + this->force_duration_window = FORCE_DURATION_WINDOW_SIZE; + return 3000; + } + } + + if (this->force_duration_window == -FORCE_DURATION_WINDOW_SIZE) + /* we are far from a force_duration window */ + return duration; + if (--this->force_duration_window == 0) { + /* we have just left a force_duration window */ + metronom_t *metronom = this->stream->metronom; + int64_t cur_offset; + cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET); + metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset + 28800); + this->force_duration_window = -FORCE_DURATION_WINDOW_SIZE; + } + } + + return duration; +} + static void frame_format_change(dxr3_decoder_t *this) { /* inform the dxr3 SPU decoder about the current format, diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c index 1e1576570..d0bb58791 100644 --- a/src/dxr3/dxr3_mpeg_encoders.c +++ b/src/dxr3/dxr3_mpeg_encoders.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dxr3_mpeg_encoders.c,v 1.19 2004/04/11 15:27:20 mroi Exp $ + * $Id: dxr3_mpeg_encoders.c,v 1.20 2004/07/20 16:37:44 mroi Exp $ */ /* mpeg encoders for the dxr3 video out plugin. @@ -46,11 +46,13 @@ #include <errno.h> #include <math.h> +#define LOG_MODULE "dxr3_mpeg_encoder" +/* #define LOG_VERBOSE */ +/* #define LOG */ + #include "xineutils.h" #include "video_out_dxr3.h" -#define LOG_ENC 1 - /* buffer size for encoded mpeg1 stream; will hold one intra frame * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ #define DEFAULT_BUFFER_SIZE 512*1024 @@ -147,9 +149,7 @@ static int rte_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) double fps; if (this->context) { /* already running */ -#if LOG_ENC - printf("dxr3_mpeg_encoder: closing current encoding context.\n"); -#endif + lprintf("closing current encoding context.\n"); rte_stop(this->context); rte_context_destroy(this->context); this->context = 0; @@ -357,15 +357,11 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) memset(this->out[0], 16, image_size); memset(this->out[1], 128, image_size/4); memset(this->out[2], 128, image_size/4); -#if LOG_ENC - printf("dxr3_mpeg_encoder: Using YUY2->YV12 conversion\n"); -#endif + lprintf("Using YUY2->YV12 conversion\n"); } if (this->context) { -#if LOG_ENC - printf("dxr3_mpeg_encoder: closing current encoding context.\n"); -#endif + lprintf("closing current encoding context.\n"); fame_close(this->context); this->context = 0; } @@ -392,13 +388,11 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) _("The encoding quality of the libfame mpeg encoder library. " "Lower is faster but gives noticeable artifacts. Higher is better but slower."), 10, NULL,NULL); -#if LOG_ENC /* the really interesting bit is the quantizer scale. The formula * below is copied from libfame's sources (could be changed in the * future) */ - printf("dxr3_mpeg_encoder: quality %d -> quant scale = %d\n", this->fp.quality, + lprintf("quality %d -> quant scale = %d\n", this->fp.quality, 1 + (30 * (100 - this->fp.quality) + 50) / 100); -#endif this->fp.width = frame->vo_frame.width; this->fp.height = frame->oheight; this->fp.profile = "mpeg1"; @@ -412,27 +406,19 @@ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) /* start guessing the framerate */ fps = 90000.0 / frame->vo_frame.duration; if (fps < 23.988) { /* NTSC-FILM */ -#if LOG_ENC - printf("dxr3_mpeg_encoder: setting mpeg output framerate to NTSC-FILM (23.976 Hz)\n"); -#endif + lprintf("setting mpeg output framerate to NTSC-FILM (23.976 Hz)\n"); this->fp.frame_rate_num = 24000; this->fp.frame_rate_den = 1001; } else if (fps < 24.5) { /* FILM */ -#if LOG_ENC - printf("dxr3_mpeg_encoder: setting mpeg output framerate to FILM (24 Hz)\n"); -#endif + lprintf("setting mpeg output framerate to FILM (24 Hz)\n"); this->fp.frame_rate_num = 24; this->fp.frame_rate_den = 1; } else if (fps < 27.485) { /* PAL */ -#if LOG_ENC - printf("dxr3_mpeg_encoder: setting mpeg output framerate to PAL (25 Hz)\n"); -#endif + lprintf("setting mpeg output framerate to PAL (25 Hz)\n"); this->fp.frame_rate_num = 25; this->fp.frame_rate_den = 1; } else { /* NTSC */ -#if LOG_ENC - printf("dxr3_mpeg_encoder: setting mpeg output framerate to NTSC (29.97 Hz)\n"); -#endif + lprintf("setting mpeg output framerate to NTSC (29.97 Hz)\n"); this->fp.frame_rate_num = 30000; this->fp.frame_rate_den = 1001; } diff --git a/src/dxr3/dxr3_scr.c b/src/dxr3/dxr3_scr.c index 8a9cf1613..bc60de491 100644 --- a/src/dxr3/dxr3_scr.c +++ b/src/dxr3/dxr3_scr.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dxr3_scr.c,v 1.15 2004/07/11 11:47:10 hadess Exp $ + * $Id: dxr3_scr.c,v 1.16 2004/07/20 16:37:44 mroi Exp $ */ /* dxr3 scr plugin. @@ -34,11 +34,13 @@ #include <unistd.h> #include <errno.h> +#define LOG_MODULE "dxr3_scr" +/* #define LOG_VERBOSE */ +/* #define LOG */ + #include "dxr3.h" #include "dxr3_scr.h" -#define LOG_SCR 0 - /* functions required by xine api */ static int dxr3_scr_get_priority(scr_plugin_t *scr); @@ -51,6 +53,7 @@ static void dxr3_scr_exit(scr_plugin_t *scr); /* config callback */ static void dxr3_scr_update_priority(void *this_gen, xine_cfg_entry_t *entry); +/* inline helper implementations */ static inline int dxr3_mvcommand(int fd_control, int command) { em8300_register_t reg; @@ -62,6 +65,7 @@ static inline int dxr3_mvcommand(int fd_control, int command) return ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®); } + dxr3_scr_t *dxr3_scr_init(xine_t *xine) { dxr3_scr_t *this; @@ -103,9 +107,7 @@ dxr3_scr_t *dxr3_scr_init(xine_t *xine) pthread_mutex_init(&this->mutex, NULL); -#if LOG_SCR - printf("dxr3_scr: init complete\n"); -#endif + lprintf("init complete\n"); return this; } @@ -126,9 +128,7 @@ static void dxr3_scr_start(scr_plugin_t *scr, int64_t vpts) this->offset = vpts - ((int64_t)vpts32 << 1); if (ioctl(this->fd_control, EM8300_IOCTL_SCR_SET, &vpts32)) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: start failed (%s)\n", strerror(errno)); -#if LOG_SCR - printf("dxr3_scr: started with vpts %lld\n", vpts); -#endif + lprintf("started with vpts %lld\n", vpts); /* mis-use vpts32 to set the clock speed to 0x900, which is normal speed */ vpts32 = 0x900; ioctl(this->fd_control, EM8300_IOCTL_SCR_SETSPEED, &vpts32); @@ -178,9 +178,7 @@ static void dxr3_scr_adjust(scr_plugin_t *scr, int64_t vpts) this->last_pts = vpts32; this->offset = vpts - ((int64_t)vpts32 << 1); } -#if LOG_SCR - printf("dxr3_scr: adjusted to vpts %lld\n", vpts); -#endif + lprintf("adjusted to vpts %lld\n", vpts); pthread_mutex_unlock(&this->mutex); } @@ -237,9 +235,7 @@ static int dxr3_scr_set_speed(scr_plugin_t *scr, int speed) pthread_mutex_unlock(&this->mutex); -#if LOG_SCR - printf("dxr3_scr: speed set to mode %d\n", speed); -#endif + lprintf("speed set to mode %d\n", speed); return speed; } diff --git a/src/dxr3/dxr3_spu_encoder.c b/src/dxr3/dxr3_spu_encoder.c index f1d362a78..b8ca223f6 100644 --- a/src/dxr3/dxr3_spu_encoder.c +++ b/src/dxr3/dxr3_spu_encoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: dxr3_spu_encoder.c,v 1.7 2004/03/04 14:40:04 mroi Exp $ + * $Id: dxr3_spu_encoder.c,v 1.8 2004/07/20 16:37:44 mroi Exp $ */ #include <stdio.h> @@ -25,10 +25,8 @@ #include <float.h> #define LOG_MODULE "dxr3_spu_encoder" -/* -#define LOG_VERBOSE -#define LOG -*/ +/* #define LOG_VERBOSE */ +/* #define LOG */ #include "video_out_dxr3.h" diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c index 8fc8c4ec2..654f1547f 100644 --- a/src/dxr3/video_out_dxr3.c +++ b/src/dxr3/video_out_dxr3.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: video_out_dxr3.c,v 1.102 2004/06/13 16:00:17 mroi Exp $ + * $Id: video_out_dxr3.c,v 1.103 2004/07/20 16:37:44 mroi Exp $ */ /* mpeg1 encoding video out plugin for the dxr3. @@ -55,6 +55,13 @@ # include <X11/extensions/Xinerama.h> #endif +#define LOG_MODULE "video_out_dxr3" +/* #define LOG_VERBOSE */ +/* #define LOG */ + +#define LOG_VID 0 +#define LOG_OVR 0 + #include "xine_internal.h" #include "xineutils.h" #include "video_out.h" @@ -62,9 +69,6 @@ #include "dxr3.h" #include "video_out_dxr3.h" -#define LOG_VID 0 -#define LOG_OVR 0 - /* the amount of extra time we give the card for decoding */ #define DECODE_PIPE_PREBUFFER 10000 @@ -268,9 +272,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v 20, dxr3_update_enhanced_mode, this); snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300-%d", class->devnum); -#if LOG_VID - printf("video_out_dxr3: Entering video init, devname = %s.\n", tmpstr); -#endif + llprintf(LOG_VID, "Entering video init, devname = %s.\n", tmpstr); if ((this->fd_control = open(tmpstr, O_WRONLY)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, @@ -401,9 +403,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v if (!(class->visual_type == XINE_VISUAL_TYPE_X11) && confnum > 1) /* no overlay modes when not using X11 -> switch to letterboxed tv */ confnum = 0; -#if LOG_VID - printf("video_out_dxr3: videomode = %s\n", videoout_modes[confnum]); -#endif + llprintf(LOG_VID, "videomode = %s\n", videoout_modes[confnum]); switch (confnum) { case 0: /* letterboxed tv mode */ this->overlay_enabled = 0; @@ -418,9 +418,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v #ifdef HAVE_X11 case 2: /* letterboxed overlay mode */ case 3: /* widescreen overlay mode */ -#if LOG_VID - printf("video_out_dxr3: setting up overlay mode\n"); -#endif + llprintf(LOG_VID, "setting up overlay mode\n"); gather_screen_vars(this, visual_gen); this->overlay.xine = this->class->xine; if (dxr3_overlay_read_state(&this->overlay) == 0) { @@ -460,21 +458,15 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v switch (confnum) { case 0: /* ntsc */ this->tv_mode = EM8300_VIDEOMODE_NTSC; -#if LOG_VID - printf("video_out_dxr3: setting tv_mode to NTSC\n"); -#endif + llprintf(LOG_VID, "setting tv_mode to NTSC\n"); break; case 1: /* pal */ this->tv_mode = EM8300_VIDEOMODE_PAL; -#if LOG_VID - printf("video_out_dxr3: setting tv_mode to PAL 50Hz\n"); -#endif + llprintf(LOG_VID, "setting tv_mode to PAL 50Hz\n"); break; case 2: /* pal60 */ this->tv_mode = EM8300_VIDEOMODE_PAL60; -#if LOG_VID - printf("video_out_dxr3: setting tv_mode to PAL 60Hz\n"); -#endif + llprintf(LOG_VID, "setting tv_mode to PAL 60Hz\n"); break; default: this->tv_mode = EM8300_VIDEOMODE_DEFAULT; @@ -1087,17 +1079,13 @@ static int dxr3_set_property(vo_driver_t *this_gen, int property, int value) switch(value) { case XINE_VO_ASPECT_SQUARE: case XINE_VO_ASPECT_4_3: -#if LOG_VID - printf("video_out_dxr3: setting aspect ratio to full\n"); -#endif + llprintf(LOG_VID, "setting aspect ratio to full\n"); val = EM8300_ASPECTRATIO_4_3; value = XINE_VO_ASPECT_4_3; break; case XINE_VO_ASPECT_ANAMORPHIC: case XINE_VO_ASPECT_DVB: -#if LOG_VID - printf("video_out_dxr3: setting aspect ratio to anamorphic\n"); -#endif + llprintf(LOG_VID, "setting aspect ratio to anamorphic\n"); val = EM8300_ASPECTRATIO_16_9; value = XINE_VO_ASPECT_ANAMORPHIC; } @@ -1115,9 +1103,7 @@ static int dxr3_set_property(vo_driver_t *this_gen, int property, int value) break; case VO_PROP_ZOOM_X: if (value == 1) { -#if LOG_VID - printf("video_out_dxr3: enabling 16:9 zoom\n"); -#endif + llprintf(LOG_VID, "enabling 16:9 zoom\n"); if (!this->widescreen_enabled) { dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, XINE_VO_ASPECT_4_3); if (!this->overlay_enabled) dxr3_zoomTV(this); @@ -1126,20 +1112,25 @@ static int dxr3_set_property(vo_driver_t *this_gen, int property, int value) * can switch to 16:9 mode. But the dxr3 cannot do this. */ } } else if (value == -1) { -#if LOG_VID - printf("video_out_dxr3: disabling 16:9 zoom\n"); -#endif + llprintf(LOG_VID, "disabling 16:9 zoom\n"); dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect); } break; case VO_PROP_TVMODE: if (++this->tv_mode > EM8300_VIDEOMODE_LAST) this->tv_mode = EM8300_VIDEOMODE_PAL; -#if LOG_VID - printf("video_out_dxr3: Changing TVMode to "); +#ifdef LOG + switch (this->tv_mode) { + case EM8300_VIDEOMODE_PAL: + llprintf(LOG_VID, "Changing TVMode to PAL\n"); + break; + case EM8300_VIDEOMODE_PAL60: + llprintf(LOG_VID, "Changing TVMode to PAL60\n"); + break; + case EM8300_VIDEOMODE_NTSC: + llprintf(LOG_VID, "Changing TVMode to NTSC\n"); + break; + } #endif - if (this->tv_mode == EM8300_VIDEOMODE_PAL) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "PAL\n"); - if (this->tv_mode == EM8300_VIDEOMODE_PAL60) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "PAL60\n"); - if (this->tv_mode == EM8300_VIDEOMODE_NTSC) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "NTSC\n"); if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting video mode failed (%s)\n", strerror(errno)); @@ -1209,15 +1200,11 @@ static int dxr3_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *da int window_showing = (int)data; int val; if (!window_showing) { -#if LOG_VID - printf("video_out_dxr3: Hiding video window and diverting video to TV\n"); -#endif + llprintf(LOG_VID, "Hiding video window and diverting video to TV\n"); val = EM8300_OVERLAY_MODE_OFF; this->overlay_enabled = 0; } else { -#if LOG_VID - printf("video_out_dxr3: Using video window for overlaying video\n"); -#endif + llprintf(LOG_VID, "Using video window for overlaying video\n"); val = EM8300_OVERLAY_MODE_OVERLAY; this->overlay_enabled = 1; this->scale.force_redraw = 1; @@ -1239,9 +1226,7 @@ static void dxr3_dispose(vo_driver_t *this_gen) dxr3_driver_t *this = (dxr3_driver_t *)this_gen; int val = EM8300_OVERLAY_MODE_OFF; -#if LOG_VID - printf("video_out_dxr3: vo exit called\n"); -#endif + llprintf(LOG_VID, "vo exit called\n"); if (this->enc && this->enc->on_close) this->enc->on_close(this); if(this->overlay_enabled) @@ -1299,10 +1284,8 @@ static void gather_screen_vars(dxr3_driver_t *this, const x11_visual_t *vis) this->overlay.screen_depth = DisplayPlanes(this->display, scrn); this->scale.frame_output_cb = (void *)vis->frame_output_cb; -#if LOG_OVR - printf("video_out_dxr3: xres: %d, yres: %d, depth: %d\n", + llprintf(LOG_OVR, "xres: %d, yres: %d, depth: %d\n", this->overlay.screen_xres, this->overlay.screen_yres, this->overlay.screen_depth); -#endif } /* dxr3_overlay_read_state helper structure */ @@ -1327,14 +1310,10 @@ static int lookup_parameter(struct lut_entry *lut, char *name, if (strcmp(name, lut[i].name) == 0) { *ptr = lut[i].ptr; *type = lut[i].type; -#if LOG_OVR - printf("video_out_dxr3: found parameter \"%s\"\n", name); -#endif + llprintf(LOG_OVR, "found parameter \"%s\"\n", name); return 1; } -#if LOG_OVR - printf("video_out_dxr3: WARNING: unknown parameter \"%s\"\n", name); -#endif + llprintf(LOG_OVR, "WARNING: unknown parameter \"%s\"\n", name); return 0; } @@ -1372,9 +1351,7 @@ static int dxr3_overlay_read_state(dxr3_overlay_t *this) fname[sizeof(fname) - strlen(tmp) - sizeof("/.overlay")] = '\0'; strcat(fname, "/.overlay"); strcat(fname, tmp); -#if LOG_OVR - printf("video_out_dxr3: attempting to open %s\n", fname); -#endif + llprintf(LOG_OVR, "attempting to open %s\n", fname); if (!(fp = fopen(fname, "r"))) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n")); @@ -1390,33 +1367,23 @@ static int dxr3_overlay_read_state(dxr3_overlay_t *this) switch(type) { case TYPE_INT: sscanf(tok, "%d", (int *)ptr); -#if LOG_OVR - printf("video_out_dxr3: value \"%s\" = %d\n", tok, *(int *)ptr); -#endif + llprintf(LOG_OVR, "value \"%s\" = %d\n", tok, *(int *)ptr); break; case TYPE_XINT: sscanf(tok, "%x", (int *)ptr); -#if LOG_OVR - printf("video_out_dxr3: value \"%s\" = %d\n", tok, *(int *)ptr); -#endif + llprintf(LOG_OVR, "value \"%s\" = %d\n", tok, *(int *)ptr); break; case TYPE_FLOAT: sscanf(tok, "%f", (float *)ptr); -#if LOG_OVR - printf("video_out_dxr3: value \"%s\" = %f\n", tok, *(float *)ptr); -#endif + llprintf(LOG_OVR, "value \"%s\" = %f\n", tok, *(float *)ptr); break; case TYPE_COEFF: for(j = 0; j < 3; j++) { sscanf(tok, "%f", &((struct coeff *)ptr)[j].k); -#if LOG_OVR - printf("video_out_dxr3: value (%d,k) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].k); -#endif + llprintf(LOG_OVR, "value (%d,k) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].k); tok = strtok(NULL, " \n"); sscanf(tok, "%f", &((struct coeff *)ptr)[j].m); -#if LOG_OVR - printf("video_out_dxr3: value (%d,m) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].m); -#endif + llprintf(LOG_OVR, "value (%d,m) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].m); tok = strtok(NULL, " \n"); } break; @@ -1451,18 +1418,14 @@ static int dxr3_overlay_set_keycolor(dxr3_overlay_t *this) int32_t overlay_limit; int ret; -#if LOG_OVR - printf("video_out_dxr3: set_keycolor: r = %f, g = %f, b = %f, interval = %f\n", + llprintf(LOG_OVR, "set_keycolor: r = %f, g = %f, b = %f, interval = %f\n", r, g, b, interval); -#endif overlay_limit = /* lower limit */ col_interp(r - interval, this->colcal_lower[0]) << 16 | col_interp(g - interval, this->colcal_lower[1]) << 8 | col_interp(b - interval, this->colcal_lower[2]); -#if LOG_OVR - printf("video_out_dxr3: lower overlay_limit = %d\n", overlay_limit); -#endif + llprintf(LOG_OVR, "lower overlay_limit = %d\n", overlay_limit); attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_LOWER; attr.value = overlay_limit; if ((ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)) < 0) { @@ -1475,9 +1438,7 @@ static int dxr3_overlay_set_keycolor(dxr3_overlay_t *this) col_interp(r + interval, this->colcal_upper[0]) << 16 | col_interp(g + interval, this->colcal_upper[1]) << 8 | col_interp(b + interval, this->colcal_upper[2]); -#if LOG_OVR - printf("video_out_dxr3: upper overlay_limit = %d\n", overlay_limit); -#endif + llprintf(LOG_OVR, "upper overlay_limit = %d\n", overlay_limit); attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_UPPER; attr.value = overlay_limit; if ((ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)) < 0) diff --git a/src/libffmpeg/xine_encoder.c b/src/libffmpeg/xine_encoder.c index 7801d7aea..8d6d72195 100644 --- a/src/libffmpeg/xine_encoder.c +++ b/src/libffmpeg/xine_encoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_encoder.c,v 1.15 2004/04/26 19:33:47 mroi Exp $ + * $Id: xine_encoder.c,v 1.16 2004/07/20 16:37:45 mroi Exp $ */ /* mpeg encoders for the dxr3 video out plugin. */ @@ -29,11 +29,13 @@ #include <errno.h> #include <math.h> +#define LOG_MODULE "dxr3_mpeg_encoder" +/* #define LOG_VERBOSE */ +/* #define LOG */ + #include "video_out_dxr3.h" #include "libavcodec/avcodec.h" -#define LOG_ENC 0 - /* buffer size for encoded mpeg1 stream; will hold one intra frame * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ #define DEFAULT_BUFFER_SIZE 512*1024 @@ -65,9 +67,7 @@ int dxr3_encoder_init(dxr3_driver_t *drv) avcodec_init(); register_avcodec(&mpeg1video_encoder); -#if LOG_ENC - printf("dxr3_mpeg_encoder: lavc init , version %x\n", avcodec_version()); -#endif + lprintf("lavc init , version %x\n", avcodec_version()); this = xine_xmalloc(sizeof(lavc_data_t)); if (!this) return 0; @@ -113,38 +113,38 @@ static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) memset(this->out[0], 16, image_size); memset(this->out[1], 128, image_size/4); memset(this->out[2], 128, image_size/4); -#if LOG_ENC - printf("dxr3_mpeg_encoder: Using YUY2->YV12 conversion\n"); -#endif + lprintf("Using YUY2->YV12 conversion\n"); } /* resolution must be a multiple of two */ if ((frame->vo_frame.pitches[0] % 2 != 0) || (frame->oheight % 2 != 0)) { - printf("dxr3_mpeg_encoder: lavc only handles video dimensions which are multiples of 2\n"); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: lavc only handles video dimensions which are multiples of 2\n"); return 0; } /* get mpeg codec handle */ codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); if (!codec) { - printf("dxr3_mpeg_encoder: lavc MPEG1 codec not found\n"); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: lavc MPEG1 codec not found\n"); return 0; } -#if LOG_ENC - printf("dxr3_mpeg_encoder: lavc MPEG1 encoder found.\n"); -#endif + lprintf("lavc MPEG1 encoder found.\n"); this->width = frame->vo_frame.pitches[0]; this->height = frame->oheight; this->context = avcodec_alloc_context(); if (!this->context) { - printf("dxr3_mpeg_encoder: Couldn't start the ffmpeg library\n"); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Couldn't start the ffmpeg library\n"); return 0; } this->picture = avcodec_alloc_frame(); if (!this->picture) { - printf("dxr3_mpeg_encoder: Couldn't allocate ffmpeg frame\n"); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Couldn't allocate ffmpeg frame\n"); return 0; } @@ -178,9 +178,7 @@ static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) 10, NULL, NULL); } -#if LOG_ENC - printf("dxr3_mpeg_encoder: lavc -> bitrate %d \n", this->context->bit_rate); -#endif + lprintf("lavc -> bitrate %d \n", this->context->bit_rate); this->context->width = frame->vo_frame.pitches[0]; this->context->height = frame->oheight; @@ -201,17 +199,16 @@ static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) /* open avcodec */ if (avcodec_open(this->context, codec) < 0) { - printf("dxr3_mpeg_encoder: could not open codec\n"); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: could not open codec\n"); return 0; } -#if LOG_ENC - printf("dxr3_mpeg_encoder: lavc MPEG1 codec opened.\n"); -#endif + lprintf("dxr3_mpeg_encoder: lavc MPEG1 codec opened.\n"); if (!this->ffmpeg_buffer) this->ffmpeg_buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE); /* why allocate more than needed ?! */ if (!this->ffmpeg_buffer) { - printf("dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n"); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n"); return 0; } @@ -228,7 +225,7 @@ static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) /* ignore old frames */ if ((frame->vo_frame.pitches[0] != this->context->width) || (frame->oheight != this->context->height)) { frame->vo_frame.free(&frame->vo_frame); - printf("LAVC ignoring frame !!!\n"); + lprintf("LAVC ignoring frame !!!\n"); return 1; } @@ -242,22 +239,20 @@ static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) written = write(drv->fd_video, this->ffmpeg_buffer, size); if (written < 0) { - printf("dxr3_mpeg_encoder: video device write failed (%s)\n", - strerror(errno)); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); return 0; } if (written != size) - printf("dxr3_mpeg_encoder: Could only write %d of %d mpeg bytes.\n", - written, size); + xprintf(drv->class->xine, XINE_VERBOSITY_LOG, + "dxr3_mpeg_encoder: Could only write %d of %d mpeg bytes.\n", written, size); return 1; } static int lavc_on_unneeded(dxr3_driver_t *drv) { lavc_data_t *this = (lavc_data_t *)drv->enc; -#if LOG_ENC - printf("dxr3_mpeg_encoder: flushing buffers\n"); -#endif + lprintf("flushing buffers\n"); if (this->context) { avcodec_close(this->context); free(this->context); @@ -278,7 +273,7 @@ static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_ if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { /* need YUY2->YV12 conversion */ if (!(this->out[0] && this->out[1] && this->out[2]) ) { - printf("dxr3_mpeg_encoder: Internal YV12 buffer not created.\n"); + lprintf("Internal YV12 buffer not created.\n"); return 0; } this->picture->data[0] = this->out[0] + frame->vo_frame.pitches[0] * drv->top_bar; /* y */ |