Commit 117d8c6d authored by Luca Barbato's avatar Luca Barbato

matroska: implement support for ProRes

Support Matroska native formatting.

On demuxing prepend a Frame container atom (32bit big endian encoded
frame size and 'icpf' string).
On muxing remove it.
parent 8071dca3
...@@ -71,6 +71,7 @@ const CodecTags ff_mkv_codec_tags[]={ ...@@ -71,6 +71,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 @@ ...@@ -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"
...@@ -1966,6 +1967,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, ...@@ -1966,6 +1967,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);
...@@ -1973,15 +1975,24 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, ...@@ -1973,15 +1975,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);
......
...@@ -1050,7 +1050,7 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, ...@@ -1050,7 +1050,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, "
...@@ -1061,12 +1061,20 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, ...@@ -1061,12 +1061,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);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment