diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat/wtvenc.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libavformat/wtvenc.c | 96 |
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 */ |