00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avformat.h"
00022 #include "subtitles.h"
00023 #include "libavutil/avstring.h"
00024
00025 AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q,
00026 const uint8_t *event, int len, int merge)
00027 {
00028 AVPacket *subs, *sub;
00029
00030 if (merge && q->nb_subs > 0) {
00031
00032
00033 int old_len;
00034 sub = &q->subs[q->nb_subs - 1];
00035 old_len = sub->size;
00036 if (av_grow_packet(sub, len) < 0)
00037 return NULL;
00038 memcpy(sub->data + old_len, event, len);
00039 } else {
00040
00041
00042 if (q->nb_subs >= INT_MAX/sizeof(*q->subs) - 1)
00043 return NULL;
00044 subs = av_fast_realloc(q->subs, &q->allocated_size,
00045 (q->nb_subs + 1) * sizeof(*q->subs));
00046 if (!subs)
00047 return NULL;
00048 q->subs = subs;
00049 sub = &subs[q->nb_subs++];
00050 if (av_new_packet(sub, len) < 0)
00051 return NULL;
00052 sub->destruct = NULL;
00053 sub->flags |= AV_PKT_FLAG_KEY;
00054 sub->pts = sub->dts = 0;
00055 memcpy(sub->data, event, len);
00056 }
00057 return sub;
00058 }
00059
00060 static int cmp_pkt_sub(const void *a, const void *b)
00061 {
00062 const AVPacket *s1 = a;
00063 const AVPacket *s2 = b;
00064 if (s1->pts == s2->pts) {
00065 if (s1->pos == s2->pos)
00066 return 0;
00067 return s1->pos > s2->pos ? 1 : -1;
00068 }
00069 return s1->pts > s2->pts ? 1 : -1;
00070 }
00071
00072 void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q)
00073 {
00074 int i;
00075
00076 qsort(q->subs, q->nb_subs, sizeof(*q->subs), cmp_pkt_sub);
00077 for (i = 0; i < q->nb_subs; i++)
00078 if (q->subs[i].duration == -1 && i < q->nb_subs - 1)
00079 q->subs[i].duration = q->subs[i + 1].pts - q->subs[i].pts;
00080 }
00081
00082 int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)
00083 {
00084 AVPacket *sub = q->subs + q->current_sub_idx;
00085
00086 if (q->current_sub_idx == q->nb_subs)
00087 return AVERROR_EOF;
00088 *pkt = *sub;
00089 pkt->dts = pkt->pts;
00090 q->current_sub_idx++;
00091 return 0;
00092 }
00093
00094 void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q)
00095 {
00096 int i;
00097
00098 for (i = 0; i < q->nb_subs; i++)
00099 av_destruct_packet(&q->subs[i]);
00100 av_freep(&q->subs);
00101 q->nb_subs = q->allocated_size = q->current_sub_idx = 0;
00102 }
00103
00104 int ff_smil_extract_next_chunk(AVIOContext *pb, AVBPrint *buf, char *c)
00105 {
00106 int i = 0;
00107 char end_chr;
00108
00109 if (!*c)
00110 *c = avio_r8(pb);
00111 if (!*c)
00112 return 0;
00113
00114 end_chr = *c == '<' ? '>' : '<';
00115 do {
00116 av_bprint_chars(buf, *c, 1);
00117 *c = avio_r8(pb);
00118 i++;
00119 } while (*c != end_chr && *c);
00120 if (end_chr == '>') {
00121 av_bprint_chars(buf, '>', 1);
00122 *c = 0;
00123 }
00124 return i;
00125 }
00126
00127 const char *ff_smil_get_attr_ptr(const char *s, const char *attr)
00128 {
00129 int in_quotes = 0;
00130 const int len = strlen(attr);
00131
00132 while (*s) {
00133 while (*s) {
00134 if (!in_quotes && isspace(*s))
00135 break;
00136 in_quotes ^= *s == '"';
00137 s++;
00138 }
00139 while (isspace(*s))
00140 s++;
00141 if (!av_strncasecmp(s, attr, len) && s[len] == '=')
00142 return s + len + 1 + (s[len + 1] == '"');
00143 }
00144 return NULL;
00145 }