fprintf(stderr,_("%s err: %s\n"),msg, errmsg);
}
-FFPacket::FFPacket()
-{
- init();
-}
-
-FFPacket::~FFPacket()
-{
- av_packet_unref(&pkt);
-}
-
void FFPacket::init()
{
av_init_packet(&pkt);
pkt.data = 0; pkt.size = 0;
}
+void FFPacket::finit()
+{
+ av_packet_unref(&pkt);
+}
FFrame::FFrame(FFStream *fst)
{
if( ipkt->stream_index == st->index ) {
while( (ipkt->size > 0 || !ipkt->data) && !got_frame ) {
ret = decode_frame(ipkt, frame, got_frame);
+ if( ret < 0 ) need_packet = 1;
if( ret <= 0 || !ipkt->data ) break;
ipkt->data += ret;
ipkt->size -= ret;
int FFStream::seek(int64_t no, double rate)
{
- if( no < 0 ) no = 0;
+ int64_t tstmp = -INT64_MAX+1;
// default ffmpeg native seek
int npkts = 1;
int64_t pos = no, plmt = -1;
if( no-n < 30*rate ) {
if( n < 0 ) n = 0;
pos = n;
- if( ++i < marks.size() ) plmt = marks[i].pos;
+ if( i < marks.size() ) plmt = marks[i].pos;
npkts = MAX_RETRY;
}
}
- double secs = pos / rate;
- int64_t pkt_ts, tstmp = secs * st->time_base.den / st->time_base.num;
- if( nudge != AV_NOPTS_VALUE ) tstmp += nudge;
+ if( pos > 0 ) {
+ double secs = pos / rate;
+ tstmp = secs * st->time_base.den / st->time_base.num;
+ if( nudge != AV_NOPTS_VALUE ) tstmp += nudge;
+ }
int ret = avformat_seek_file(fmt_ctx, st->index,
-INT64_MAX, tstmp, INT64_MAX, AVSEEK_FLAG_ANY);
if( ret >= 0 ) {
avcodec_flush_buffers(st->codec);
+ ipkt.finit(); ipkt.init();
need_packet = 0; flushed = 0;
seeked = 1; st_eof(0);
// read up to retry packets, limited to npkts in stream, and not past pkt.pos plmt
- for( int retry=MAX_RETRY; ret>=0 && --retry>=0; ) {
+ for(;;) {
if( read_packet() <= 0 ) { ret = -1; break; }
if( plmt >= 0 && ipkt->pos >= plmt ) break;
if( ipkt->stream_index != st->index ) continue;
if( --npkts <= 0 ) break;
- if( (pkt_ts=ipkt->dts) == AV_NOPTS_VALUE &&
- (pkt_ts=ipkt->pts) == AV_NOPTS_VALUE ) continue;
+ int64_t pkt_ts = ipkt->dts != AV_NOPTS_VALUE ? ipkt->dts : ipkt->pts;
+ if( pkt_ts == AV_NOPTS_VALUE ) continue;
if( pkt_ts >= tstmp ) break;
}
}
void FFAudioStream::load_markers()
{
IndexState *index_state = ffmpeg->file_base->asset->index_state;
+ if( index_state->marker_status == MARKERS_NOTTESTED ) return;
if( !index_state || idx >= index_state->audio_markers.size() ) return;
FFStream::load_markers(*index_state->audio_markers[idx], sample_rate);
}
ff_err(ret, "FFVideoStream::decode_frame: Could not read video frame\n");
return -1;
}
+ else // this is right out of ffplay, looks questionable ???
+ ret = pkt->size;
+
if( got_frame ) {
int64_t pkt_ts = av_frame_get_best_effort_timestamp(frame);
if( pkt_ts != AV_NOPTS_VALUE )
set_option_path(path, "%s/%s", type, spec);
}
-int FFMPEG::get_format(char *format, const char *path, char *spec)
+int FFMPEG::get_format(char *format, const char *path, const char *spec)
{
char option_path[BCTEXTLEN], line[BCTEXTLEN], codec[BCTEXTLEN];
get_option_path(option_path, path, spec);
return ret;
}
+int FFMPEG::get_codec(char *codec, const char *path, const char *spec)
+{
+ char option_path[BCTEXTLEN], line[BCTEXTLEN], format[BCTEXTLEN];
+ get_option_path(option_path, path, spec);
+ FILE *fp = fopen(option_path,"r");
+ if( !fp ) return 1;
+ int ret = 0;
+ if( !fgets(line, sizeof(line), fp) ) ret = 1;
+ if( !ret ) {
+ line[sizeof(line)-1] = 0;
+ ret = scan_option_line(line, format, codec);
+ }
+ fclose(fp);
+ return ret;
+}
+
int FFMPEG::get_file_format()
{
int ret = 0;
return 0;
}
+int FFMPEG::load_defaults(const char *path, const char *type,
+ char *codec, char *codec_options, int len)
+{
+ char default_file[BCTEXTLEN];
+ FFMPEG::set_option_path(default_file, "%s/%s.dfl", path, type);
+ FILE *fp = fopen(default_file,"r");
+ if( !fp ) return 1;
+ fgets(codec, BCSTRLEN, fp);
+ char *cp = codec;
+ while( *cp && *cp!='\n' ) ++cp;
+ *cp = 0;
+ while( len > 0 && fgets(codec_options, len, fp) ) {
+ int n = strlen(codec_options);
+ codec_options += n; len -= n;
+ }
+ fclose(fp);
+ FFMPEG::set_option_path(default_file, "%s/%s", path, codec);
+ return FFMPEG::load_options(default_file, codec_options, len);
+}
+
+void FFMPEG::set_asset_format(Asset *asset, const char *text)
+{
+ if( asset->format != FILE_FFMPEG ) return;
+ strcpy(asset->fformat, text);
+ if( !asset->ff_audio_options[0] ) {
+ asset->audio_data = !load_defaults("audio", text, asset->acodec,
+ asset->ff_audio_options, sizeof(asset->ff_audio_options));
+ }
+ if( !asset->ff_video_options[0] ) {
+ asset->video_data = !load_defaults("video", text, asset->vcodec,
+ asset->ff_video_options, sizeof(asset->ff_video_options));
+ }
+}
+
int FFMPEG::get_encoder(const char *options,
char *format, char *codec, char *bsfilter, char *bsargs)
{
if( running() ) {
done = 1;
mux_lock->unlock();
- join();
}
+ join();
}
void FFMPEG::flow_off()
int got_frame = 0;
int ret = aud->decode_frame(&pkt, frame, got_frame);
if( ret <= 0 ) break;
- if( got_frame ) {
+ if( got_frame && frame->channels == nch ) {
float *samples;
int len = aud->get_samples(samples,
&frame->extended_data[0], frame->nb_samples);