summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/ffmpeg/libavformat/wtvenc.c
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat/wtvenc.c')
-rw-r--r--chromium/third_party/ffmpeg/libavformat/wtvenc.c96
1 files changed, 68 insertions, 28 deletions
diff --git a/chromium/third_party/ffmpeg/libavformat/wtvenc.c b/chromium/third_party/ffmpeg/libavformat/wtvenc.c
index 04e6cc22f8d..634545d4594 100644
--- a/chromium/third_party/ffmpeg/libavformat/wtvenc.c
+++ b/chromium/third_party/ffmpeg/libavformat/wtvenc.c
@@ -30,8 +30,8 @@
#include "avformat.h"
#include "avio_internal.h"
#include "internal.h"
+#include "mpegts.h"
#include "wtv.h"
-#include "asf.h"
#define WTV_BIGSECTOR_SIZE (1 << WTV_BIGSECTOR_BITS)
#define INDEX_BASE 0x2
@@ -130,16 +130,6 @@ typedef struct {
#define write_pad(pb, size) ffio_fill(pb, 0, size)
-static const ff_asf_guid *get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
-{
- int i;
- for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
- if (id == av_guid[i].id)
- return &(av_guid[i].guid);
- }
- return NULL;
-}
-
/**
* Write chunk header. If header chunk (0x80000000 set) then add to list of header chunks
*/
@@ -223,10 +213,53 @@ static void finish_chunk(AVFormatContext *s)
write_index(s);
}
+static void put_videoinfoheader2(AVIOContext *pb, AVStream *st)
+{
+ AVRational dar = av_mul_q(st->sample_aspect_ratio, (AVRational){st->codec->width, st->codec->height});
+ unsigned int num, den;
+ av_reduce(&num, &den, dar.num, dar.den, 0xFFFFFFFF);
+
+ /* VIDEOINFOHEADER2 */
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, st->codec->width);
+ avio_wl32(pb, st->codec->height);
+
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+
+ avio_wl32(pb, st->codec->bit_rate);
+ avio_wl32(pb, 0);
+ avio_wl64(pb, st->avg_frame_rate.num && st->avg_frame_rate.den ? INT64_C(10000000) / av_q2d(st->avg_frame_rate) : 0);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+
+ avio_wl32(pb, num);
+ avio_wl32(pb, den);
+ avio_wl32(pb, 0);
+ avio_wl32(pb, 0);
+
+ ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0, 1);
+
+ if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+ int padding = (st->codec->extradata_size & 3) ? 4 - (st->codec->extradata_size & 3) : 0;
+ /* MPEG2VIDEOINFO */
+ avio_wl32(pb, 0);
+ avio_wl32(pb, st->codec->extradata_size + padding);
+ avio_wl32(pb, -1);
+ avio_wl32(pb, -1);
+ avio_wl32(pb, 0);
+ avio_write(pb, st->codec->extradata, st->codec->extradata_size);
+ ffio_fill(pb, 0, padding);
+ }
+}
+
static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
{
- WtvContext *wctx = s->priv_data;
const ff_asf_guid *g, *media_type, *format_type;
+ const AVCodecTag *tags;
AVIOContext *pb = s->pb;
int64_t hdr_pos_start;
int hdr_size = 0;
@@ -234,21 +267,18 @@ static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
g = get_codec_guid(st->codec->codec_id, ff_video_guids);
media_type = &ff_mediatype_video;
- format_type = &ff_format_mpeg2_video;
+ format_type = st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO ? &ff_format_mpeg2_video : &ff_format_videoinfo2;
+ tags = ff_codec_bmp_tags;
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
g = get_codec_guid(st->codec->codec_id, ff_codec_wav_guids);
media_type = &ff_mediatype_audio;
format_type = &ff_format_waveformatex;
+ tags = ff_codec_wav_tags;
} else {
av_log(s, AV_LOG_ERROR, "unknown codec_type (0x%x)\n", st->codec->codec_type);
return -1;
}
- if (g == NULL) {
- av_log(s, AV_LOG_ERROR, "can't get video codec_id (0x%x) guid.\n", st->codec->codec_id);
- return -1;
- }
-
ff_put_guid(pb, media_type); // mediatype
ff_put_guid(pb, &ff_mediasubtype_cpfilters_processed); // subtype
write_pad(pb, 12);
@@ -257,15 +287,10 @@ static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
hdr_pos_start = avio_tell(pb);
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (wctx->first_video_flag) {
- write_pad(pb, 216); //The size is sensitive.
- wctx->first_video_flag = 0;
- } else {
- write_pad(pb, 72); // aspect ratio
- ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0);
- }
+ put_videoinfoheader2(pb, st);
} else {
- ff_put_wav_header(pb, st->codec);
+ if (ff_put_wav_header(pb, st->codec, 0) < 0)
+ format_type = &ff_format_none;
}
hdr_size = avio_tell(pb) - hdr_pos_start;
@@ -273,7 +298,17 @@ static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
avio_seek(pb, -(hdr_size + 4), SEEK_CUR);
avio_wl32(pb, hdr_size + 32);
avio_seek(pb, hdr_size, SEEK_CUR);
- ff_put_guid(pb, g); // actual_subtype
+ if (g) {
+ ff_put_guid(pb, g); // actual_subtype
+ } else {
+ int tag = ff_codec_get_tag(tags, st->codec->codec_id);
+ if (!tag) {
+ av_log(s, AV_LOG_ERROR, "unsupported codec_id (0x%x)\n", st->codec->codec_id);
+ return -1;
+ }
+ avio_wl32(pb, tag);
+ avio_write(pb, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12);
+ }
ff_put_guid(pb, format_type); // actual_formattype
return 0;
@@ -426,10 +461,15 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
{
AVIOContext *pb = s->pb;
WtvContext *wctx = s->priv_data;
+ AVStream *st = s->streams[pkt->stream_index];
- if (s->streams[pkt->stream_index]->codec->codec_id == AV_CODEC_ID_MJPEG && !wctx->thumbnail.size) {
+ if (st->codec->codec_id == AV_CODEC_ID_MJPEG && !wctx->thumbnail.size) {
av_copy_packet(&wctx->thumbnail, pkt);
return 0;
+ } else if (st->codec->codec_id == AV_CODEC_ID_H264) {
+ int ret = ff_check_h264_startcode(s, st, pkt);
+ if (ret < 0)
+ return ret;
}
/* emit sync chunk and 'timeline.table.0.entries.Event' record every 50 frames */