[xiph-commits] r17186 - trunk/ffmpeg2theora/src
oggk at svn.xiph.org
oggk at svn.xiph.org
Fri Apr 30 03:42:47 PDT 2010
Author: oggk
Date: 2010-04-30 03:42:47 -0700 (Fri, 30 Apr 2010)
New Revision: 17186
Modified:
trunk/ffmpeg2theora/src/ffmpeg2theora.c
Log:
call avcodec_decode_subtitle2, for those formats that it implements, and
some general cleanup, which should make it easier to decode more formats.
OKd by j
Modified: trunk/ffmpeg2theora/src/ffmpeg2theora.c
===================================================================
--- trunk/ffmpeg2theora/src/ffmpeg2theora.c 2010-04-29 08:04:22 UTC (rev 17185)
+++ trunk/ffmpeg2theora/src/ffmpeg2theora.c 2010-04-30 10:42:47 UTC (rev 17186)
@@ -458,6 +458,30 @@
return end-start;
}
+static void extra_info_from_ssa(AVPacket *pkt, const char **utf8, size_t *utf8len, char **allocated_utf8, float *duration)
+{
+ char *dupe;
+
+ *allocated_utf8 = NULL;
+ dupe = malloc(pkt->size+1); // not zero terminated, so make it so
+ if (dupe) {
+ memcpy(dupe, pkt->data, pkt->size);
+ dupe[pkt->size] = 0;
+ *duration = get_duration_from_ssa(dupe);
+ *allocated_utf8 = get_raw_text_from_ssa(dupe);
+ if (*allocated_utf8) {
+ if (*allocated_utf8 == dupe) {
+ *allocated_utf8 = NULL;
+ }
+ else {
+ *utf8 = *allocated_utf8;
+ *utf8len = strlen(*utf8);
+ }
+ }
+ free(dupe);
+ }
+}
+
static const char *find_language_for_subtitle_stream(const AVStream *s)
{
const char *lang=find_iso639_1(s->language);
@@ -1516,70 +1540,83 @@
AVStream *stream=this->context->streams[pkt.stream_index];
AVCodecContext *enc = stream->codec;
if (enc) {
- if (enc->codec_id == CODEC_ID_TEXT || enc->codec_id == CODEC_ID_SSA || enc->codec_id==CODEC_ID_MOV_TEXT) {
- char *allocated_utf8 = NULL;
- const char *utf8 = pkt.data;
- size_t utf8len = pkt.size;
- float t = pkt.pts * av_q2d(stream->time_base) - this->start_time;
- // my test case has 0 duration, how clever of that. I assume it's that old 'ends whenever the next
- // one starts' hack, but it means I don't know in advance what duration it has. Great!
- float duration;
- if (pkt.duration <= 0)
- duration = 2.0f;
- else
- duration = pkt.duration * av_q2d(stream->time_base);
+ char *allocated_utf8 = NULL;
+ const char *utf8 = NULL;
+ size_t utf8len = 0;
+ float t;
+ AVSubtitle sub;
+ int got_sub=0;
- // SSA has control stuff in there, extract raw text
- if (enc->codec_id == CODEC_ID_SSA) {
- char *dupe = malloc(utf8len+1); // not zero terminated, so make it so
- if (dupe) {
- memcpy(dupe, utf8, utf8len);
- dupe[utf8len] = 0;
- duration = get_duration_from_ssa(dupe);
- allocated_utf8 = get_raw_text_from_ssa(dupe);
- if (allocated_utf8) {
- if (allocated_utf8 == dupe) {
- allocated_utf8 = NULL;
- }
- else {
- utf8 = allocated_utf8;
- utf8len = strlen(utf8);
- }
- }
- free(dupe);
+ /* work out timing */
+ t = (float)pkt.pts * stream->time_base.num / stream->time_base.den - this->start_time;
+ // my test case has 0 duration, how clever of that. I assume it's that old 'ends whenever the next
+ // one starts' hack, but it means I don't know in advance what duration it has. Great!
+ float duration;
+ if (pkt.duration <= 0) {
+ duration = 2.0f;
+ }
+ else {
+ duration = (float)pkt.duration * stream->time_base.num / stream->time_base.den;
+ }
+
+ /* generic decoding */
+ if (enc->codec && avcodec_decode_subtitle2(enc,&sub,&got_sub,&pkt) >= 0) {
+ if (got_sub) {
+ if (sub.rects[0]->ass) {
+ extra_info_from_ssa(&pkt,&utf8,&utf8len,&allocated_utf8,&duration);
}
- else {
- utf8 = NULL;
- utf8len = 0;
+ else if (sub.rects[0]->text) {
+ utf8 = sub.rects[0]->text;
+ utf8len = strlen(utf8);
}
}
- else if (enc->codec_id == CODEC_ID_MOV_TEXT) {
- if (utf8len >= 2) {
- const unsigned char *data = (const unsigned char*)pkt.data;
- unsigned int text_len = (data[0] << 8) | data[1];
- utf8 += 2;
- utf8len -= 2;
- if (text_len < utf8len) {
- utf8len = text_len;
- }
- if (utf8len == 0) utf8 = NULL;
+ }
+ else if (enc->codec_id == CODEC_ID_TEXT) {
+ utf8 = pkt.data;
+ utf8len = pkt.size;
+ }
+ else if (enc->codec_id == CODEC_ID_SSA) {
+ // SSA has control stuff in there, extract raw text
+ extra_info_from_ssa(&pkt,&utf8,&utf8len,&allocated_utf8,&duration);
+ }
+ else if (enc->codec_id == CODEC_ID_MOV_TEXT) {
+ utf8 = pkt.data;
+ utf8len = pkt.size;
+ if (utf8len >= 2) {
+ const unsigned char *data = (const unsigned char*)pkt.data;
+ unsigned int text_len = (data[0] << 8) | data[1];
+ utf8 += 2;
+ utf8len -= 2;
+ if (text_len < utf8len) {
+ utf8len = text_len;
}
- else {
- utf8 = NULL;
- utf8len = 0;
- }
+ if (utf8len == 0) utf8 = NULL;
}
- if (t < 0 && t + duration > 0) {
- duration += t;
- t = 0;
+ else {
+ utf8 = NULL;
+ utf8len = 0;
}
- if (utf8 && t >= 0)
- add_subtitle_for_stream(this->kate_streams, this->n_kate_streams, pkt.stream_index, t, duration, utf8, utf8len, info.frontend);
- if (allocated_utf8) free(allocated_utf8);
}
else {
/* TODO: other types */
}
+
+ /* clip timings after any possible SSA extraction */
+ if (t < 0 && t + duration > 0) {
+ duration += t;
+ t = 0;
+ }
+
+ /* we have text and timing now, adjust for start time, encode, and cleanup */
+ if (utf8 && t >= 0)
+ add_subtitle_for_stream(this->kate_streams, this->n_kate_streams, pkt.stream_index, t, duration, utf8, utf8len, info.frontend);
+
+ if (allocated_utf8) free(allocated_utf8);
+ if (got_sub) {
+#if 0
+ avcodec_free_subtitle(enc,&sub);
+#endif
+ }
}
}
More information about the commits
mailing list