clean out old hwdecode stuff. refactor common code out

This commit is contained in:
Isaac Connor
2019-06-25 14:11:59 -04:00
parent bfb7238edb
commit 2cbcaeebbc
4 changed files with 161 additions and 412 deletions

View File

@@ -20,18 +20,18 @@ FFmpeg_Input::~FFmpeg_Input() {
}
}
int FFmpeg_Input::Open( const char *filepath ) {
int FFmpeg_Input::Open(const char *filepath) {
int error;
/** Open the input file to read from it. */
if ( (error = avformat_open_input( &input_format_context, filepath, NULL, NULL)) < 0 ) {
error = avformat_open_input(&input_format_context, filepath, NULL, NULL);
if ( error < 0 ) {
Error("Could not open input file '%s' (error '%s')\n",
filepath, av_make_error_string(error).c_str() );
input_format_context = NULL;
return error;
}
}
/** Get information on the input file (number of streams etc.). */
if ( (error = avformat_find_stream_info(input_format_context, NULL)) < 0 ) {
@@ -44,23 +44,23 @@ int FFmpeg_Input::Open( const char *filepath ) {
}
streams = new stream[input_format_context->nb_streams];
Debug(2,"Have %d streams", input_format_context->nb_streams);
Debug(2, "Have %d streams", input_format_context->nb_streams);
for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) {
if ( is_video_stream( input_format_context->streams[i] ) ) {
if ( is_video_stream(input_format_context->streams[i]) ) {
zm_dump_stream_format(input_format_context, i, 0, 0);
if ( video_stream_id == -1 ) {
video_stream_id = i;
// if we break, then we won't find the audio stream
} else {
Warning( "Have another video stream." );
Warning("Have another video stream.");
}
} else if ( is_audio_stream( input_format_context->streams[i] ) ) {
} else if ( is_audio_stream(input_format_context->streams[i]) ) {
if ( audio_stream_id == -1 ) {
Debug(2,"Audio stream is %d", i);
Debug(2, "Audio stream is %d", i);
audio_stream_id = i;
} else {
Warning( "Have another audio stream." );
Warning("Have another audio stream.");
}
} else {
Warning("Unknown stream type");
@@ -68,25 +68,26 @@ int FFmpeg_Input::Open( const char *filepath ) {
streams[i].frame_count = 0;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
streams[i].context = avcodec_alloc_context3( NULL );
avcodec_parameters_to_context( streams[i].context, input_format_context->streams[i]->codecpar );
streams[i].context = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(streams[i].context, input_format_context->streams[i]->codecpar);
#else
streams[i].context = input_format_context->streams[i]->codec;
#endif
if ( !(streams[i].codec = avcodec_find_decoder(streams[i].context->codec_id)) ) {
Error( "Could not find input codec\n");
Error("Could not find input codec");
avformat_close_input(&input_format_context);
return AVERROR_EXIT;
} else {
Debug(1, "Using codec (%s) for stream %d", streams[i].codec->name, i );
Debug(1, "Using codec (%s) for stream %d", streams[i].codec->name, i);
}
if ((error = avcodec_open2( streams[i].context, streams[i].codec, NULL)) < 0) {
Error( "Could not open input codec (error '%s')\n",
av_make_error_string(error).c_str() );
error = avcodec_open2(streams[i].context, streams[i].codec, NULL);
if ( error < 0 ) {
Error("Could not open input codec (error '%s')",
av_make_error_string(error).c_str());
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
avcodec_free_context( &streams[i].context );
avcodec_free_context(&streams[i].context);
#endif
avformat_close_input(&input_format_context);
return error;
@@ -94,14 +95,14 @@ int FFmpeg_Input::Open( const char *filepath ) {
} // end foreach stream
if ( video_stream_id == -1 )
Error( "Unable to locate video stream in %s", filepath );
Error("Unable to locate video stream in %s", filepath);
if ( audio_stream_id == -1 )
Debug( 3, "Unable to locate audio stream in %s", filepath );
Debug(3, "Unable to locate audio stream in %s", filepath);
return 0;
} // end int FFmpeg_Input::Open( const char * filepath )
AVFrame *FFmpeg_Input::get_frame( int stream_id ) {
AVFrame *FFmpeg_Input::get_frame(int stream_id) {
Debug(1, "Getting frame from stream %d", stream_id);
int frameComplete = false;
@@ -119,85 +120,38 @@ AVFrame *FFmpeg_Input::get_frame( int stream_id ) {
// Check for Connection failure.
(ret == -110)
) {
Info( "av_read_frame returned %s.", errbuf );
Info("av_read_frame returned %s.", errbuf);
return NULL;
}
Error( "Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, ret, errbuf );
Error("Unable to read packet from stream %d: error %d \"%s\".",
packet.stream_index, ret, errbuf);
return NULL;
}
dumpPacket(input_format_context->streams[packet.stream_index], &packet, "Received packet");
if ( (stream_id < 0) || (packet.stream_index == stream_id) ) {
Debug(3,"Packet is for our stream (%d)", packet.stream_index );
Debug(3, "Packet is for our stream (%d)", packet.stream_index);
AVCodecContext *context = streams[packet.stream_index].context;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
ret = avcodec_send_packet(context, &packet);
if ( ret < 0 ) {
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
Error("Unable to send packet at frame %d: %s, continuing",
streams[packet.stream_index].frame_count, errbuf);
zm_av_packet_unref(&packet);
continue;
}
#if HAVE_AVUTIL_HWCONTEXT_H
if ( hwaccel ) {
ret = avcodec_receive_frame( context, hwFrame );
if ( ret < 0 ) {
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
Error( "Unable to receive frame %d: %s, continuing", streams[packet.stream_index].frame_count, errbuf );
zm_av_packet_unref( &packet );
continue;
}
ret = av_hwframe_transfer_data(frame, hwFrame, 0);
if (ret < 0) {
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
Error( "Unable to transfer frame at frame %d: %s, continuing", streams[packet.stream_index].frame_count, errbuf );
zm_av_packet_unref(&packet);
continue;
}
} else {
#endif
if ( frame ) {
av_frame_free(&frame);
frame = zm_av_frame_alloc();
} else {
frame = zm_av_frame_alloc();
}
//Debug(1,"Getting frame %d", streams[packet.stream_index].frame_count);
ret = avcodec_receive_frame(context, frame);
ret = zm_receive_frame(context, frame, packet);
if ( ret < 0 ) {
av_strerror( ret, errbuf, AV_ERROR_MAX_STRING_SIZE );
Error( "Unable to send packet at frame %d: %s, continuing", streams[packet.stream_index].frame_count, errbuf );
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
Error("Unable to decode frame at frame %d: %s, continuing",
streams[packet.stream_index].frame_count, errbuf);
zm_av_packet_unref( &packet );
av_frame_free(&frame);
continue;
}
#if HAVE_AVUTIL_HWCONTEXT_H
}
#endif
frameComplete = 1;
# else
if ( frame ) {
av_frame_free(&frame);
frame = zm_av_frame_alloc();
} else {
frame = zm_av_frame_alloc();
}
ret = zm_avcodec_decode_video(context, frame, &frameComplete, &packet);
if ( ret < 0 ) {
av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);
Error( "Unable to decode frame at frame %d: %s, continuing", streams[packet.stream_index].frame_count, errbuf );
zm_av_packet_unref( &packet );
av_frame_free(&frame);
continue;
}
#endif
} // end if it's the right stream
frameComplete = 1;
} // end if it's the right stream
zm_av_packet_unref(&packet);
@@ -206,7 +160,7 @@ AVFrame *FFmpeg_Input::get_frame( int stream_id ) {
} // end AVFrame *FFmpeg_Input::get_frame
AVFrame *FFmpeg_Input::get_frame( int stream_id, double at ) {
AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
Debug(1, "Getting frame from stream %d at %f", stream_id, at);
int64_t seek_target = (int64_t)(at * AV_TIME_BASE);
@@ -218,9 +172,8 @@ AVFrame *FFmpeg_Input::get_frame( int stream_id, double at ) {
if ( !frame ) {
// Don't have a frame yet, so get a keyframe before the timestamp
if ( ( ret = av_seek_frame(
input_format_context, stream_id, seek_target, AVSEEK_FLAG_FRAME
) < 0 ) ) {
ret = av_seek_frame(input_format_context, stream_id, seek_target, AVSEEK_FLAG_FRAME);
if ( ret < 0 ) {
Error("Unable to seek in stream");
return NULL;
}
@@ -246,7 +199,7 @@ AVFrame *FFmpeg_Input::get_frame( int stream_id, double at ) {
if ( frame->pts <= seek_target ) {
zm_dump_frame(frame, "pts <= seek_target");
while ( frame && (frame->pts < seek_target) ) {
if ( ! get_frame(stream_id) )
if ( !get_frame(stream_id) )
return frame;
}
return frame;