Commit 36e61e24 authored by Clément Bœsch's avatar Clément Bœsch

lavc: add ff_bprint_to_extradata() helper and use it.

This commit also makes sure the extradata and subtitle_header are NUL
terminated, without taking into account the trailing '\0' in account in
the size.

At the same time, it should fix 'warning: dereferencing type-punned
pointer will break strict-aliasing rules' warning for compilers who
don't consider uint8_t** and char** compatibles.
parent e911f4ae
...@@ -29,10 +29,11 @@ ...@@ -29,10 +29,11 @@
static av_cold int ass_decode_init(AVCodecContext *avctx) static av_cold int ass_decode_init(AVCodecContext *avctx)
{ {
avctx->subtitle_header = av_malloc(avctx->extradata_size); avctx->subtitle_header = av_malloc(avctx->extradata_size + 1);
if (!avctx->subtitle_header) if (!avctx->subtitle_header)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size); memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size);
avctx->subtitle_header[avctx->extradata_size] = 0;
avctx->subtitle_header_size = avctx->extradata_size; avctx->subtitle_header_size = avctx->extradata_size;
avctx->priv_data = ff_ass_split(avctx->extradata); avctx->priv_data = ff_ass_split(avctx->extradata);
if(!avctx->priv_data) if(!avctx->priv_data)
......
...@@ -28,11 +28,12 @@ ...@@ -28,11 +28,12 @@
static av_cold int ass_encode_init(AVCodecContext *avctx) static av_cold int ass_encode_init(AVCodecContext *avctx)
{ {
avctx->extradata = av_malloc(avctx->subtitle_header_size); avctx->extradata = av_malloc(avctx->subtitle_header_size + 1);
if (!avctx->extradata) if (!avctx->extradata)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size); memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size);
avctx->extradata_size = avctx->subtitle_header_size; avctx->extradata_size = avctx->subtitle_header_size;
avctx->extradata[avctx->extradata_size] = 0;
return 0; return 0;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
*/ */
#include "avcodec.h" #include "avcodec.h"
#include "bytestream.h" #include "bytestream.h"
#include "internal.h"
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/imgutils.h" #include "libavutil/imgutils.h"
...@@ -408,9 +409,9 @@ static int dvdsub_init(AVCodecContext *avctx) ...@@ -408,9 +409,9 @@ static int dvdsub_init(AVCodecContext *avctx)
av_bprintf(&extradata, " %06"PRIx32"%c", av_bprintf(&extradata, " %06"PRIx32"%c",
dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n'); dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n');
if ((ret = av_bprint_finalize(&extradata, (char **)&avctx->extradata)) < 0) ret = ff_bprint_to_extradata(avctx, &extradata);
if (ret < 0)
return ret; return ret;
avctx->extradata_size = extradata.len;
return 0; return 0;
} }
......
...@@ -201,4 +201,9 @@ int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDict ...@@ -201,4 +201,9 @@ int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDict
*/ */
int ff_codec_close_recursive(AVCodecContext *avctx); int ff_codec_close_recursive(AVCodecContext *avctx);
/**
* Finalize buf into extradata and set its size appropriately.
*/
int ff_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf);
#endif /* AVCODEC_INTERNAL_H */ #endif /* AVCODEC_INTERNAL_H */
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h"
#include "libavutil/channel_layout.h" #include "libavutil/channel_layout.h"
#include "libavutil/crc.h" #include "libavutil/crc.h"
#include "libavutil/mathematics.h" #include "libavutil/mathematics.h"
...@@ -2684,3 +2685,21 @@ int avcodec_is_open(AVCodecContext *s) ...@@ -2684,3 +2685,21 @@ int avcodec_is_open(AVCodecContext *s)
{ {
return !!s->internal; return !!s->internal;
} }
int ff_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf)
{
int ret;
char *str;
ret = av_bprint_finalize(buf, &str);
if (ret < 0)
return ret;
avctx->extradata = str;
/* Note: the string is NUL terminated (so extradata can be read as a
* string), but the ending character is not accounted in the size (in
* binary formats you are likely not supposed to mux that character). When
* extradata is copied, it is also padded with FF_INPUT_BUFFER_PADDING_SIZE
* zeros. */
avctx->extradata_size = buf->len;
return 0;
}
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "subtitles.h" #include "subtitles.h"
#include "libavcodec/internal.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
typedef struct ASSContext{ typedef struct ASSContext{
...@@ -132,12 +133,9 @@ static int ass_read_header(AVFormatContext *s) ...@@ -132,12 +133,9 @@ static int ass_read_header(AVFormatContext *s)
av_bprint_finalize(&line, NULL); av_bprint_finalize(&line, NULL);
av_bprint_finalize(&header, (char **)&st->codec->extradata); res = ff_bprint_to_extradata(st->codec, &header);
if (!st->codec->extradata) { if (res < 0)
res = AVERROR(ENOMEM);
goto end; goto end;
}
st->codec->extradata_size = header.len + 1;
ff_subtitles_queue_finalize(&ass->q); ff_subtitles_queue_finalize(&ass->q);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "subtitles.h" #include "subtitles.h"
#include "libavcodec/internal.h"
#include "libavcodec/jacosub.h" #include "libavcodec/jacosub.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
...@@ -159,7 +160,7 @@ static int jacosub_read_header(AVFormatContext *s) ...@@ -159,7 +160,7 @@ static int jacosub_read_header(AVFormatContext *s)
JACOsubContext *jacosub = s->priv_data; JACOsubContext *jacosub = s->priv_data;
int shift_set = 0; // only the first shift matters int shift_set = 0; // only the first shift matters
int merge_line = 0; int merge_line = 0;
int i; int i, ret;
AVStream *st = avformat_new_stream(s, NULL); AVStream *st = avformat_new_stream(s, NULL);
if (!st) if (!st)
...@@ -228,8 +229,9 @@ static int jacosub_read_header(AVFormatContext *s) ...@@ -228,8 +229,9 @@ static int jacosub_read_header(AVFormatContext *s)
} }
/* general/essential directives in the extradata */ /* general/essential directives in the extradata */
av_bprint_finalize(&header, (char **)&st->codec->extradata); ret = ff_bprint_to_extradata(st->codec, &header);
st->codec->extradata_size = header.len + 1; if (ret < 0)
return ret;
/* SHIFT and TIMERES affect the whole script so packet timing can only be /* SHIFT and TIMERES affect the whole script so packet timing can only be
* done in a second pass */ * done in a second pass */
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "subtitles.h" #include "subtitles.h"
#include "libavcodec/internal.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
...@@ -91,13 +92,9 @@ static int sami_read_header(AVFormatContext *s) ...@@ -91,13 +92,9 @@ static int sami_read_header(AVFormatContext *s)
av_bprint_clear(&buf); av_bprint_clear(&buf);
} }
st->codec->extradata_size = hdr_buf.len + 1; res = ff_bprint_to_extradata(st->codec, &hdr_buf);
av_bprint_finalize(&hdr_buf, (char **)&st->codec->extradata); if (res < 0)
if (!st->codec->extradata) {
st->codec->extradata_size = 0;
res = AVERROR(ENOMEM);
goto end; goto end;
}
ff_subtitles_queue_finalize(&sami->q); ff_subtitles_queue_finalize(&sami->q);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "avformat.h" #include "avformat.h"
#include "internal.h" #include "internal.h"
#include "subtitles.h" #include "subtitles.h"
#include "libavcodec/internal.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
...@@ -99,12 +100,9 @@ static int subviewer_read_header(AVFormatContext *s) ...@@ -99,12 +100,9 @@ static int subviewer_read_header(AVFormatContext *s)
av_bprintf(&header, "%s", line); av_bprintf(&header, "%s", line);
if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) { if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) {
/* end of header */ /* end of header */
av_bprint_finalize(&header, (char **)&st->codec->extradata); res = ff_bprint_to_extradata(st->codec, &header);
if (!st->codec->extradata) { if (res < 0)
res = AVERROR(ENOMEM);
goto end; goto end;
}
st->codec->extradata_size = header.len + 1;
} else if (strncmp(line, "[INFORMATION]", 13)) { } else if (strncmp(line, "[INFORMATION]", 13)) {
/* assume file metadata at this point */ /* assume file metadata at this point */
int i, j = 0; int i, j = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment