FFStream::~FFStream()
{
+ frm_lock->lock("FFStream::~FFStream");
if( reading > 0 || writing > 0 ) avcodec_close(avctx);
if( avctx ) avcodec_free_context(&avctx);
if( fmt_ctx ) avformat_close_input(&fmt_ctx);
if( frame ) av_frame_free(&frame);
if( fframe ) av_frame_free(&fframe);
if( probe_frame ) av_frame_free(&probe_frame);
+ frm_lock->unlock();
delete frm_lock;
if( stats_fp ) fclose(stats_fp);
if( stats_in ) av_freep(&stats_in);
}
if( ret >= 0 && hw_type != AV_HWDEVICE_TYPE_NONE ) {
ret = decode_hw_format(decoder, hw_type);
- if( !ret ) hw_type = AV_HWDEVICE_TYPE_NONE;
}
if( ret >= 0 ) {
avcodec_parameters_to_context(avctx, st->codecpar);
avctx->thread_count = ffmpeg->ff_cpus();
ret = avcodec_open2(avctx, decoder, &copts);
}
+ AVFrame *hw_frame = 0;
if( ret >= 0 && hw_type != AV_HWDEVICE_TYPE_NONE ) {
- AVFrame *frame = av_frame_alloc();
- if( !frame ) {
+ if( !(hw_frame=av_frame_alloc()) ) {
fprintf(stderr, "FFStream::decode_activate: av_frame_alloc failed\n");
ret = AVERROR(ENOMEM);
}
if( ret >= 0 )
- ret = decode(frame);
- if( ret < 0 || hw_pix_fmt == AV_PIX_FMT_NONE ) {
- ff_err(ret, "HW device init failed, using SW decode.\nfile:%s\n",
- ffmpeg->fmt_ctx->url);
- avcodec_close(avctx);
- avcodec_free_context(&avctx);
- av_buffer_unref(&hw_device_ctx);
- hw_device_ctx = 0;
- av_frame_free(&frame);
- hw_type = AV_HWDEVICE_TYPE_NONE;
- int flags = AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY;
- int idx = st->index;
- av_seek_frame(fmt_ctx, idx, INT64_MIN, flags);
- need_packet = 1; flushed = 0;
- seeked = 1; st_eof(0);
- ret = 0;
- continue;
- }
- probe_frame = frame;
+ ret = decode(hw_frame);
}
- if( ret >= 0 ) {
- reading = 1;
+ if( ret < 0 && hw_type != AV_HWDEVICE_TYPE_NONE ) {
+ ff_err(ret, "HW device init failed, using SW decode.\nfile:%s\n",
+ ffmpeg->fmt_ctx->url);
+ avcodec_close(avctx);
+ avcodec_free_context(&avctx);
+ av_buffer_unref(&hw_device_ctx);
+ hw_device_ctx = 0;
+ av_frame_free(&hw_frame);
+ hw_type = AV_HWDEVICE_TYPE_NONE;
+ int flags = AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY;
+ int idx = st->index;
+ av_seek_frame(fmt_ctx, idx, 0, flags);
+ need_packet = 1; flushed = 0;
+ seeked = 1; st_eof(0);
+ ret = 0;
+ continue;
}
+ probe_frame = hw_frame;
+ if( ret >= 0 )
+ reading = 1;
else
eprintf(_("open decoder failed\n"));
}
}
int ret = 0;
int retries = MAX_RETRY;
-
+ frm_lock->lock("FFStream::decode");
while( ret >= 0 && !flushed && --retries >= 0 ) {
if( need_packet ) {
if( (ret=read_packet()) < 0 ) break;
flushed = st_eof();
}
}
+ frm_lock->unlock();
if( retries < 0 ) {
fprintf(stderr, "FFStream::decode: Retry limit\n");
tstmp = av_rescale_q(tstmp, time_base, AV_TIME_BASE_Q);
idx = -1;
#endif
+ frm_lock->lock("FFStream::seek");
av_frame_free(&probe_frame);
avcodec_flush_buffers(avctx);
avformat_flush(fmt_ctx);
if( pkt_ts >= tstmp ) break;
}
if( retry < 0 ) {
- fprintf(stderr,"FFStream::seek: retry limit, pos=%jd tstmp=%jd\n",pos,tstmp);
+ ff_err(AVERROR(EIO), "FFStream::seek: %s\n"
+ " retry limit, pos=%jd tstmp=%jd, ",
+ ffmpeg->fmt_ctx->url, pos, tstmp);
ret = -1;
}
if( ret < 0 ) break;
break;
}
}
+ frm_lock->unlock();
if( ret < 0 ) {
printf("** seek fail %jd, %jd\n", pos, tstmp);
seeked = need_packet = 0;
if( !config ) {
fprintf(stderr, "Decoder %s does not support device type %s.\n",
decoder->name, av_hwdevice_get_type_name(type));
+ ret = -1;
break;
}
if( (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&
avctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
ret = 1;
}
- else
+ else {
ff_err(ret, "Failed HW device create.\ndev:%s\n",
av_hwdevice_get_type_name(type));
+ ret = -1;
+ }
}
return ret;
}
av_dict_copy(&copts, opts, 0);
AVStream *st = fmt_ctx->streams[i];
AVCodecID codec_id = st->codecpar->codec_id;
- AVCodec *decoder = avcodec_find_decoder(codec_id);
+ AVCodec *decoder = 0;
+ switch( st->codecpar->codec_type ) {
+ case AVMEDIA_TYPE_VIDEO:
+ if( opt_video_decoder )
+ decoder = avcodec_find_decoder_by_name(opt_video_decoder);
+ else
+ video_codec_remaps.update(codec_id, decoder);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if( opt_audio_decoder )
+ decoder = avcodec_find_decoder_by_name(opt_audio_decoder);
+ else
+ audio_codec_remaps.update(codec_id, decoder);
+ break;
+ default:
+ continue;
+ }
+ if( !decoder && !(decoder = avcodec_find_decoder(codec_id)) )
+ continue;
AVCodecContext *avctx = avcodec_alloc_context3(decoder);
if( !avctx ) {
eprintf(_("cant allocate codec context\n"));
if( vidx < 0 ) break;
FFVideoStream *vid = ffvideo[vidx];
if( !vid->avctx ) break;
- int64_t tstmp = pkt.dts;
- if( tstmp == AV_NOPTS_VALUE ) tstmp = pkt.pts;
+ int64_t tstmp = pkt.pts;
+ if( tstmp == AV_NOPTS_VALUE ) tstmp = pkt.dts;
if( tstmp != AV_NOPTS_VALUE && (pkt.flags & AV_PKT_FLAG_KEY) && pkt.pos > 0 ) {
if( vid->nudge != AV_NOPTS_VALUE ) tstmp -= vid->nudge;
double secs = to_secs(tstmp, st->time_base);