diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libavformat/matroskaenc.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libavformat/matroskaenc.c | 84 |
1 files changed, 65 insertions, 19 deletions
diff --git a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c index e461c5e60ed..17eb318aadb 100644 --- a/chromium/third_party/ffmpeg/libavformat/matroskaenc.c +++ b/chromium/third_party/ffmpeg/libavformat/matroskaenc.c @@ -22,6 +22,7 @@ #include <stdint.h> #include "avc.h" +#include "hevc.h" #include "avformat.h" #include "avio_internal.h" #include "avlanguage.h" @@ -84,6 +85,7 @@ typedef struct { typedef struct { int write_dts; int has_cue; + int64_t ts_offset; } mkv_track; #define MODE_MATROSKAv2 0x01 @@ -532,6 +534,8 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo ret = put_wv_codecpriv(dyn_cp, codec); else if (codec->codec_id == AV_CODEC_ID_H264) ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size); + else if (codec->codec_id == AV_CODEC_ID_HEVC) + ret = ff_isom_write_hvcc(dyn_cp, codec->extradata, codec->extradata_size, 0); else if (codec->codec_id == AV_CODEC_ID_ALAC) { if (codec->extradata_size < 36) { av_log(s, AV_LOG_ERROR, @@ -541,6 +545,9 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo } else avio_write(dyn_cp, codec->extradata + 12, codec->extradata_size - 12); + } else if (codec->codec_id == AV_CODEC_ID_PRORES && + ff_codec_get_id(ff_codec_movvideo_tags, codec->codec_tag) == AV_CODEC_ID_PRORES) { + avio_wl32(dyn_cp, codec->codec_tag); } else if (codec->extradata_size && codec->codec_id != AV_CODEC_ID_TTA) avio_write(dyn_cp, codec->extradata, codec->extradata_size); @@ -548,9 +555,23 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo if (qt_id) { if (!codec->codec_tag) codec->codec_tag = ff_codec_get_tag(ff_codec_movvideo_tags, codec->codec_id); - if (codec->extradata_size) + if (codec->extradata_size) { + if ( ff_codec_get_id(ff_codec_movvideo_tags, codec->codec_tag) == codec->codec_id + && ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(codec->extradata+4)) != codec->codec_id + ) { + int i; + avio_wb32(dyn_cp, 0x5a + codec->extradata_size); + avio_wl32(dyn_cp, codec->codec_tag); + for(i=0; i<0x5a-8; i++) + avio_w8(dyn_cp, 0); + } avio_write(dyn_cp, codec->extradata, codec->extradata_size); + } } else { + if (!ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id)) + av_log(s, AV_LOG_WARNING, "codec %s is not supported by this format\n", + avcodec_get_name(codec->codec_id)); + if (!codec->codec_tag) codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id); if (!codec->codec_tag) { @@ -559,7 +580,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo ret = AVERROR(EINVAL); } - ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0); + ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0, 0); } } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -573,7 +594,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo if (!codec->codec_tag) codec->codec_tag = tag; - ff_put_wav_header(dyn_cp, codec); + ff_put_wav_header(dyn_cp, codec, FF_PUT_WAV_HEADER_FORCE_WAVEFORMATEX); } codecpriv_size = avio_close_dyn_buf(dyn_cp, &codecpriv); @@ -616,7 +637,7 @@ static int mkv_write_tracks(AVFormatContext *s) continue; } - if (!bit_depth) + if (!bit_depth && codec->codec_id != AV_CODEC_ID_ADPCM_G726) bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3; if (!bit_depth) bit_depth = codec->bits_per_coded_sample; @@ -674,13 +695,17 @@ static int mkv_write_tracks(AVFormatContext *s) } } + if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->delay && codec->codec_id == AV_CODEC_ID_OPUS) { +// mkv->tracks[i].ts_offset = av_rescale_q(codec->delay, +// (AVRational){ 1, codec->sample_rate }, +// st->time_base); + + put_ebml_uint(pb, MATROSKA_ID_CODECDELAY, + av_rescale_q(codec->delay, (AVRational){ 1, codec->sample_rate }, + (AVRational){ 1, 1000000000 })); + } if (codec->codec_id == AV_CODEC_ID_OPUS) { - uint64_t codec_delay =av_rescale_q(codec->delay, - (AVRational){1, codec->sample_rate}, - (AVRational){1, 1000000000}); - put_ebml_uint(pb, MATROSKA_ID_CODECDELAY, codec_delay); put_ebml_uint(pb, MATROSKA_ID_SEEKPREROLL, OPUS_SEEK_PREROLL); - } if (mkv->mode == MODE_WEBM && !(codec->codec_id == AV_CODEC_ID_VP8 || @@ -928,7 +953,9 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme end_ebml_master(s->pb, targets); while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) - if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode")) + if (av_strcasecmp(t->key, "title") && + av_strcasecmp(t->key, "stereo_mode") && + av_strcasecmp(t->key, "encoding_tool")) mkv_write_simpletag(s->pb, t); end_ebml_master(s->pb, tag); @@ -1069,7 +1096,7 @@ static int mkv_write_header(AVFormatContext *s) AVIOContext *pb = s->pb; ebml_master ebml_header, segment_info; AVDictionaryEntry *tag; - int ret, i; + int ret, i, version = 2; if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM; else mkv->mode = MODE_MATROSKAv2; @@ -1077,7 +1104,12 @@ static int mkv_write_header(AVFormatContext *s) if (s->avoid_negative_ts < 0) s->avoid_negative_ts = 1; - for (i = 0; i < s->nb_streams; i++) + if (mkv->mode != MODE_WEBM || + av_dict_get(s->metadata, "stereo_mode", NULL, 0) || + av_dict_get(s->metadata, "alpha_mode", NULL, 0)) + version = 4; + + for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->codec->codec_id == AV_CODEC_ID_ATRAC3 || s->streams[i]->codec->codec_id == AV_CODEC_ID_COOK || s->streams[i]->codec->codec_id == AV_CODEC_ID_RA_288 || @@ -1089,8 +1121,13 @@ static int mkv_write_header(AVFormatContext *s) avcodec_get_name(s->streams[i]->codec->codec_id)); return AVERROR_PATCHWELCOME; } + if (s->streams[i]->codec->codec_id == AV_CODEC_ID_OPUS || + av_dict_get(s->streams[i]->metadata, "stereo_mode", NULL, 0) || + av_dict_get(s->streams[i]->metadata, "alpha_mode", NULL, 0)) + version = 4; + } - mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks)); + mkv->tracks = av_mallocz_array(s->nb_streams, sizeof(*mkv->tracks)); if (!mkv->tracks) return AVERROR(ENOMEM); @@ -1100,7 +1137,7 @@ static int mkv_write_header(AVFormatContext *s) put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); put_ebml_string (pb, EBML_ID_DOCTYPE , s->oformat->name); - put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 4); + put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , version); put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); end_ebml_master(pb, ebml_header); @@ -1123,7 +1160,7 @@ static int mkv_write_header(AVFormatContext *s) put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000); if ((tag = av_dict_get(s->metadata, "title", NULL, 0))) put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value); - if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { + if (!(s->flags & AVFMT_FLAG_BITEXACT)) { uint32_t segment_uid[4]; AVLFG lfg; @@ -1133,7 +1170,10 @@ static int mkv_write_header(AVFormatContext *s) segment_uid[i] = av_lfg_get(&lfg); put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); - put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); + if ((tag = av_dict_get(s->metadata, "encoding_tool", NULL, 0))) + put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, tag->value); + else + put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); } else { const char *ident = "Lavf"; @@ -1349,6 +1389,10 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, if (codec->codec_id == AV_CODEC_ID_H264 && codec->extradata_size > 0 && (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) ff_avc_parse_nal_units_buf(pkt->data, &data, &size); + else if (codec->codec_id == AV_CODEC_ID_HEVC && codec->extradata_size > 6 && + (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) + /* extradata is Annex B, assume the bitstream is too and convert it */ + ff_hevc_annexb2mp4_buf(pkt->data, &data, &size, 0, NULL); else if (codec->codec_id == AV_CODEC_ID_WAVPACK) { int ret = mkv_strip_wavpack(pkt->data, &data, &size); if (ret < 0) { @@ -1520,6 +1564,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n"); return AVERROR(EINVAL); } + ts += mkv->tracks[pkt->stream_index].ts_offset; if (!s->pb->seekable) { if (!mkv->dyn_bc) { @@ -1585,6 +1630,7 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) cluster_time = pkt->dts - mkv->cluster_pts; else cluster_time = pkt->pts - mkv->cluster_pts; + cluster_time += mkv->tracks[pkt->stream_index].ts_offset; // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or // after 4k and on a keyframe @@ -1630,9 +1676,9 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM); } else ret = av_dup_packet(&mkv->cur_audio_pkt); - if (mkv->cur_audio_pkt.side_data_elems > 0) { - ret = av_copy_packet_side_data(&mkv->cur_audio_pkt, &mkv->cur_audio_pkt); - } + if (mkv->cur_audio_pkt.side_data_elems > 0) { + ret = av_copy_packet_side_data(&mkv->cur_audio_pkt, &mkv->cur_audio_pkt); + } } else ret = mkv_write_packet_internal(s, pkt); return ret; |