int64_t usf_reader_c::try_to_parse_timecode(const char *s) { int64_t timecode; if (!parse_timecode(s, timecode)) throw mtx::xml::conversion_x{Y("Invalid start or stop timecode")}; return timecode; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVSubtitle *sub = data; const uint8_t *buf_end = buf + buf_size; uint8_t *bitmap; int w, h, x, y, i; int64_t packet_time = 0; GetBitContext gb; int has_alpha = avctx->codec_tag == MKTAG('D','X','S','A'); // check that at least header fits if (buf_size < 27 + 7 * 2 + 4 * 3) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); return -1; } // read start and end time if (buf[0] != '[' || buf[13] != '-' || buf[26] != ']') { av_log(avctx, AV_LOG_ERROR, "invalid time code\n"); return -1; } if (avpkt->pts != AV_NOPTS_VALUE) packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000}); sub->start_display_time = parse_timecode(buf + 1, packet_time); sub->end_display_time = parse_timecode(buf + 14, packet_time); buf += 27; // read header w = bytestream_get_le16(&buf); h = bytestream_get_le16(&buf); if (av_image_check_size(w, h, 0, avctx) < 0) return -1; x = bytestream_get_le16(&buf); y = bytestream_get_le16(&buf); // skip bottom right position, it gives no new information bytestream_get_le16(&buf); bytestream_get_le16(&buf); // The following value is supposed to indicate the start offset // (relative to the palette) of the data for the second field, // however there are files where it has a bogus value and thus // we just ignore it bytestream_get_le16(&buf); // allocate sub and set values sub->rects = av_mallocz(sizeof(*sub->rects)); sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); sub->num_rects = 1; sub->rects[0]->x = x; sub->rects[0]->y = y; sub->rects[0]->w = w; sub->rects[0]->h = h; sub->rects[0]->type = SUBTITLE_BITMAP; sub->rects[0]->pict.linesize[0] = w; sub->rects[0]->pict.data[0] = av_malloc(w * h); sub->rects[0]->nb_colors = 4; sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); // read palette for (i = 0; i < sub->rects[0]->nb_colors; i++) ((uint32_t*)sub->rects[0]->pict.data[1])[i] = bytestream_get_be24(&buf); // make all except background (first entry) non-transparent for (i = 0; i < sub->rects[0]->nb_colors; i++) ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= (has_alpha ? *buf++ : (i ? 0xff : 0)) << 24; // process RLE-compressed data init_get_bits(&gb, buf, (buf_end - buf) * 8); bitmap = sub->rects[0]->pict.data[0]; for (y = 0; y < h; y++) { // interlaced: do odd lines if (y == (h + 1) / 2) bitmap = sub->rects[0]->pict.data[0] + w; for (x = 0; x < w; ) { int log2 = ff_log2_tab[show_bits(&gb, 8)]; int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); int color = get_bits(&gb, 2); run = FFMIN(run, w - x); // run length 0 means till end of row if (!run) run = w - x; memset(bitmap, color, run); bitmap += run; x += run; } // interlaced, skip every second line bitmap += w; align_get_bits(&gb); } *data_size = 1; return buf_size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { AVSubtitle *sub = data; const uint8_t *buf_end = buf + buf_size; uint8_t *bitmap; int w, h, x, y, rlelen, i; GetBitContext gb; // check that at least header fits if (buf_size < 27 + 7 * 2 + 4 * 3) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); return -1; } // read start and end time if (buf[0] != '[' || buf[13] != '-' || buf[26] != ']') { av_log(avctx, AV_LOG_ERROR, "invalid time code\n"); return -1; } sub->start_display_time = parse_timecode(buf + 1); sub->end_display_time = parse_timecode(buf + 14); buf += 27; // read header w = bytestream_get_le16(&buf); h = bytestream_get_le16(&buf); if (avcodec_check_dimensions(avctx, w, h) < 0) return -1; x = bytestream_get_le16(&buf); y = bytestream_get_le16(&buf); // skip bottom right position, it gives no new information bytestream_get_le16(&buf); bytestream_get_le16(&buf); rlelen = bytestream_get_le16(&buf); // allocate sub and set values if (!sub->rects) { sub->rects = av_mallocz(sizeof(AVSubtitleRect)); sub->num_rects = 1; } av_freep(&sub->rects[0].bitmap); sub->rects[0].x = x; sub->rects[0].y = y; sub->rects[0].w = w; sub->rects[0].h = h; sub->rects[0].linesize = w; sub->rects[0].bitmap = av_malloc(w * h); sub->rects[0].nb_colors = 4; sub->rects[0].rgba_palette = av_malloc(sub->rects[0].nb_colors * 4); // read palette for (i = 0; i < sub->rects[0].nb_colors; i++) sub->rects[0].rgba_palette[i] = bytestream_get_be24(&buf); // make all except background (first entry) non-transparent for (i = 1; i < sub->rects[0].nb_colors; i++) sub->rects[0].rgba_palette[i] |= 0xff000000; // process RLE-compressed data rlelen = FFMIN(rlelen, buf_end - buf); init_get_bits(&gb, buf, rlelen * 8); bitmap = sub->rects[0].bitmap; for (y = 0; y < h; y++) { // interlaced: do odd lines if (y == (h + 1) / 2) bitmap = sub->rects[0].bitmap + w; for (x = 0; x < w; ) { int log2 = ff_log2_tab[show_bits(&gb, 8)]; int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); int color = get_bits(&gb, 2); run = FFMIN(run, w - x); // run length 0 means till end of row if (!run) run = w - x; memset(bitmap, color, run); bitmap += run; x += run; } // interlaced, skip every second line bitmap += w; align_get_bits(&gb); } *data_size = 1; return buf_size; }
/* * do ioctls and * send stuff down - dont care about * flow control */ static int parsewput( queue_t *q, register mblk_t *mp ) { register int ok = 1; register mblk_t *datap; register struct iocblk *iocp; parsestream_t *parse = (parsestream_t *)(void *)q->q_ptr; parseprintf(DD_WPUT,("parse: parsewput\n")); switch (mp->b_datap->db_type) { default: putnext(q, mp); break; case M_IOCTL: iocp = (struct iocblk *)(void *)mp->b_rptr; switch (iocp->ioc_cmd) { default: parseprintf(DD_WPUT,("parse: parsewput - forward M_IOCTL\n")); putnext(q, mp); break; case CIOGETEV: /* * taken from Craig Leres ppsclock module (and modified) */ datap = allocb(sizeof(struct ppsclockev), BPRI_MED); if (datap == NULL || mp->b_cont) { mp->b_datap->db_type = M_IOCNAK; iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL; if (datap != NULL) freeb(datap); qreply(q, mp); break; } mp->b_cont = datap; *(struct ppsclockev *)(void *)datap->b_wptr = parse->parse_ppsclockev; datap->b_wptr += sizeof(struct ppsclockev) / sizeof(*datap->b_wptr); mp->b_datap->db_type = M_IOCACK; iocp->ioc_count = sizeof(struct ppsclockev); qreply(q, mp); break; case PARSEIOC_ENABLE: case PARSEIOC_DISABLE: { parse->parse_status = (parse->parse_status & (unsigned)~PARSE_ENABLE) | (iocp->ioc_cmd == PARSEIOC_ENABLE) ? PARSE_ENABLE : 0; if (!setup_stream(RD(q), (parse->parse_status & PARSE_ENABLE) ? M_PARSE : M_NOPARSE)) { mp->b_datap->db_type = M_IOCNAK; } else { mp->b_datap->db_type = M_IOCACK; } qreply(q, mp); break; } case PARSEIOC_TIMECODE: case PARSEIOC_SETFMT: case PARSEIOC_GETFMT: case PARSEIOC_SETCS: if (iocp->ioc_count == sizeof(parsectl_t)) { parsectl_t *dct = (parsectl_t *)(void *)mp->b_cont->b_rptr; switch (iocp->ioc_cmd) { case PARSEIOC_TIMECODE: parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_TIMECODE\n")); ok = parse_timecode(dct, &parse->parse_io); break; case PARSEIOC_SETFMT: parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETFMT\n")); ok = parse_setfmt(dct, &parse->parse_io); break; case PARSEIOC_GETFMT: parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_GETFMT\n")); ok = parse_getfmt(dct, &parse->parse_io); break; case PARSEIOC_SETCS: parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETCS\n")); ok = parse_setcs(dct, &parse->parse_io); break; } mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK; } else { mp->b_datap->db_type = M_IOCNAK; } parseprintf(DD_WPUT,("parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK")); qreply(q, mp); break; } } return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVSubtitle *sub = data; const uint8_t *buf_end = buf + buf_size; uint8_t *bitmap; int w, h, x, y, rlelen, i; int64_t packet_time = 0; GetBitContext gb; memset(sub, 0, sizeof(*sub)); // check that at least header fits if (buf_size < 27 + 7 * 2 + 4 * 3) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); return -1; } // read start and end time if (buf[0] != '[' || buf[13] != '-' || buf[26] != ']') { av_log(avctx, AV_LOG_ERROR, "invalid time code\n"); return -1; } if (avpkt->pts != AV_NOPTS_VALUE) packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000}); sub->start_display_time = parse_timecode(buf + 1, packet_time); sub->end_display_time = parse_timecode(buf + 14, packet_time); buf += 27; // read header w = bytestream_get_le16(&buf); h = bytestream_get_le16(&buf); if (avcodec_check_dimensions(avctx, w, h) < 0) return -1; x = bytestream_get_le16(&buf); y = bytestream_get_le16(&buf); #ifdef SUPPORT_DIVX_DRM if((video_height - (y+h)) > 30) { y = video_height-30-h-1; } #endif /* end of SUPPORT_DIVX_DRM */ // skip bottom right position, it gives no new information bytestream_get_le16(&buf); bytestream_get_le16(&buf); rlelen = bytestream_get_le16(&buf); // allocate sub and set values sub->rects = av_mallocz(sizeof(*sub->rects)); sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); sub->num_rects = 1; sub->rects[0]->x = x; sub->rects[0]->y = y; sub->rects[0]->w = w; sub->rects[0]->h = h; sub->rects[0]->type = SUBTITLE_BITMAP; sub->rects[0]->pict.linesize[0] = w; sub->rects[0]->pict.data[0] = av_malloc(w * h); sub->rects[0]->nb_colors = 4; sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); // read palette for (i = 0; i < sub->rects[0]->nb_colors; i++) ((uint32_t*)sub->rects[0]->pict.data[1])[i] = bytestream_get_be24(&buf); // make all except background (first entry) non-transparent #if 1 if(sub_type == 2) //DXSA { for (i = 0; i < sub->rects[0]->nb_colors; i++) { if(buf[i]) ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= 0xff000000; } if(buf[0] == buf[1] && buf[0] == buf[2] && buf[0] == buf[3] && buf[1] == buf[2] && buf[1] == buf[3] && buf[2] == buf[3] && buf[0] < 0xff) { transport_float = (float)buf[0] / 256.0; } buf += 4; } else { for (i = 1; i < sub->rects[0]->nb_colors; i++) ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= 0xff000000; } #else for (i = 1; i < sub->rects[0]->nb_colors; i++) ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= 0xff000000; #endif // process RLE-compressed data rlelen = FFMIN(rlelen, buf_end - buf); init_get_bits(&gb, buf, rlelen * 8); bitmap = sub->rects[0]->pict.data[0]; for (y = 0; y < h; y++) { // interlaced: do odd lines if (y == (h + 1) / 2) bitmap = sub->rects[0]->pict.data[0] + w; for (x = 0; x < w; ) { int log2 = ff_log2_tab[show_bits(&gb, 8)]; int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); int color = get_bits(&gb, 2); run = FFMIN(run, w - x); // run length 0 means till end of row if (!run) run = w - x; memset(bitmap, color, run); bitmap += run; x += run; } // interlaced, skip every second line bitmap += w; align_get_bits(&gb); } *data_size = 1; return buf_size; }