static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt) { const char *ptr = avpkt->data; int len, size = avpkt->size; while (size > 0) { ASSDialog *dialog = ff_ass_split_dialog(avctx->priv_data, ptr, 0, NULL); int duration = dialog->end - dialog->start; len = ff_ass_add_rect(data, ptr, 0, duration, 1); if (len < 0) return len; ptr += len; size -= len; } *got_sub_ptr = avpkt->size > 0; return avpkt->size; }
static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf, int bufsize, const AVSubtitle *sub) { MovTextContext *s = avctx->priv_data; ASSDialog *dialog; int i, len, num; s->ptr = s->buffer; s->end = s->ptr + sizeof(s->buffer); for (i = 0; i < sub->num_rects; i++) { if (sub->rects[i]->type != SUBTITLE_ASS) { av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); return AVERROR(ENOSYS); } dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num); for (; dialog && num--; dialog++) { ff_ass_split_override_codes(&mov_text_callbacks, s, dialog->text); } } if (s->ptr == s->buffer) return 0; AV_WB16(buf, strlen(s->buffer)); buf += 2; len = av_strlcpy(buf, s->buffer, bufsize - 2); if (len > bufsize-3) { av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n"); return AVERROR(EINVAL); } return len + 2; }
static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf, int bufsize, const AVSubtitle *sub) { MovTextContext *s = avctx->priv_data; ASSDialog *dialog; int i, j, num, length; s->text_pos = 0; s->count = 0; s->style_box_flag = 0; s->style_entries = 0; for (i = 0; i < sub->num_rects; i++) { if (sub->rects[i]->type != SUBTITLE_ASS) { av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); return AVERROR(ENOSYS); } dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num); for (; dialog && num--; dialog++) { ff_ass_split_override_codes(&mov_text_callbacks, s, dialog->text); } if (s->style_box_flag) { s->tsmb_size = s->count * STYLE_RECORD_SIZE + SIZE_ADD; //size of one style record is 12 bytes s->tsmb_size = AV_RB32(&s->tsmb_size); s->tsmb_type = MKTAG('s','t','y','l'); s->style_entries = AV_RB16(&s->count); s->style_fontID = 0x00 | 0x01<<8; s->style_fontsize = 0x12; s->style_color = MKTAG(0xFF, 0xFF, 0xFF, 0xFF); /*The above three attributes are hard coded for now but will come from ASS style in the future*/ av_bprint_append_any(&s->buffer, &s->tsmb_size, 4); av_bprint_append_any(&s->buffer, &s->tsmb_type, 4); av_bprint_append_any(&s->buffer, &s->style_entries, 2); for (j = 0; j < s->count; j++) { av_bprint_append_any(&s->buffer, &s->style_attributes[j]->style_start, 2); av_bprint_append_any(&s->buffer, &s->style_attributes[j]->style_end, 2); av_bprint_append_any(&s->buffer, &s->style_fontID, 2); av_bprint_append_any(&s->buffer, &s->style_attributes[j]->style_flag, 1); av_bprint_append_any(&s->buffer, &s->style_fontsize, 1); av_bprint_append_any(&s->buffer, &s->style_color, 4); } for (j = 0; j < s->count; j++) { av_freep(&s->style_attributes[j]); } av_freep(&s->style_attributes); av_freep(&s->style_attributes_temp); } } AV_WB16(buf, s->text_pos); buf += 2; if (!av_bprint_is_complete(&s->buffer)) { length = AVERROR(ENOMEM); goto exit; } if (!s->buffer.len) { length = 0; goto exit; } if (s->buffer.len > bufsize - 3) { av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n"); length = AVERROR(EINVAL); goto exit; } memcpy(buf, s->buffer.str, s->buffer.len); length = s->buffer.len + 2; exit: av_bprint_clear(&s->buffer); return length; }