mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
Merge commit '117d8c6d1f1c187ffc6098d9618457e00534e013'
* commit '117d8c6d1f1c187ffc6098d9618457e00534e013': matroska: implement support for ProRes matroska: implement support for ALAC Conflicts: libavformat/matroskaenc.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
b8044972c4
@ -73,6 +73,7 @@ const CodecTags ff_mkv_codec_tags[]={
|
|||||||
{"V_MPEG4/ISO/SP" , AV_CODEC_ID_MPEG4},
|
{"V_MPEG4/ISO/SP" , AV_CODEC_ID_MPEG4},
|
||||||
{"V_MPEG4/ISO/AVC" , AV_CODEC_ID_H264},
|
{"V_MPEG4/ISO/AVC" , AV_CODEC_ID_H264},
|
||||||
{"V_MPEG4/MS/V3" , AV_CODEC_ID_MSMPEG4V3},
|
{"V_MPEG4/MS/V3" , AV_CODEC_ID_MSMPEG4V3},
|
||||||
|
{"V_PRORES" , AV_CODEC_ID_PRORES},
|
||||||
{"V_REAL/RV10" , AV_CODEC_ID_RV10},
|
{"V_REAL/RV10" , AV_CODEC_ID_RV10},
|
||||||
{"V_REAL/RV20" , AV_CODEC_ID_RV20},
|
{"V_REAL/RV20" , AV_CODEC_ID_RV20},
|
||||||
{"V_REAL/RV30" , AV_CODEC_ID_RV30},
|
{"V_REAL/RV30" , AV_CODEC_ID_RV30},
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "isom.h"
|
#include "isom.h"
|
||||||
#include "rm.h"
|
#include "rm.h"
|
||||||
#include "matroska.h"
|
#include "matroska.h"
|
||||||
|
#include "libavcodec/bytestream.h"
|
||||||
#include "libavcodec/mpeg4audio.h"
|
#include "libavcodec/mpeg4audio.h"
|
||||||
#include "libavutil/intfloat.h"
|
#include "libavutil/intfloat.h"
|
||||||
#include "libavutil/intreadwrite.h"
|
#include "libavutil/intreadwrite.h"
|
||||||
@ -1615,7 +1616,7 @@ static int matroska_read_header(AVFormatContext *s)
|
|||||||
Create the "atom size", "tag", and "tag version" fields the
|
Create the "atom size", "tag", and "tag version" fields the
|
||||||
decoder expects manually. */
|
decoder expects manually. */
|
||||||
extradata_size = 12 + track->codec_priv.size;
|
extradata_size = 12 + track->codec_priv.size;
|
||||||
extradata = av_mallocz(extradata_size);
|
extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
if (extradata == NULL)
|
if (extradata == NULL)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
AV_WB32(extradata, extradata_size);
|
AV_WB32(extradata, extradata_size);
|
||||||
@ -2117,6 +2118,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
|
|||||||
MatroskaTrackEncoding *encodings = track->encodings.elem;
|
MatroskaTrackEncoding *encodings = track->encodings.elem;
|
||||||
uint32_t pkt_size = lace_size[n];
|
uint32_t pkt_size = lace_size[n];
|
||||||
uint8_t *pkt_data = data;
|
uint8_t *pkt_data = data;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
if (encodings && encodings->scope & 1) {
|
if (encodings && encodings->scope & 1) {
|
||||||
res = matroska_decode_buffer(&pkt_data, &pkt_size, track);
|
res = matroska_decode_buffer(&pkt_data, &pkt_size, track);
|
||||||
@ -2124,15 +2126,24 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (st->codec->codec_id == AV_CODEC_ID_PRORES)
|
||||||
|
offset = 8;
|
||||||
|
|
||||||
pkt = av_mallocz(sizeof(AVPacket));
|
pkt = av_mallocz(sizeof(AVPacket));
|
||||||
/* XXX: prevent data copy... */
|
/* XXX: prevent data copy... */
|
||||||
if (av_new_packet(pkt, pkt_size) < 0) {
|
if (av_new_packet(pkt, pkt_size + offset) < 0) {
|
||||||
av_free(pkt);
|
av_free(pkt);
|
||||||
res = AVERROR(ENOMEM);
|
res = AVERROR(ENOMEM);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pkt->data, pkt_data, pkt_size);
|
if (st->codec->codec_id == AV_CODEC_ID_PRORES) {
|
||||||
|
uint8_t *buf = pkt->data;
|
||||||
|
bytestream_put_be32(&buf, pkt_size);
|
||||||
|
bytestream_put_be32(&buf, MKBETAG('i', 'c', 'p', 'f'));
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pkt->data + offset, pkt_data, pkt_size);
|
||||||
|
|
||||||
if (pkt_data != data)
|
if (pkt_data != data)
|
||||||
av_free(pkt_data);
|
av_free(pkt_data);
|
||||||
|
@ -475,8 +475,16 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo
|
|||||||
ret = ff_flac_write_header(dyn_cp, codec, 1);
|
ret = ff_flac_write_header(dyn_cp, codec, 1);
|
||||||
else if (codec->codec_id == AV_CODEC_ID_H264)
|
else if (codec->codec_id == AV_CODEC_ID_H264)
|
||||||
ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size);
|
ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size);
|
||||||
else if (codec->codec_id == AV_CODEC_ID_ALAC && (12 < codec->extradata_size))
|
else if (codec->codec_id == AV_CODEC_ID_ALAC) {
|
||||||
ret = ff_isom_write_avcc(dyn_cp, codec->extradata + 12, codec->extradata_size - 12);
|
if (codec->extradata_size < 36) {
|
||||||
|
av_log(s, AV_LOG_ERROR,
|
||||||
|
"Invalid extradata found, ALAC expects a 36-byte "
|
||||||
|
"QuickTime atom.");
|
||||||
|
ret = AVERROR_INVALIDDATA;
|
||||||
|
} else
|
||||||
|
avio_write(dyn_cp, codec->extradata + 12,
|
||||||
|
codec->extradata_size - 12);
|
||||||
|
}
|
||||||
else if (codec->extradata_size)
|
else if (codec->extradata_size)
|
||||||
avio_write(dyn_cp, codec->extradata, codec->extradata_size);
|
avio_write(dyn_cp, codec->extradata, codec->extradata_size);
|
||||||
} else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
} else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
@ -1061,7 +1069,7 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
MatroskaMuxContext *mkv = s->priv_data;
|
MatroskaMuxContext *mkv = s->priv_data;
|
||||||
AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
|
AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
|
||||||
uint8_t *data = NULL;
|
uint8_t *data = NULL;
|
||||||
int size = pkt->size;
|
int offset = 0, size = pkt->size;
|
||||||
int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
|
int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
|
||||||
|
|
||||||
av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
|
av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
|
||||||
@ -1072,12 +1080,20 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
|||||||
ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
|
ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
|
||||||
else
|
else
|
||||||
data = pkt->data;
|
data = pkt->data;
|
||||||
|
|
||||||
|
if (codec->codec_id == AV_CODEC_ID_PRORES) {
|
||||||
|
/* Matroska specification requires to remove the first QuickTime atom
|
||||||
|
*/
|
||||||
|
size -= 8;
|
||||||
|
offset = 8;
|
||||||
|
}
|
||||||
|
|
||||||
put_ebml_id(pb, blockid);
|
put_ebml_id(pb, blockid);
|
||||||
put_ebml_num(pb, size+4, 0);
|
put_ebml_num(pb, size+4, 0);
|
||||||
avio_w8(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126
|
avio_w8(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126
|
||||||
avio_wb16(pb, ts - mkv->cluster_pts);
|
avio_wb16(pb, ts - mkv->cluster_pts);
|
||||||
avio_w8(pb, flags);
|
avio_w8(pb, flags);
|
||||||
avio_write(pb, data, size);
|
avio_write(pb, data + offset, size);
|
||||||
if (data != pkt->data)
|
if (data != pkt->data)
|
||||||
av_free(data);
|
av_free(data);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user