[FFmpeg-devel] [PATCH 3/3] allow passing subtitles header between decoder and encoder

Aurélien Jacobs aurel
Sun Aug 8 02:26:58 CEST 2010


From: Aurelien Jacobs <aurel at gnuage.org>

---
 ffmpeg.c             |   11 +++++++++++
 libavcodec/assdec.c  |   11 +++++++++++
 libavcodec/assenc.c  |   11 +++++++++++
 libavcodec/avcodec.h |    8 ++++++++
 libavcodec/utils.c   |    2 ++
 5 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index ca85b34..4b37e94 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2354,6 +2354,7 @@ static int transcode(AVFormatContext **output_files,
         ost = ost_table[i];
         if (ost->encoding_needed) {
             AVCodec *codec = output_codecs[i];
+            AVCodecContext *dec = ist_table[ost->source_index]->st->codec;
             if (!codec)
                 codec = avcodec_find_encoder(ost->st->codec->codec_id);
             if (!codec) {
@@ -2362,6 +2363,15 @@ static int transcode(AVFormatContext **output_files,
                 ret = AVERROR(EINVAL);
                 goto dump_format;
             }
+            if (dec->subtitle_header) {
+                ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);
+                if (!ost->st->codec->subtitle_header) {
+                    ret = AVERROR(ENOMEM);
+                    goto dump_format;
+                }
+                memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
+                ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
+            }
             if (avcodec_open(ost->st->codec, codec) < 0) {
                 snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",
                         ost->file_index, ost->index);
@@ -2692,6 +2702,7 @@ static int transcode(AVFormatContext **output_files,
                 }
                 av_fifo_free(ost->fifo); /* works even if fifo is not
                                              initialized but set to zero */
+                av_freep(&ost->st->codec->subtitle_header);
                 av_free(ost->pict_tmp.data[0]);
                 if (ost->video_resample)
                     sws_freeContext(ost->img_resample_ctx);
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index 98878a1..60b450b 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -22,6 +22,16 @@
 #include "avcodec.h"
 
 
+static av_cold int ass_decode_init(AVCodecContext *avctx)
+{
+    avctx->subtitle_header = av_malloc(avctx->extradata_size);
+    if (!avctx->extradata)
+        return AVERROR(ENOMEM);
+    memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size);
+    avctx->subtitle_header_size = avctx->extradata_size;
+    return 0;
+}
+
 static int ass_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                             AVPacket *avpkt)
 {
@@ -43,5 +53,6 @@ AVCodec ass_decoder = {
     .long_name = NULL_IF_CONFIG_SMALL("Advanced SubStation Alpha subtitle"),
     .type      = AVMEDIA_TYPE_SUBTITLE,
     .id        = CODEC_ID_SSA,
+    .init      = ass_decode_init,
     .decode    = ass_decode_frame,
 };
diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index d0ba462..6f64f6d 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -23,6 +23,16 @@
 #include "libavutil/avstring.h"
 
 
+static av_cold int ass_encode_init(AVCodecContext *avctx)
+{
+    avctx->extradata = av_malloc(avctx->subtitle_header_size);
+    if (!avctx->extradata)
+        return AVERROR(ENOMEM);
+    memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size);
+    avctx->extradata_size = avctx->subtitle_header_size;
+    return 0;
+}
+
 static int ass_encode_frame(AVCodecContext *avctx,
                             unsigned char *buf, int bufsize, void *data)
 {
@@ -57,5 +67,6 @@ AVCodec ass_encoder = {
     .long_name = NULL_IF_CONFIG_SMALL("Advanced SubStation Alpha subtitle"),
     .type      = AVMEDIA_TYPE_SUBTITLE,
     .id        = CODEC_ID_SSA,
+    .init      = ass_encode_init,
     .encode    = ass_encode_frame,
 };
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 9186bf5..14d8c16 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2707,6 +2707,14 @@ typedef struct AVCodecContext {
      * - decoding: unused
      */
     int lpc_passes;
+
+    /**
+     * Header containing style information for text subtitles.
+     * - encoding: Set/allocated/freed by user (before avcodec_open())
+     * - decoding: Set/allocated/freed by libavcodec (by avcodec_open())
+     */
+    uint8_t *subtitle_header;
+    int subtitle_header_size;
 } AVCodecContext;
 
 /**
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index f13b271..258a276 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -732,6 +732,8 @@ av_cold int avcodec_close(AVCodecContext *avctx)
     av_freep(&avctx->priv_data);
     if(avctx->codec && avctx->codec->encode)
         av_freep(&avctx->extradata);
+    if (avctx->codec && avctx->codec->decode)
+        av_freep(&avctx->subtitle_header);
     avctx->codec = NULL;
     entangled_thread_counter--;
 
-- 
1.7.1




More information about the ffmpeg-devel mailing list