uint64_t pixel_width;
uint64_t pixel_height;
uint64_t fourcc;
+ uint64_t interlaced;
+ uint64_t field_order;
uint64_t stereo_mode;
} MatroskaTrackVideo;
{ MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE },
{ MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE },
{ MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE },
- { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_NONE },
+ { MATROSKA_ID_VIDEOFLAGINTERLACED, EBML_UINT, 0, offsetof(MatroskaTrackVideo, interlaced), { .u = MATROSKA_VIDEO_INTERLACE_FLAG_UNDETERMINED } },
+ { MATROSKA_ID_VIDEOFIELDORDER, EBML_UINT, 0, offsetof(MatroskaTrackVideo, field_order), { .u = MATROSKA_VIDEO_FIELDORDER_UNDETERMINED } },
{ MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo, stereo_mode), { .u = MATROSKA_VIDEO_STEREOMODE_TYPE_NB } },
{ MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE },
{ 0 }
av_log(s, AV_LOG_WARNING,
"Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n");
} else
- st->codec->channel_layout = mask;
+ st->codecpar->channel_layout = mask;
}
av_dict_free(&dict);
}
return 0;
}
+static int mkv_field_order(int64_t field_order)
+{
+ switch (field_order) {
+ case MATROSKA_VIDEO_FIELDORDER_PROGRESSIVE:
+ return AV_FIELD_PROGRESSIVE;
+ case MATROSKA_VIDEO_FIELDORDER_UNDETERMINED:
+ return AV_FIELD_UNKNOWN;
+ case MATROSKA_VIDEO_FIELDORDER_TT:
+ return AV_FIELD_TT;
+ case MATROSKA_VIDEO_FIELDORDER_BB:
+ return AV_FIELD_BB;
+ case MATROSKA_VIDEO_FIELDORDER_BT:
+ return AV_FIELD_BT;
+ case MATROSKA_VIDEO_FIELDORDER_TB:
+ return AV_FIELD_TB;
+ default:
+ return AV_FIELD_UNKNOWN;
+ }
+}
+
+static void mkv_stereo_mode_display_mul(int stereo_mode,
+ int *h_width, int *h_height)
+{
+ switch (stereo_mode) {
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_MONO:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_RL:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR:
+ break;
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_RL:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR:
+ *h_width = 2;
+ break;
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_BOTTOM_TOP:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_RL:
+ case MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR:
+ *h_height = 2;
+ break;
+ }
+}
+
static int matroska_parse_tracks(AVFormatContext *s)
{
MatroskaDemuxContext *matroska = s->priv_data;
ffio_init_context(&b, track->codec_priv.data,
track->codec_priv.size,
0, NULL, NULL, NULL, NULL);
- ret = ff_get_wav_header(s, &b, st->codec, track->codec_priv.size);
+ ret = ff_get_wav_header(s, &b, st->codecpar, track->codec_priv.size);
if (ret < 0)
return ret;
- codec_id = st->codec->codec_id;
+ codec_id = st->codecpar->codec_id;
extradata_offset = FFMIN(track->codec_priv.size, 18);
} else if (!strcmp(track->codec_id, "V_QUICKTIME") &&
(track->codec_priv.size >= 86) &&
(track->codec_priv.data)) {
- track->video.fourcc = AV_RL32(track->codec_priv.data);
- codec_id = ff_codec_get_id(ff_codec_movvideo_tags,
- track->video.fourcc);
+ if (track->codec_priv.size == AV_RB32(track->codec_priv.data)) {
+ track->video.fourcc = AV_RL32(track->codec_priv.data + 4);
+ codec_id = ff_codec_get_id(ff_codec_movvideo_tags,
+ track->video.fourcc);
+ }
+ if (codec_id == AV_CODEC_ID_NONE) {
+ track->video.fourcc = AV_RL32(track->codec_priv.data);
+ codec_id = ff_codec_get_id(ff_codec_movvideo_tags,
+ track->video.fourcc);
+ }
if (codec_id == AV_CODEC_ID_NONE) {
char buf[32];
av_get_codec_tag_string(buf, sizeof(buf), track->video.fourcc);
if (!track->audio.buf)
return AVERROR(ENOMEM);
if (codec_id == AV_CODEC_ID_RA_288) {
- st->codec->block_align = track->audio.coded_framesize;
+ st->codecpar->block_align = track->audio.coded_framesize;
track->codec_priv.size = 0;
} else {
if (codec_id == AV_CODEC_ID_SIPR && flavor < 4) {
- const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
+ static const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 };
track->audio.sub_packet_size = ff_sipr_subpk_size[flavor];
- st->codec->bit_rate = sipr_bit_rate[flavor];
+ st->codecpar->bit_rate = sipr_bit_rate[flavor];
}
- st->codec->block_align = track->audio.sub_packet_size;
+ st->codecpar->block_align = track->audio.sub_packet_size;
extradata_offset = 78;
}
} else if (codec_id == AV_CODEC_ID_FLAC && track->codec_priv.size) {
avpriv_set_pts_info(st, 64, matroska->time_scale * track->time_scale,
1000 * 1000 * 1000); /* 64 bit pts in ns */
+ if (track->type == MATROSKA_TRACK_TYPE_AUDIO &&
+ track->audio.out_samplerate) {
+ st->codecpar->initial_padding = av_rescale_q(track->codec_delay,
+ (AVRational){ 1, 1000000000 },
+ (AVRational){ 1, track->audio.out_samplerate });
+ }
+
/* convert the delay from ns to the track timebase */
track->codec_delay = av_rescale_q(track->codec_delay,
(AVRational){ 1, 1000000000 },
st->time_base);
- st->codec->codec_id = codec_id;
+ st->codecpar->codec_id = codec_id;
st->start_time = 0;
if (strcmp(track->language, "und"))
av_dict_set(&st->metadata, "language", track->language, 0);
if (track->flag_forced)
st->disposition |= AV_DISPOSITION_FORCED;
- if (!st->codec->extradata) {
+ if (!st->codecpar->extradata) {
if (extradata) {
- st->codec->extradata = extradata;
- st->codec->extradata_size = extradata_size;
+ st->codecpar->extradata = extradata;
+ st->codecpar->extradata_size = extradata_size;
} else if (track->codec_priv.data && track->codec_priv.size > 0) {
- st->codec->extradata = av_mallocz(track->codec_priv.size +
- AV_INPUT_BUFFER_PADDING_SIZE);
- if (!st->codec->extradata)
+ st->codecpar->extradata = av_mallocz(track->codec_priv.size +
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codecpar->extradata)
return AVERROR(ENOMEM);
- st->codec->extradata_size = track->codec_priv.size;
- memcpy(st->codec->extradata,
+ st->codecpar->extradata_size = track->codec_priv.size;
+ memcpy(st->codecpar->extradata,
track->codec_priv.data + extradata_offset,
track->codec_priv.size);
}
}
if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_tag = track->video.fourcc;
- st->codec->width = track->video.pixel_width;
- st->codec->height = track->video.pixel_height;
+ int display_width_mul = 1;
+ int display_height_mul = 1;
+
+ st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codecpar->codec_tag = track->video.fourcc;
+ st->codecpar->width = track->video.pixel_width;
+ st->codecpar->height = track->video.pixel_height;
+
+ if (track->video.interlaced == MATROSKA_VIDEO_INTERLACE_FLAG_INTERLACED)
+ st->codecpar->field_order = mkv_field_order(track->video.field_order);
+
+ if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
+ mkv_stereo_mode_display_mul(track->video.stereo_mode, &display_width_mul, &display_height_mul);
+
av_reduce(&st->sample_aspect_ratio.num,
&st->sample_aspect_ratio.den,
- st->codec->height * track->video.display_width,
- st->codec->width * track->video.display_height,
+ st->codecpar->height * track->video.display_width * display_width_mul,
+ st->codecpar->width * track->video.display_height * display_height_mul,
255);
- if (st->codec->codec_id != AV_CODEC_ID_H264 &&
- st->codec->codec_id != AV_CODEC_ID_HEVC)
+ if (st->codecpar->codec_id != AV_CODEC_ID_H264 &&
+ st->codecpar->codec_id != AV_CODEC_ID_HEVC)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
if (track->default_duration) {
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
return ret;
}
} else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
- st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- st->codec->sample_rate = track->audio.out_samplerate;
- st->codec->channels = track->audio.channels;
- if (st->codec->codec_id != AV_CODEC_ID_AAC)
+ st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+ st->codecpar->sample_rate = track->audio.out_samplerate;
+ st->codecpar->channels = track->audio.channels;
+ if (st->codecpar->codec_id != AV_CODEC_ID_AAC)
st->need_parsing = AVSTREAM_PARSE_HEADERS;
+ if (st->codecpar->codec_id == AV_CODEC_ID_MP3)
+ st->need_parsing = AVSTREAM_PARSE_FULL;
} else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
- st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- if (st->codec->codec_id == AV_CODEC_ID_SSA)
+ st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ if (st->codecpar->codec_id == AV_CODEC_ID_SSA)
matroska->contains_ssa = 1;
}
}
break;
av_dict_set(&st->metadata, "filename", attachments[j].filename, 0);
av_dict_set(&st->metadata, "mimetype", attachments[j].mime, 0);
- st->codec->codec_id = AV_CODEC_ID_NONE;
+ st->codecpar->codec_id = AV_CODEC_ID_NONE;
for (i = 0; ff_mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
if (!strncmp(ff_mkv_image_mime_tags[i].str, attachments[j].mime,
strlen(ff_mkv_image_mime_tags[i].str))) {
- st->codec->codec_id = ff_mkv_image_mime_tags[i].id;
+ st->codecpar->codec_id = ff_mkv_image_mime_tags[i].id;
break;
}
}
attachments[j].stream = st;
- if (st->codec->codec_id != AV_CODEC_ID_NONE) {
- st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ if (st->codecpar->codec_id != AV_CODEC_ID_NONE) {
+ st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
+ st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
av_init_packet(&st->attached_pic);
if ((res = av_new_packet(&st->attached_pic, attachments[j].bin.size)) < 0)
st->attached_pic.stream_index = st->index;
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
} else {
- st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
- st->codec->extradata = av_malloc(attachments[j].bin.size);
- if (!st->codec->extradata)
+ st->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
+ st->codecpar->extradata = av_malloc(attachments[j].bin.size);
+ if (!st->codecpar->extradata)
break;
- st->codec->extradata_size = attachments[j].bin.size;
- memcpy(st->codec->extradata, attachments[j].bin.data,
+ st->codecpar->extradata_size = attachments[j].bin.size;
+ memcpy(st->codecpar->extradata, attachments[j].bin.data,
attachments[j].bin.size);
for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) {
if (!strncmp(ff_mkv_mime_tags[i].str, attachments[j].mime,
strlen(ff_mkv_mime_tags[i].str))) {
- st->codec->codec_id = ff_mkv_mime_tags[i].id;
+ st->codecpar->codec_id = ff_mkv_mime_tags[i].id;
break;
}
}
uint8_t *data, int size, uint64_t timecode,
uint64_t duration, int64_t pos)
{
- int a = st->codec->block_align;
+ int a = st->codecpar->block_align;
int sps = track->audio.sub_packet_size;
int cfs = track->audio.coded_framesize;
int h = track->audio.sub_packet_h;
if (!track->audio.pkt_cnt) {
if (track->audio.sub_packet_cnt == 0)
track->audio.buf_timecode = timecode;
- if (st->codec->codec_id == AV_CODEC_ID_RA_288) {
+ if (st->codecpar->codec_id == AV_CODEC_ID_RA_288) {
if (size < cfs * h / 2) {
av_log(matroska->ctx, AV_LOG_ERROR,
"Corrupt int4 RM-style audio packet size\n");
for (x = 0; x < h / 2; x++)
memcpy(track->audio.buf + x * 2 * w + y * cfs,
data + x * cfs, cfs);
- } else if (st->codec->codec_id == AV_CODEC_ID_SIPR) {
+ } else if (st->codecpar->codec_id == AV_CODEC_ID_SIPR) {
if (size < w) {
av_log(matroska->ctx, AV_LOG_ERROR,
"Corrupt sipr RM-style audio packet size\n");
}
if (++track->audio.sub_packet_cnt >= h) {
- if (st->codec->codec_id == AV_CODEC_ID_SIPR)
+ if (st->codecpar->codec_id == AV_CODEC_ID_SIPR)
ff_rm_reorder_sipr_data(track->audio.buf, h, w);
track->audio.sub_packet_cnt = 0;
track->audio.pkt_cnt = h * w / a;
uint16_t ver;
int ret, offset = 0;
- if (srclen < 12 || track->stream->codec->extradata_size < 2)
+ if (srclen < 12 || track->stream->codecpar->extradata_size < 2)
return AVERROR_INVALIDDATA;
- ver = AV_RL16(track->stream->codec->extradata);
+ ver = AV_RL16(track->stream->codecpar->extradata);
samples = AV_RL32(src);
src += 4;
return res;
}
- if (st->codec->codec_id == AV_CODEC_ID_WAVPACK) {
+ if (st->codecpar->codec_id == AV_CODEC_ID_WAVPACK) {
uint8_t *wv_data;
res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size);
if (res < 0) {
pkt_data = wv_data;
}
- if (st->codec->codec_id == AV_CODEC_ID_PRORES)
+ if (st->codecpar->codec_id == AV_CODEC_ID_PRORES)
offset = 8;
pkt = av_mallocz(sizeof(AVPacket));
return AVERROR(ENOMEM);
}
- if (st->codec->codec_id == AV_CODEC_ID_PRORES) {
+ if (st->codecpar->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'));
else
pkt->pts = timecode;
pkt->pos = pos;
- if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE || st->codec->codec_id == AV_CODEC_ID_TEXT)
+ if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE || st->codecpar->codec_id == AV_CODEC_ID_TEXT)
pkt->duration = duration;
#if FF_API_CONVERGENCE_DURATION
FF_DISABLE_DEPRECATION_WARNINGS
- if (st->codec->codec_id == AV_CODEC_ID_TEXT)
+ if (st->codecpar->codec_id == AV_CODEC_ID_TEXT)
pkt->convergence_duration = duration;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
- if (st->codec->codec_id == AV_CODEC_ID_SSA)
+ if (st->codecpar->codec_id == AV_CODEC_ID_SSA)
matroska_fix_ass_packet(matroska, pkt, duration);
if (matroska->prev_pkt &&
timecode != AV_NOPTS_VALUE &&
matroska->prev_pkt->pts == timecode &&
matroska->prev_pkt->stream_index == st->index &&
- st->codec->codec_id == AV_CODEC_ID_SSA)
+ st->codecpar->codec_id == AV_CODEC_ID_SSA)
matroska_merge_packets(matroska->prev_pkt, pkt);
else {
dynarray_add(&matroska->packets, &matroska->num_packets, pkt);
FFMAX(track->end_timecode, timecode + block_duration);
for (n = 0; n < laces; n++) {
- if ((st->codec->codec_id == AV_CODEC_ID_RA_288 ||
- st->codec->codec_id == AV_CODEC_ID_COOK ||
- st->codec->codec_id == AV_CODEC_ID_SIPR ||
- st->codec->codec_id == AV_CODEC_ID_ATRAC3) &&
- st->codec->block_align && track->audio.sub_packet_size) {
+ if ((st->codecpar->codec_id == AV_CODEC_ID_RA_288 ||
+ st->codecpar->codec_id == AV_CODEC_ID_COOK ||
+ st->codecpar->codec_id == AV_CODEC_ID_SIPR ||
+ st->codecpar->codec_id == AV_CODEC_ID_ATRAC3) &&
+ st->codecpar->block_align && track->audio.sub_packet_size) {
res = matroska_parse_rm_audio(matroska, track, st, data,
lace_size[n],
timecode, duration, pos);