#include "mpegaudio.h"
#include "asf.h"
#include "common.h"
+#include "asfcrypt.h"
#undef NDEBUG
#include <assert.h>
int type, type_specific_size, sizeX;
uint64_t total_size;
unsigned int tag1;
- int64_t pos1, pos2;
+ int64_t pos1, pos2, start_time;
int test_for_ext_stream_audio, is_dvr_ms_audio=0;
pos1 = url_ftell(pb);
if (!asf_st)
goto fail;
st->priv_data = asf_st;
- st->start_time = asf->hdr.preroll;
+ start_time = asf->hdr.preroll;
+
if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
st->duration = asf->hdr.send_time /
- (10000000 / 1000) - st->start_time;
+ (10000000 / 1000) - start_time;
}
get_guid(pb, &g);
bitrate= get_le32(pb);
stream_id= (flags & 0x7f);
// av_log(NULL, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate);
- asf->stream_bitrates[stream_id-1]= bitrate;
+ asf->stream_bitrates[stream_id]= bitrate;
}
} else if (!memcmp(&g, &extended_content_header, sizeof(GUID))) {
int desc_count, i;
{
if (!strcmp(name,"WM/AlbumTitle")) get_str16_nolen(pb, value_len, s->album, sizeof(s->album));
else if(!strcmp(name,"WM/Genre" )) get_str16_nolen(pb, value_len, s->genre, sizeof(s->genre));
- else if(!strcmp(name,"WM/Track")) {
+ else if(!strcmp(name,"WM/Track") && s->track == 0) {
char track[8];
get_str16_nolen(pb, value_len, track, sizeof(track));
s->track = strtol(track, NULL, 10) + 1;
if ((value_type >= 2) && (value_type <= 5)) // boolean or DWORD or QWORD or WORD
{
value_num= get_value(pb, value_type);
- if (!strcmp(name,"WM/Track" )) s->track = value_num + 1;
+ if (!strcmp(name,"WM/Track" ) && s->track == 0) s->track = value_num + 1;
if (!strcmp(name,"WM/TrackNumber")) s->track = value_num;
}
}
asf->packet_multi_size -= asf->packet_obj_size;
//printf("COMPRESS size %d %d %d ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size);
}
+ if( /*asf->packet_frag_size == asf->packet_obj_size*/
+ asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size
+ && asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size){
+ av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n",
+ asf_st->frag_offset, asf->packet_frag_size,
+ asf->packet_obj_size, asf_st->pkt.size);
+ asf->packet_obj_size= asf_st->pkt.size;
+ }
+
if ( asf_st->pkt.size != asf->packet_obj_size
|| asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) { //FIXME is this condition sufficient?
if(asf_st->pkt.data){
get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset,
asf->packet_frag_size);
+ if (s->key && s->keylen == 20)
+ ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,
+ asf->packet_frag_size);
asf_st->frag_offset += asf->packet_frag_size;
/* test if whole packet is read */
if (asf_st->frag_offset == asf_st->pkt.size) {
+ //workaround for macroshit radio DVR-MS files
+ if( s->streams[asf->stream_index]->codec->codec_id == CODEC_ID_MPEG2VIDEO
+ && asf_st->pkt.size > 100){
+ int i;
+ for(i=0; i<asf_st->pkt.size && !asf_st->pkt.data[i]; i++);
+ if(i == asf_st->pkt.size){
+ av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");
+ asf_st->frag_offset = 0;
+ av_free_packet(&asf_st->pkt);
+ continue;
+ }
+ }
+
/* return packet */
if (asf_st->ds_span > 1) {
if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span){
- av_log(s, AV_LOG_ERROR, "pkt.size != ds_packet_size * ds_span\n");
+ av_log(s, AV_LOG_ERROR, "pkt.size != ds_packet_size * ds_span (%d %d %d)\n", asf_st->pkt.size, asf_st->ds_packet_size, asf_st->ds_span);
}else{
/* packet descrambling */
uint8_t *newdata = av_malloc(asf_st->pkt.size);
return 0;
}
-static int asf_read_close(AVFormatContext *s)
-{
- int i;
-
- for(i=0;i<s->nb_streams;i++) {
- AVStream *st = s->streams[i];
- av_free(st->priv_data);
- av_free(st->codec->palctrl);
- }
- return 0;
-}
-
// Added to support seeking after packets have been read
// If information is not reset, read_packet fails due to
// leftover information from previous reads
asf->asf_st= NULL;
}
+static int asf_read_close(AVFormatContext *s)
+{
+ int i;
+
+ asf_reset_header(s);
+ for(i=0;i<s->nb_streams;i++) {
+ AVStream *st = s->streams[i];
+ av_free(st->priv_data);
+ av_free(st->codec->palctrl);
+ }
+ return 0;
+}
+
static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
{
ASFContext *asf = s->priv_data;