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;
|
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)
|
static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size)
|
||||||
{
|
{
|
||||||
ASFContext *asf = s->priv_data;
|
ASFContext *asf = s->priv_data;
|
||||||
@ -396,8 +581,6 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
ASFContext *asf = s->priv_data;
|
ASFContext *asf = s->priv_data;
|
||||||
ff_asf_guid g;
|
ff_asf_guid g;
|
||||||
ByteIOContext *pb = s->pb;
|
ByteIOContext *pb = s->pb;
|
||||||
AVStream *st;
|
|
||||||
ASFStream *asf_st;
|
|
||||||
int i;
|
int i;
|
||||||
int64_t gsize;
|
int64_t gsize;
|
||||||
|
|
||||||
@ -431,180 +614,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
if (!ff_guidcmp(&g, &ff_asf_file_header)) {
|
if (!ff_guidcmp(&g, &ff_asf_file_header)) {
|
||||||
asf_read_file_properties(s, gsize);
|
asf_read_file_properties(s, gsize);
|
||||||
} else if (!ff_guidcmp(&g, &ff_asf_stream_header)) {
|
} else if (!ff_guidcmp(&g, &ff_asf_stream_header)) {
|
||||||
enum AVMediaType type;
|
asf_read_stream_properties(s, gsize);
|
||||||
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));
|
|
||||||
} else if (!ff_guidcmp(&g, &ff_asf_comment_header)) {
|
} else if (!ff_guidcmp(&g, &ff_asf_comment_header)) {
|
||||||
asf_read_content_desc(s, gsize);
|
asf_read_content_desc(s, gsize);
|
||||||
} else if (!ff_guidcmp(&g, &ff_asf_language_guid)) {
|
} else if (!ff_guidcmp(&g, &ff_asf_language_guid)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user