diff options
Diffstat (limited to 'ffmpeg/libavformat/wtvenc.c')
| -rw-r--r-- | ffmpeg/libavformat/wtvenc.c | 93 |
1 files changed, 66 insertions, 27 deletions
diff --git a/ffmpeg/libavformat/wtvenc.c b/ffmpeg/libavformat/wtvenc.c index 22917a4..5e3b9b9 100644 --- a/ffmpeg/libavformat/wtvenc.c +++ b/ffmpeg/libavformat/wtvenc.c @@ -28,6 +28,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/avassert.h" #include "avformat.h" +#include "avio_internal.h" #include "internal.h" #include "wtv.h" #include "asf.h" @@ -87,10 +88,10 @@ typedef struct { typedef struct { int64_t timeline_start_pos; WtvFile file[WTV_FILES]; - int64_t serial; /** chunk serial number */ - int64_t last_chunk_pos; /** last chunk position */ - int64_t last_timestamp_pos; /** last timestamp chunk position */ - int64_t first_index_pos; /** first index_chunk position */ + int64_t serial; /**< chunk serial number */ + int64_t last_chunk_pos; /**< last chunk position */ + int64_t last_timestamp_pos; /**< last timestamp chunk position */ + int64_t first_index_pos; /**< first index_chunk position */ WtvChunkEntry index[MAX_NB_INDEX]; int nb_index; @@ -127,12 +128,7 @@ typedef struct { WTVHeaderWriteFunc *write_header; } WTVRootEntryTable; -static int write_pad(AVIOContext *pb, int size) -{ - for (; size > 0; size--) - avio_w8(pb, 0); - return 0; -} +#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) { @@ -227,10 +223,52 @@ 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) { + /* MPEG2VIDEOINFO */ + avio_wl32(pb, 0); + avio_wl32(pb, st->codec->extradata_size); + avio_wl32(pb, -1); + avio_wl32(pb, -1); + avio_wl32(pb, 0); + avio_write(pb, st->codec->extradata, st->codec->extradata_size); + avio_wl64(pb, 0); + } +} + 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; @@ -238,21 +276,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); @@ -261,15 +296,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) + format_type = &ff_format_none; } hdr_size = avio_tell(pb) - hdr_pos_start; @@ -277,7 +307,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; @@ -457,7 +497,6 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) write_pad(pb, WTV_PAD8(pkt->size) - pkt->size); wctx->serial++; - avio_flush(pb); return 0; } |
