int txt_render(int size, uint8_t *pdata)
{
  const uint8_t *bp;
  int left;
  int lines;
  int64_t pts;
  vbi_sliced *psliced = txtdata->sliced;

  bp = pdata;
  left = size;
  if (txtdata) {
    while ( left > 0 ) {			
      lines = vbi_dvb_demux_cor( txtdata->m_demuxer, psliced, SOFTSUB_SLICED_NB ,&pts, &bp, &left );
      if ( lines > 0 ) {
	vbi_decode( txtdata->m_decoder, psliced, lines, pts/90000.0 );
      }
    }
  }
  return 0;
}
예제 #2
0
/*****************************************************************************
 * Decode:
 *****************************************************************************/
static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t   *p_sys = p_dec->p_sys;
    block_t         *p_block;
    subpicture_t    *p_spu = NULL;
    video_format_t  fmt;
    bool            b_cached = false;
    vbi_page        p_page;
    const uint8_t   *p_pos;
    unsigned int    i_left;

    if( (pp_block == NULL) || (*pp_block == NULL) )
        return NULL;

    p_block = *pp_block;
    *pp_block = NULL;

    p_pos = p_block->p_buffer;
    i_left = p_block->i_buffer;

    while( i_left > 0 )
    {
        vbi_sliced      p_sliced[MAX_SLICES];
        unsigned int    i_lines = 0;
        int64_t         i_pts;

        i_lines = vbi_dvb_demux_cor( p_sys->p_dvb_demux, p_sliced,
                                     MAX_SLICES, &i_pts, &p_pos, &i_left );

        if( i_lines > 0 )
            vbi_decode( p_sys->p_vbi_dec, p_sliced, i_lines, i_pts / 90000.0 );
    }

    /* */
    vlc_mutex_lock( &p_sys->lock );
    const int i_align = p_sys->i_align;
    const unsigned int i_wanted_page = p_sys->i_wanted_page;
    const unsigned int i_wanted_subpage = p_sys->i_wanted_subpage;
    const bool b_opaque = p_sys->b_opaque;
    vlc_mutex_unlock( &p_sys->lock );

    /* Try to see if the page we want is in the cache yet */
    memset( &p_page, 0, sizeof(vbi_page) );
    b_cached = vbi_fetch_vt_page( p_sys->p_vbi_dec, &p_page,
                                  vbi_dec2bcd( i_wanted_page ),
                                  i_wanted_subpage, VBI_WST_LEVEL_3p5,
                                  25, true );

    if( i_wanted_page == p_sys->i_last_page && !p_sys->b_update )
        goto error;

    if( !b_cached )
    {
        if( p_sys->i_last_page != i_wanted_page )
        {
            /* We need to reset the subtitle */
            p_spu = Subpicture( p_dec, &fmt, true,
                                p_page.columns, p_page.rows,
                                i_align, p_block->i_pts );
            if( !p_spu )
                goto error;
            p_spu->p_region->psz_text = strdup("");

            p_sys->b_update = true;
            p_sys->i_last_page = i_wanted_page;
            goto exit;
        }
        goto error;
    }

    p_sys->b_update = false;
    p_sys->i_last_page = i_wanted_page;
#ifdef ZVBI_DEBUG
    msg_Dbg( p_dec, "we now have page: %d ready for display",
             i_wanted_page );
#endif
    /* If there is a page or sub to render, then we do that here */
    /* Create the subpicture unit */
    p_spu = Subpicture( p_dec, &fmt, p_sys->b_text,
                        p_page.columns, p_page.rows,
                        i_align, p_block->i_pts );
    if( !p_spu )
        goto error;

    if( p_sys->b_text )
    {
        unsigned int i_textsize = 7000;
        int i_total;
        char p_text[i_textsize+1];

        i_total = vbi_print_page_region( &p_page, p_text, i_textsize,
                        "UTF-8", 0, 0, 0, 0, p_page.columns, p_page.rows );
        p_text[i_total] = '\0';
        /* Strip off the pagenumber */
        if( i_total <= 40 )
            goto error;
        p_spu->p_region->psz_text = strdup( &p_text[8] );

#ifdef ZVBI_DEBUG
        msg_Info( p_dec, "page %x-%x(%d)\n%s", p_page.pgno, p_page.subno, i_total, p_text );
#endif
    }
    else
    {
        picture_t *p_pic = p_spu->p_region->p_picture;

        /* ZVBI is stupid enough to assume pitch == width */
        p_pic->p->i_pitch = 4 * fmt.i_width;
        vbi_draw_vt_page( &p_page, ZVBI_PIXFMT_RGBA32,
                          p_spu->p_region->p_picture->p->p_pixels, 1, 1 );

        vlc_mutex_lock( &p_sys->lock );
        memcpy( p_sys->nav_link, &p_page.nav_link, sizeof( p_sys->nav_link )) ;
        vlc_mutex_unlock( &p_sys->lock );

        OpaquePage( p_pic, p_page, fmt, b_opaque );
    }

exit:
    vbi_unref_page( &p_page );
    block_Release( p_block );
    return p_spu;

error:
    vbi_unref_page( &p_page );
    if( p_spu != NULL )
    {
        decoder_DeleteSubpicture( p_dec, p_spu );
        p_spu = NULL;
    }

    block_Release( p_block );
    return NULL;
}
예제 #3
0
static int
dvb_read			(vbi_capture *		cap,
				 vbi_capture_buffer **	raw,
				 vbi_capture_buffer **	sliced,
				 const struct timeval *	timeout)
{
	vbi_capture_dvb *dvb = PARENT (cap, vbi_capture_dvb, capture);
	vbi_capture_buffer *sb;
	struct timeval start;
	struct timeval now;
	unsigned int n_lines;
	int64_t pts;

	if (!sliced || !(sb = *sliced)) {
		sb = &dvb->sliced_buffer;
		sb->data = dvb->sliced_data;
	}

	start.tv_sec = 0;
	start.tv_usec = 0;

	/* When timeout is zero elapsed time doesn't matter. */
	if ((timeout->tv_sec | timeout->tv_usec) > 0)
		gettimeofday (&start, /* timezone */ NULL);

	now = start;

	for (;;) {
		if (0 == dvb->b_left) {
			ssize_t actual;

			actual = select_read (dvb, &now, &start, timeout);
			if (actual <= 0)
				return actual;

			gettimeofday (&now, /* timezone */ NULL);

			/* XXX inaccurate. Should be the time when we
			   received the first byte of the first packet
			   containing data of the returned frame. Or so. */
			dvb->sample_time = now.tv_sec
				+ now.tv_usec * (1 / 1e6);

			dvb->bp = dvb->pes_buffer;
			dvb->b_left = actual;
		}

		/* Demultiplexer coroutine. Returns when one frame is complete
		   or the buffer is empty, advancing bp and b_left. Don't
		   change sb->data in flight. */
		/* XXX max sliced lines needs an API change. Currently this
		   value is determined by vbi_raw_decoder line count below,
		   256 / 2 because fields don't really apply here and in
		   practice even 32 should be enough. */
		n_lines = vbi_dvb_demux_cor (dvb->demux,
					     sb->data,
					     /* max sliced lines */ 128,
					     &pts,
					     &dvb->bp,
					     &dvb->b_left);
		if (n_lines > 0)
			break;

		if (dvb->bug_compatible) {
			/* Only one read(), timeout ignored. */
			return 0; /* timeout */
		} else {
			/* Read until EAGAIN, another error or the
			   timeout expires, in this order. */
		}
	}

	if (sliced) {
		sb->size = n_lines * sizeof (vbi_sliced);
		sb->timestamp = dvb->sample_time;

		/* XXX PTS needs an API change.
		   sb->sample_time = dvb->sample_time;
		   sb->stream_time = pts; (first sliced line) */
		dvb->last_pts = pts;

		*sliced = sb;
	}

	if (raw && *raw) {
		/* Not implemented yet. */
		sb = *raw;
		sb->size = 0;
	}

	return 1; /* success */
}