}
while( ret >= 0 && st != 0 && !reading ) {
AVCodecID codec_id = st->codecpar->codec_id;
- AVCodec *decoder = avcodec_find_decoder(codec_id);
+ AVCodec *decoder = 0;
+ if( is_video() ) {
+ if( ffmpeg->opt_video_decoder )
+ decoder = avcodec_find_decoder_by_name(ffmpeg->opt_video_decoder);
+ else
+ ffmpeg->video_codec_remaps.update(codec_id, decoder);
+ }
+ else if( is_audio() ) {
+ if( ffmpeg->opt_audio_decoder )
+ decoder = avcodec_find_decoder_by_name(ffmpeg->opt_audio_decoder);
+ else
+ ffmpeg->audio_codec_remaps.update(codec_id, decoder);
+ }
+ if( !decoder )
+ decoder = avcodec_find_decoder(codec_id);
avctx = avcodec_alloc_context3(decoder);
if( !avctx ) {
eprintf(_("cant allocate codec context\n"));
AVPacket *pkt = ret > 0 ? (AVPacket*)ipkt : 0;
if( pkt ) {
if( pkt->stream_index != st->index ) continue;
- if( !pkt->data | !pkt->size ) continue;
+ if( !pkt->data || !pkt->size ) continue;
}
if( (ret=avcodec_send_packet(avctx, pkt)) < 0 ) {
ff_err(ret, "FFStream::decode: avcodec_send_packet failed.\nfile:%s\n",
frame->best_effort_timestamp = AV_NOPTS_VALUE;
int ret = avcodec_receive_frame(avctx, frame);
if( ret < 0 ) {
- if( first_frame || ret == AVERROR(EAGAIN) ) return 0;
+ if( first_frame ) return 0;
+ if( ret == AVERROR(EAGAIN) ) return 0;
if( ret == AVERROR_EOF ) { st_eof(1); return 0; }
ff_err(ret, "FFAudioStream::decode_frame: Could not read audio frame.\nfile:%s\n",
ffmpeg->fmt_ctx->url);
int first_frame = seeked; seeked = 0;
int ret = avcodec_receive_frame(avctx, frame);
if( ret < 0 ) {
- if( first_frame || ret == AVERROR(EAGAIN) ) return 0;
+ if( first_frame ) return 0;
if( ret == AVERROR(EAGAIN) ) return 0;
if( ret == AVERROR_EOF ) { st_eof(1); return 0; }
ff_err(ret, "FFVideoStream::decode_frame: Could not read video frame.\nfile:%s\n,",
frame->interlaced_frame = interlaced;
frame->top_field_first = top_field_first;
}
+ if( frame && frame->format == AV_PIX_FMT_VAAPI ) { // ugly
+ int ret = avcodec_send_frame(avctx, frame);
+ for( int retry=MAX_RETRY; !ret && --retry>=0; ) {
+ FFPacket pkt; av_init_packet(pkt);
+ pkt->data = NULL; pkt->size = 0;
+ if( (ret=avcodec_receive_packet(avctx, pkt)) < 0 ) {
+ if( ret == AVERROR(EAGAIN) ) ret = 0; // weird
+ break;
+ }
+ ret = write_packet(pkt);
+ pkt->stream_index = 0;
+ av_packet_unref(pkt);
+ }
+ if( ret < 0 ) {
+ ff_err(ret, "FFStream::encode_frame: vaapi encode failed.\nfile: %s\n",
+ ffmpeg->fmt_ctx->url);
+ return -1;
+ }
+ return 0;
+ }
return FFStream::encode_frame(frame);
}
opt_video_filter = 0;
opt_audio_filter = 0;
opt_hw_dev = 0;
+ opt_video_decoder = 0;
+ opt_audio_decoder = 0;
fflags = 0;
char option_path[BCTEXTLEN];
set_option_path(option_path, "%s", "ffmpeg.opts");
return ret;
}
+FFCodecRemap::FFCodecRemap()
+{
+ old_codec = 0;
+ new_codec = 0;
+}
+FFCodecRemap::~FFCodecRemap()
+{
+ delete [] old_codec;
+ delete [] new_codec;
+}
+
+int FFCodecRemaps::add(const char *val)
+{
+ char old_codec[BCSTRLEN], new_codec[BCSTRLEN];
+ if( sscanf(val, " %63[a-zA-z0-9_-] = %63[a-z0-9_-]",
+ &old_codec[0], &new_codec[0]) != 2 ) return 1;
+ FFCodecRemap &remap = append();
+ remap.old_codec = cstrdup(old_codec);
+ remap.new_codec = cstrdup(new_codec);
+ return 0;
+}
+
+
+int FFCodecRemaps::update(AVCodecID &codec_id, AVCodec *&decoder)
+{
+ AVCodec *codec = avcodec_find_decoder(codec_id);
+ if( !codec ) return -1;
+ const char *name = codec->name;
+ FFCodecRemaps &map = *this;
+ int k = map.size();
+ while( --k >= 0 && strcmp(map[k].old_codec, name) );
+ if( k < 0 ) return 1;
+ const char *new_codec = map[k].new_codec;
+ codec = avcodec_find_decoder_by_name(new_codec);
+ if( !codec ) return -1;
+ decoder = codec;
+ return 0;
+}
+
int FFMPEG::read_options(FILE *fp, const char *options, AVDictionary *&opts)
{
int ret = 0, no = 0;
if( !ret ) {
if( !strcmp(key, "duration") )
opt_duration = strtod(val, 0);
+ else if( !strcmp(key, "video_decoder") )
+ opt_video_decoder = cstrdup(val);
+ else if( !strcmp(key, "audio_decoder") )
+ opt_audio_decoder = cstrdup(val);
+ else if( !strcmp(key, "remap_video_decoder") )
+ video_codec_remaps.add(val);
+ else if( !strcmp(key, "remap_audio_decoder") )
+ audio_codec_remaps.add(val);
else if( !strcmp(key, "video_filter") )
opt_video_filter = cstrdup(val);
else if( !strcmp(key, "audio_filter") )
vid->height = asset->height;
vid->frame_rate = asset->frame_rate;
- AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
+ AVPixelFormat pix_fmt = av_get_pix_fmt(asset->ff_pixel_format);
if( opt_hw_dev != 0 ) {
AVHWDeviceType hw_type = vid->encode_hw_activate(opt_hw_dev);
switch( hw_type ) {
pix_fmt = AV_PIX_FMT_VAAPI;
break;
case AV_HWDEVICE_TYPE_NONE:
- default:
- pix_fmt = av_get_pix_fmt(asset->ff_pixel_format);
- break;
+ default: break;
}
}
if( pix_fmt == AV_PIX_FMT_NONE )