return 1;
pos = url_ftell(s->pb);
if (!ffm->write_index) {
- if (pos == ffm->file_size);
+ if (pos == ffm->file_size)
return AVERROR_EOF;
avail_size = ffm->file_size - pos;
} else {
return AVERROR(EAGAIN);
}
+static int ffm_resync(AVFormatContext *s, int state)
+{
+ av_log(s, AV_LOG_ERROR, "resyncing\n");
+ while (state != PACKET_ID) {
+ if (url_feof(s->pb)) {
+ av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n");
+ return -1;
+ }
+ state = (state << 8) | get_byte(s->pb);
+ }
+ return 0;
+}
+
/* first is true if we read the frame header */
static int ffm_read_data(AVFormatContext *s,
uint8_t *buf, int size, int header)
{
FFMContext *ffm = s->priv_data;
ByteIOContext *pb = s->pb;
- int len, fill_size, size1, frame_offset;
+ int len, fill_size, size1, frame_offset, id;
size1 = size;
while (size > 0) {
if (url_ftell(pb) == ffm->file_size)
url_fseek(pb, ffm->packet_size, SEEK_SET);
retry_read:
- get_be16(pb); /* PACKET_ID */
+ id = get_be16(pb); /* PACKET_ID */
+ if (id != PACKET_ID)
+ if (ffm_resync(s, id) < 0)
+ return -1;
fill_size = get_be16(pb);
ffm->dts = get_be64(pb);
frame_offset = get_be16(pb);
//#define DEBUG_SEEK
-/* pos is between 0 and file_size - FFM_PACKET_SIZE. It is translated
- by the write position inside this function */
+/* ensure that acutal seeking happens between FFM_PACKET_SIZE
+ and file_size - FFM_PACKET_SIZE */
static void ffm_seek1(AVFormatContext *s, int64_t pos1)
{
FFMContext *ffm = s->priv_data;
ByteIOContext *pb = s->pb;
int64_t pos;
- pos = pos1 + ffm->write_index;
- if (pos >= ffm->file_size)
- pos -= (ffm->file_size - FFM_PACKET_SIZE);
+ pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE);
+ pos = FFMAX(pos, FFM_PACKET_SIZE);
#ifdef DEBUG_SEEK
av_log(s, AV_LOG_DEBUG, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos);
#endif
url_fskip(pb, 4);
dts = get_be64(pb);
#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "pts=%0.6f\n", pts / 1000000.0);
+ av_log(s, AV_LOG_DEBUG, "dts=%0.6f\n", dts / 1000000.0);
#endif
return dts;
}
st = av_new_stream(s, 0);
if (!st)
goto fail;
- s->streams[i] = st;
av_set_pts_info(st, 64, 1, 1000000);
codec->rc_buffer_aggressivity = av_int2dbl(get_be64(pb));
codec->codec_tag = get_be32(pb);
codec->thread_count = get_byte(pb);
+ codec->coder_type = get_be32(pb);
+ codec->me_cmp = get_be32(pb);
+ codec->partitions = get_be32(pb);
+ codec->me_subpel_quality = get_be32(pb);
+ codec->me_range = get_be32(pb);
+ codec->keyint_min = get_be32(pb);
+ codec->scenechange_threshold = get_be32(pb);
+ codec->b_frame_strategy = get_be32(pb);
+ codec->qcompress = av_int2dbl(get_be64(pb));
+ codec->qblur = av_int2dbl(get_be64(pb));
+ codec->max_qdiff = get_be32(pb);
+ codec->refs = get_be32(pb);
+ codec->directpred = get_be32(pb);
break;
case CODEC_TYPE_AUDIO:
codec->sample_rate = get_be32(pb);
codec->channels = get_le16(pb);
codec->frame_size = get_le16(pb);
+ codec->sample_fmt = get_le16(pb);
break;
default:
goto fail;
#endif
/* find the position using linear interpolation (better than
dichotomy in typical cases) */
- pos_min = 0;
- pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE;
+ pos_min = FFM_PACKET_SIZE;
+ pos_max = ffm->file_size - FFM_PACKET_SIZE;
while (pos_min <= pos_max) {
pts_min = get_dts(s, pos_min);
pts_max = get_dts(s, pos_max);
}
}
pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
- if (pos > 0)
- pos -= FFM_PACKET_SIZE;
+
found:
ffm_seek1(s, pos);