summaryrefslogtreecommitdiff
path: root/ffmpeg/libavformat/wtvenc.c
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
committerTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
commitf7813a5324be39d13ab536c245d15dfc602a7849 (patch)
treefad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavformat/wtvenc.c
parentb7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff)
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavformat/wtvenc.c')
-rw-r--r--ffmpeg/libavformat/wtvenc.c93
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;
}