コード例 #1
0
ファイル: video_overlay.c プロジェクト: bielorkut/showtime
/**
 * Decode subtitles from LAVC
 */
static void
video_subtitles_lavc(video_decoder_t *vd, media_buf_t *mb,
		     AVCodecContext *ctx)
{
  AVSubtitle sub;
  int size = 0, i, x, y;
  video_overlay_t *vo;

  AVPacket avpkt;
  av_init_packet(&avpkt);
  avpkt.data = mb->mb_data;
  avpkt.size = mb->mb_size;

  if(avcodec_decode_subtitle2(ctx, &sub, &size, &avpkt) < 1 || size < 1) 
    return;

  if(sub.num_rects == 0) {
    // Flush screen
    vo = calloc(1, sizeof(video_overlay_t));
    vo->vo_type = VO_TIMED_FLUSH;
    vo->vo_start = mb->mb_pts + sub.start_display_time * 1000;
    video_overlay_enqueue(vd, vo);
    return;
  }

  for(i = 0; i < sub.num_rects; i++) {
    AVSubtitleRect *r = sub.rects[i];

    switch(r->type) {

    case SUBTITLE_BITMAP:
      vo = calloc(1, sizeof(video_overlay_t));

      vo->vo_start = mb->mb_pts + sub.start_display_time * 1000;
      vo->vo_stop  = mb->mb_pts + sub.end_display_time * 1000;
		  
      vo->vo_x = r->x;
      vo->vo_y = r->y;

      vo->vo_pixmap = pixmap_create(r->w, r->h, PIX_FMT_BGR32, 1);

      const uint8_t *src = r->pict.data[0];
      const uint32_t *clut = (uint32_t *)r->pict.data[1];
      uint32_t *dst = (uint32_t *)vo->vo_pixmap->pm_pixels;
      
      for(y = 0; y < r->h; y++) {
	for(x = 0; x < r->w; x++) {
	  *dst++ = clut[src[x]];
	}
	src += r->pict.linesize[0];
      }
      video_overlay_enqueue(vd, vo);
      break;

    case SUBTITLE_ASS:
      sub_ass_render(vd, r->ass,
		     ctx->subtitle_header, ctx->subtitle_header_size);
      break;

    default:
      break;
    }
  }
}
コード例 #2
0
ファイル: video_overlay.c プロジェクト: Bibamaru/showtime
/**
 * Decode subtitles from LAVC
 */
static void
video_subtitles_lavc(media_pipe_t *mp, media_buf_t *mb,
		     AVCodecContext *ctx)
{
  AVSubtitle sub;
  int got_sub = 0, i, x, y;
  video_overlay_t *vo;

  AVPacket avpkt;
  av_init_packet(&avpkt);
  avpkt.data = mb->mb_data;
  avpkt.size = mb->mb_size;

  if(avcodec_decode_subtitle2(ctx, &sub, &got_sub, &avpkt) < 1 || !got_sub) 
    return;

  if(sub.num_rects == 0) {
    // Flush screen
    vo = calloc(1, sizeof(video_overlay_t));
    vo->vo_type = VO_TIMED_FLUSH;
    vo->vo_start = mb->mb_pts + sub.start_display_time * 1000;
    video_overlay_enqueue(mp, vo);
  } else {

    for(i = 0; i < sub.num_rects; i++) {
      AVSubtitleRect *r = sub.rects[i];

      switch(r->type) {

      case SUBTITLE_BITMAP:
	vo = calloc(1, sizeof(video_overlay_t));

	vo->vo_start = mb->mb_pts + sub.start_display_time * 1000;
	vo->vo_stop  = mb->mb_pts + sub.end_display_time * 1000;
        vo->vo_canvas_width  = ctx->width;
        vo->vo_canvas_height = ctx->height;

	vo->vo_x = r->x;
	vo->vo_y = r->y;

	vo->vo_pixmap = pixmap_create(r->w, r->h, PIXMAP_BGR32, 0);

	if(vo->vo_pixmap == NULL) {
	  free(vo);
	  break;
	}

	const uint8_t *src = r->pict.data[0];
	const uint32_t *clut = (uint32_t *)r->pict.data[1];
      
	for(y = 0; y < r->h; y++) {
	  uint32_t *dst = (uint32_t *)(vo->vo_pixmap->pm_pixels + 
				       y * vo->vo_pixmap->pm_linesize);
	  for(x = 0; x < r->w; x++)
	    *dst++ = clut[src[x]];

	  src += r->pict.linesize[0];
	}
	video_overlay_enqueue(mp, vo);
	break;

      case SUBTITLE_ASS:
	sub_ass_render(mp, r->ass,
		       ctx->subtitle_header, ctx->subtitle_header_size,
		       mb->mb_font_context);
	break;

      default:
	break;
      }
    }
  }
  avsubtitle_free(&sub);
}