asfdec: split reading stream properties out of asf_read_header()
This contains a rename from gsize->size Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
This commit is contained in:
parent
70630e35a4
commit
8bf6db1b29
@ -206,6 +206,191 @@ static int asf_read_file_properties(AVFormatContext *s, int64_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
|
||||
{
|
||||
ASFContext *asf = s->priv_data;
|
||||
ByteIOContext *pb = s->pb;
|
||||
AVStream *st;
|
||||
ASFStream *asf_st;
|
||||
ff_asf_guid g;
|
||||
enum AVMediaType type;
|
||||
int type_specific_size, sizeX;
|
||||
uint64_t total_size;
|
||||
unsigned int tag1;
|
||||
int64_t pos1, pos2, start_time;
|
||||
int test_for_ext_stream_audio, is_dvr_ms_audio=0;
|
||||
|
||||
if (s->nb_streams == ASF_MAX_STREAMS) {
|
||||
av_log(s, AV_LOG_ERROR, "too many streams\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
pos1 = url_ftell(pb);
|
||||
|
||||
st = av_new_stream(s, 0);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
|
||||
asf_st = av_mallocz(sizeof(ASFStream));
|
||||
if (!asf_st)
|
||||
return AVERROR(ENOMEM);
|
||||
st->priv_data = asf_st;
|
||||
start_time = asf->hdr.preroll;
|
||||
|
||||
asf_st->stream_language_index = 128; // invalid stream index means no language info
|
||||
|
||||
if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
|
||||
st->duration = asf->hdr.play_time /
|
||||
(10000000 / 1000) - start_time;
|
||||
}
|
||||
ff_get_guid(pb, &g);
|
||||
|
||||
test_for_ext_stream_audio = 0;
|
||||
if (!ff_guidcmp(&g, &ff_asf_audio_stream)) {
|
||||
type = AVMEDIA_TYPE_AUDIO;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_video_stream)) {
|
||||
type = AVMEDIA_TYPE_VIDEO;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) {
|
||||
type = AVMEDIA_TYPE_VIDEO;
|
||||
st->codec->codec_id = CODEC_ID_MJPEG;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_command_stream)) {
|
||||
type = AVMEDIA_TYPE_DATA;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) {
|
||||
test_for_ext_stream_audio = 1;
|
||||
type = AVMEDIA_TYPE_UNKNOWN;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
ff_get_guid(pb, &g);
|
||||
total_size = get_le64(pb);
|
||||
type_specific_size = get_le32(pb);
|
||||
get_le32(pb);
|
||||
st->id = get_le16(pb) & 0x7f; /* stream id */
|
||||
// mapping of asf ID to AV stream ID;
|
||||
asf->asfid2avid[st->id] = s->nb_streams - 1;
|
||||
|
||||
get_le32(pb);
|
||||
|
||||
if (test_for_ext_stream_audio) {
|
||||
ff_get_guid(pb, &g);
|
||||
if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) {
|
||||
type = AVMEDIA_TYPE_AUDIO;
|
||||
is_dvr_ms_audio=1;
|
||||
ff_get_guid(pb, &g);
|
||||
get_le32(pb);
|
||||
get_le32(pb);
|
||||
get_le32(pb);
|
||||
ff_get_guid(pb, &g);
|
||||
get_le32(pb);
|
||||
}
|
||||
}
|
||||
|
||||
st->codec->codec_type = type;
|
||||
if (type == AVMEDIA_TYPE_AUDIO) {
|
||||
ff_get_wav_header(pb, st->codec, type_specific_size);
|
||||
if (is_dvr_ms_audio) {
|
||||
// codec_id and codec_tag are unreliable in dvr_ms
|
||||
// files. Set them later by probing stream.
|
||||
st->codec->codec_id = CODEC_ID_PROBE;
|
||||
st->codec->codec_tag = 0;
|
||||
}
|
||||
if (st->codec->codec_id == CODEC_ID_AAC) {
|
||||
st->need_parsing = AVSTREAM_PARSE_NONE;
|
||||
} else {
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
}
|
||||
/* We have to init the frame size at some point .... */
|
||||
pos2 = url_ftell(pb);
|
||||
if (size >= (pos2 + 8 - pos1 + 24)) {
|
||||
asf_st->ds_span = get_byte(pb);
|
||||
asf_st->ds_packet_size = get_le16(pb);
|
||||
asf_st->ds_chunk_size = get_le16(pb);
|
||||
get_le16(pb); //ds_data_size
|
||||
get_byte(pb); //ds_silence_data
|
||||
}
|
||||
//printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n",
|
||||
// asf_st->ds_packet_size, asf_st->ds_chunk_size,
|
||||
// asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data);
|
||||
if (asf_st->ds_span > 1) {
|
||||
if (!asf_st->ds_chunk_size
|
||||
|| (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)
|
||||
|| asf_st->ds_packet_size % asf_st->ds_chunk_size)
|
||||
asf_st->ds_span = 0; // disable descrambling
|
||||
}
|
||||
switch (st->codec->codec_id) {
|
||||
case CODEC_ID_MP3:
|
||||
st->codec->frame_size = MPA_FRAME_SIZE;
|
||||
break;
|
||||
case CODEC_ID_PCM_S16LE:
|
||||
case CODEC_ID_PCM_S16BE:
|
||||
case CODEC_ID_PCM_U16LE:
|
||||
case CODEC_ID_PCM_U16BE:
|
||||
case CODEC_ID_PCM_S8:
|
||||
case CODEC_ID_PCM_U8:
|
||||
case CODEC_ID_PCM_ALAW:
|
||||
case CODEC_ID_PCM_MULAW:
|
||||
st->codec->frame_size = 1;
|
||||
break;
|
||||
default:
|
||||
/* This is probably wrong, but it prevents a crash later */
|
||||
st->codec->frame_size = 1;
|
||||
break;
|
||||
}
|
||||
} else if (type == AVMEDIA_TYPE_VIDEO &&
|
||||
size - (url_ftell(pb) - pos1 + 24) >= 51) {
|
||||
get_le32(pb);
|
||||
get_le32(pb);
|
||||
get_byte(pb);
|
||||
get_le16(pb); /* size */
|
||||
sizeX= get_le32(pb); /* size */
|
||||
st->codec->width = get_le32(pb);
|
||||
st->codec->height = get_le32(pb);
|
||||
/* not available for asf */
|
||||
get_le16(pb); /* panes */
|
||||
st->codec->bits_per_coded_sample = get_le16(pb); /* depth */
|
||||
tag1 = get_le32(pb);
|
||||
url_fskip(pb, 20);
|
||||
// av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX);
|
||||
if (sizeX > 40) {
|
||||
st->codec->extradata_size = sizeX - 40;
|
||||
st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
|
||||
}
|
||||
|
||||
/* Extract palette from extradata if bpp <= 8 */
|
||||
/* This code assumes that extradata contains only palette */
|
||||
/* This is true for all paletted codecs implemented in ffmpeg */
|
||||
if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
|
||||
st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
|
||||
#if HAVE_BIGENDIAN
|
||||
for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
|
||||
st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]);
|
||||
#else
|
||||
memcpy(st->codec->palctrl->palette, st->codec->extradata,
|
||||
FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
|
||||
#endif
|
||||
st->codec->palctrl->palette_changed = 1;
|
||||
}
|
||||
|
||||
st->codec->codec_tag = tag1;
|
||||
st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
|
||||
if(tag1 == MKTAG('D', 'V', 'R', ' ')){
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
// issue658 containse wrong w/h and MS even puts a fake seq header with wrong w/h in extradata while a correct one is in te stream. maximum lameness
|
||||
st->codec->width =
|
||||
st->codec->height = 0;
|
||||
av_freep(&st->codec->extradata);
|
||||
st->codec->extradata_size=0;
|
||||
}
|
||||
if(st->codec->codec_id == CODEC_ID_H264)
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
|
||||
}
|
||||
pos2 = url_ftell(pb);
|
||||
url_fskip(pb, size - (pos2 - pos1 + 24));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size)
|
||||
{
|
||||
ASFContext *asf = s->priv_data;
|
||||
@ -396,8 +581,6 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
ASFContext *asf = s->priv_data;
|
||||
ff_asf_guid g;
|
||||
ByteIOContext *pb = s->pb;
|
||||
AVStream *st;
|
||||
ASFStream *asf_st;
|
||||
int i;
|
||||
int64_t gsize;
|
||||
|
||||
@ -431,180 +614,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
if (!ff_guidcmp(&g, &ff_asf_file_header)) {
|
||||
asf_read_file_properties(s, gsize);
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_stream_header)) {
|
||||
enum AVMediaType type;
|
||||
int type_specific_size, sizeX;
|
||||
uint64_t total_size;
|
||||
unsigned int tag1;
|
||||
int64_t pos1, pos2, start_time;
|
||||
int test_for_ext_stream_audio, is_dvr_ms_audio=0;
|
||||
|
||||
if (s->nb_streams == ASF_MAX_STREAMS) {
|
||||
av_log(s, AV_LOG_ERROR, "too many streams\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
pos1 = url_ftell(pb);
|
||||
|
||||
st = av_new_stream(s, 0);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
|
||||
asf_st = av_mallocz(sizeof(ASFStream));
|
||||
if (!asf_st)
|
||||
return AVERROR(ENOMEM);
|
||||
st->priv_data = asf_st;
|
||||
start_time = asf->hdr.preroll;
|
||||
|
||||
asf_st->stream_language_index = 128; // invalid stream index means no language info
|
||||
|
||||
if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
|
||||
st->duration = asf->hdr.play_time /
|
||||
(10000000 / 1000) - start_time;
|
||||
}
|
||||
ff_get_guid(pb, &g);
|
||||
|
||||
test_for_ext_stream_audio = 0;
|
||||
if (!ff_guidcmp(&g, &ff_asf_audio_stream)) {
|
||||
type = AVMEDIA_TYPE_AUDIO;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_video_stream)) {
|
||||
type = AVMEDIA_TYPE_VIDEO;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) {
|
||||
type = AVMEDIA_TYPE_VIDEO;
|
||||
st->codec->codec_id = CODEC_ID_MJPEG;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_command_stream)) {
|
||||
type = AVMEDIA_TYPE_DATA;
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) {
|
||||
test_for_ext_stream_audio = 1;
|
||||
type = AVMEDIA_TYPE_UNKNOWN;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
ff_get_guid(pb, &g);
|
||||
total_size = get_le64(pb);
|
||||
type_specific_size = get_le32(pb);
|
||||
get_le32(pb);
|
||||
st->id = get_le16(pb) & 0x7f; /* stream id */
|
||||
// mapping of asf ID to AV stream ID;
|
||||
asf->asfid2avid[st->id] = s->nb_streams - 1;
|
||||
|
||||
get_le32(pb);
|
||||
|
||||
if (test_for_ext_stream_audio) {
|
||||
ff_get_guid(pb, &g);
|
||||
if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) {
|
||||
type = AVMEDIA_TYPE_AUDIO;
|
||||
is_dvr_ms_audio=1;
|
||||
ff_get_guid(pb, &g);
|
||||
get_le32(pb);
|
||||
get_le32(pb);
|
||||
get_le32(pb);
|
||||
ff_get_guid(pb, &g);
|
||||
get_le32(pb);
|
||||
}
|
||||
}
|
||||
|
||||
st->codec->codec_type = type;
|
||||
if (type == AVMEDIA_TYPE_AUDIO) {
|
||||
ff_get_wav_header(pb, st->codec, type_specific_size);
|
||||
if (is_dvr_ms_audio) {
|
||||
// codec_id and codec_tag are unreliable in dvr_ms
|
||||
// files. Set them later by probing stream.
|
||||
st->codec->codec_id = CODEC_ID_PROBE;
|
||||
st->codec->codec_tag = 0;
|
||||
}
|
||||
if (st->codec->codec_id == CODEC_ID_AAC) {
|
||||
st->need_parsing = AVSTREAM_PARSE_NONE;
|
||||
} else {
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
}
|
||||
/* We have to init the frame size at some point .... */
|
||||
pos2 = url_ftell(pb);
|
||||
if (gsize >= (pos2 + 8 - pos1 + 24)) {
|
||||
asf_st->ds_span = get_byte(pb);
|
||||
asf_st->ds_packet_size = get_le16(pb);
|
||||
asf_st->ds_chunk_size = get_le16(pb);
|
||||
get_le16(pb); //ds_data_size
|
||||
get_byte(pb); //ds_silence_data
|
||||
}
|
||||
//printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n",
|
||||
// asf_st->ds_packet_size, asf_st->ds_chunk_size,
|
||||
// asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data);
|
||||
if (asf_st->ds_span > 1) {
|
||||
if (!asf_st->ds_chunk_size
|
||||
|| (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)
|
||||
|| asf_st->ds_packet_size % asf_st->ds_chunk_size)
|
||||
asf_st->ds_span = 0; // disable descrambling
|
||||
}
|
||||
switch (st->codec->codec_id) {
|
||||
case CODEC_ID_MP3:
|
||||
st->codec->frame_size = MPA_FRAME_SIZE;
|
||||
break;
|
||||
case CODEC_ID_PCM_S16LE:
|
||||
case CODEC_ID_PCM_S16BE:
|
||||
case CODEC_ID_PCM_U16LE:
|
||||
case CODEC_ID_PCM_U16BE:
|
||||
case CODEC_ID_PCM_S8:
|
||||
case CODEC_ID_PCM_U8:
|
||||
case CODEC_ID_PCM_ALAW:
|
||||
case CODEC_ID_PCM_MULAW:
|
||||
st->codec->frame_size = 1;
|
||||
break;
|
||||
default:
|
||||
/* This is probably wrong, but it prevents a crash later */
|
||||
st->codec->frame_size = 1;
|
||||
break;
|
||||
}
|
||||
} else if (type == AVMEDIA_TYPE_VIDEO &&
|
||||
gsize - (url_ftell(pb) - pos1 + 24) >= 51) {
|
||||
get_le32(pb);
|
||||
get_le32(pb);
|
||||
get_byte(pb);
|
||||
get_le16(pb); /* size */
|
||||
sizeX= get_le32(pb); /* size */
|
||||
st->codec->width = get_le32(pb);
|
||||
st->codec->height = get_le32(pb);
|
||||
/* not available for asf */
|
||||
get_le16(pb); /* panes */
|
||||
st->codec->bits_per_coded_sample = get_le16(pb); /* depth */
|
||||
tag1 = get_le32(pb);
|
||||
url_fskip(pb, 20);
|
||||
// av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX);
|
||||
if (sizeX > 40) {
|
||||
st->codec->extradata_size = sizeX - 40;
|
||||
st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
|
||||
}
|
||||
|
||||
/* Extract palette from extradata if bpp <= 8 */
|
||||
/* This code assumes that extradata contains only palette */
|
||||
/* This is true for all paletted codecs implemented in ffmpeg */
|
||||
if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
|
||||
st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
|
||||
#if HAVE_BIGENDIAN
|
||||
for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
|
||||
st->codec->palctrl->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]);
|
||||
#else
|
||||
memcpy(st->codec->palctrl->palette, st->codec->extradata,
|
||||
FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
|
||||
#endif
|
||||
st->codec->palctrl->palette_changed = 1;
|
||||
}
|
||||
|
||||
st->codec->codec_tag = tag1;
|
||||
st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
|
||||
if(tag1 == MKTAG('D', 'V', 'R', ' ')){
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
// issue658 containse wrong w/h and MS even puts a fake seq header with wrong w/h in extradata while a correct one is in te stream. maximum lameness
|
||||
st->codec->width =
|
||||
st->codec->height = 0;
|
||||
av_freep(&st->codec->extradata);
|
||||
st->codec->extradata_size=0;
|
||||
}
|
||||
if(st->codec->codec_id == CODEC_ID_H264)
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
|
||||
}
|
||||
pos2 = url_ftell(pb);
|
||||
url_fskip(pb, gsize - (pos2 - pos1 + 24));
|
||||
asf_read_stream_properties(s, gsize);
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_comment_header)) {
|
||||
asf_read_content_desc(s, gsize);
|
||||
} else if (!ff_guidcmp(&g, &ff_asf_language_guid)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user