00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "avcodec.h"
00023 #include "ass.h"
00024 #include "libavutil/avstring.h"
00025 #include "libavutil/common.h"
00026 #include "libavutil/bprint.h"
00027 #include "libavutil/intreadwrite.h"
00028
00029 static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end)
00030 {
00031 while (text < text_end) {
00032 switch (*text) {
00033 case '\r':
00034 break;
00035 case '\n':
00036 av_bprintf(buf, "\\N");
00037 break;
00038 default:
00039 av_bprint_chars(buf, *text, 1);
00040 break;
00041 }
00042 text++;
00043 }
00044
00045 av_bprintf(buf, "\r\n");
00046 return 0;
00047 }
00048
00049 static int mov_text_init(AVCodecContext *avctx) {
00050
00051
00052
00053
00054
00055
00056 return ff_ass_subtitle_header_default(avctx);
00057 }
00058
00059 static int mov_text_decode_frame(AVCodecContext *avctx,
00060 void *data, int *got_sub_ptr, AVPacket *avpkt)
00061 {
00062 AVSubtitle *sub = data;
00063 int ts_start, ts_end;
00064 AVBPrint buf;
00065 const char *ptr = avpkt->data;
00066 const char *end;
00067
00068 if (!ptr || avpkt->size < 2)
00069 return AVERROR_INVALIDDATA;
00070
00071
00072
00073
00074
00075
00076
00077
00078 if (avpkt->size == 2)
00079 return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;
00080
00081
00082
00083
00084
00085
00086 end = ptr + FFMAX(2 + AV_RB16(ptr), avpkt->size);
00087 ptr += 2;
00088
00089 ts_start = av_rescale_q(avpkt->pts,
00090 avctx->time_base,
00091 (AVRational){1,100});
00092 ts_end = av_rescale_q(avpkt->pts + avpkt->duration,
00093 avctx->time_base,
00094 (AVRational){1,100});
00095
00096
00097 av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
00098 text_to_ass(&buf, ptr, end);
00099
00100 if (!av_bprint_is_complete(&buf))
00101 return AVERROR(ENOMEM);
00102
00103 ff_ass_add_rect(sub, buf.str, ts_start, ts_end-ts_start, 0);
00104 *got_sub_ptr = sub->num_rects > 0;
00105 av_bprint_finalize(&buf, NULL);
00106 return avpkt->size;
00107 }
00108
00109 AVCodec ff_movtext_decoder = {
00110 .name = "mov_text",
00111 .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
00112 .type = AVMEDIA_TYPE_SUBTITLE,
00113 .id = AV_CODEC_ID_MOV_TEXT,
00114 .init = mov_text_init,
00115 .decode = mov_text_decode_frame,
00116 };