annotate ffmpeg/libavformat/srtenc.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * SubRip subtitle muxer
yading@11 3 * Copyright (c) 2012 Nicolas George <nicolas.george@normalesup.org>
yading@11 4 *
yading@11 5 * This file is part of FFmpeg.
yading@11 6 *
yading@11 7 * FFmpeg is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * FFmpeg is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with FFmpeg; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 #include "avformat.h"
yading@11 23 #include "internal.h"
yading@11 24 #include "libavutil/log.h"
yading@11 25 #include "libavutil/intreadwrite.h"
yading@11 26
yading@11 27 /* TODO: add options for:
yading@11 28 - character encoding;
yading@11 29 - LF / CRLF;
yading@11 30 - byte order mark.
yading@11 31 */
yading@11 32
yading@11 33 typedef struct SRTContext{
yading@11 34 unsigned index;
yading@11 35 } SRTContext;
yading@11 36
yading@11 37 static int srt_write_header(AVFormatContext *avf)
yading@11 38 {
yading@11 39 SRTContext *srt = avf->priv_data;
yading@11 40
yading@11 41 if (avf->nb_streams != 1 ||
yading@11 42 avf->streams[0]->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
yading@11 43 av_log(avf, AV_LOG_ERROR,
yading@11 44 "SRT supports only a single subtitles stream.\n");
yading@11 45 return AVERROR(EINVAL);
yading@11 46 }
yading@11 47 if (avf->streams[0]->codec->codec_id != AV_CODEC_ID_TEXT &&
yading@11 48 avf->streams[0]->codec->codec_id != AV_CODEC_ID_SUBRIP &&
yading@11 49 avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT) {
yading@11 50 av_log(avf, AV_LOG_ERROR,
yading@11 51 "Unsupported subtitles codec: %s\n",
yading@11 52 avcodec_get_name(avf->streams[0]->codec->codec_id));
yading@11 53 return AVERROR(EINVAL);
yading@11 54 }
yading@11 55 avpriv_set_pts_info(avf->streams[0], 64, 1, 1000);
yading@11 56 srt->index = 1;
yading@11 57 return 0;
yading@11 58 }
yading@11 59
yading@11 60 static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt)
yading@11 61 {
yading@11 62 SRTContext *srt = avf->priv_data;
yading@11 63 int write_ts = avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT;
yading@11 64
yading@11 65 if (write_ts) {
yading@11 66 int64_t s = pkt->pts, e, d = pkt->duration;
yading@11 67 int size, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
yading@11 68 const uint8_t *p;
yading@11 69
yading@11 70 p = av_packet_get_side_data(pkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);
yading@11 71 if (p && size == 16) {
yading@11 72 x1 = AV_RL32(p );
yading@11 73 y1 = AV_RL32(p + 4);
yading@11 74 x2 = AV_RL32(p + 8);
yading@11 75 y2 = AV_RL32(p + 12);
yading@11 76 }
yading@11 77
yading@11 78 if (d <= 0)
yading@11 79 /* For backward compatibility, fallback to convergence_duration. */
yading@11 80 d = pkt->convergence_duration;
yading@11 81 if (s == AV_NOPTS_VALUE || d < 0) {
yading@11 82 av_log(avf, AV_LOG_WARNING,
yading@11 83 "Insufficient timestamps in event number %d.\n", srt->index);
yading@11 84 return 0;
yading@11 85 }
yading@11 86 e = s + d;
yading@11 87 avio_printf(avf->pb, "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d",
yading@11 88 srt->index,
yading@11 89 (int)(s / 3600000), (int)(s / 60000) % 60,
yading@11 90 (int)(s / 1000) % 60, (int)(s % 1000),
yading@11 91 (int)(e / 3600000), (int)(e / 60000) % 60,
yading@11 92 (int)(e / 1000) % 60, (int)(e % 1000));
yading@11 93 if (p)
yading@11 94 avio_printf(avf->pb, " X1:%03d X2:%03d Y1:%03d Y2:%03d",
yading@11 95 x1, x2, y1, y2);
yading@11 96 avio_printf(avf->pb, "\n");
yading@11 97 }
yading@11 98 avio_write(avf->pb, pkt->data, pkt->size);
yading@11 99 if (write_ts)
yading@11 100 avio_write(avf->pb, "\n\n", 2);
yading@11 101 srt->index++;
yading@11 102 return 0;
yading@11 103 }
yading@11 104
yading@11 105 AVOutputFormat ff_srt_muxer = {
yading@11 106 .name = "srt",
yading@11 107 .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
yading@11 108 .mime_type = "application/x-subrip",
yading@11 109 .extensions = "srt",
yading@11 110 .priv_data_size = sizeof(SRTContext),
yading@11 111 .write_header = srt_write_header,
yading@11 112 .write_packet = srt_write_packet,
yading@11 113 .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
yading@11 114 .subtitle_codec = AV_CODEC_ID_SUBRIP,
yading@11 115 };