diff --git a/src/media_object.cpp b/src/media_object.cpp index 428cd3d..9737029 100644 --- a/src/media_object.cpp +++ b/src/media_object.cpp @@ -350,7 +350,7 @@ media_object::~media_object() } } -void media_object::set_video_frame_template(int index) +void media_object::set_video_frame_template(int index, int width_before_avcodec_open, int height_before_avcodec_open) { AVStream *video_stream = _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[index]]; AVCodecContext *video_codec_ctx = _ffmpeg->video_codec_ctxs[index]; @@ -359,6 +359,17 @@ void media_object::set_video_frame_template(int index) // Dimensions and aspect ratio video_frame_template.raw_width = video_codec_ctx->width; video_frame_template.raw_height = video_codec_ctx->height; + if (width_before_avcodec_open >= 1 && height_before_avcodec_open >= 1 + && (width_before_avcodec_open != video_codec_ctx->width + || height_before_avcodec_open != video_codec_ctx->height)) + { + msg::wrn(_("%s video stream %d: Using frame size %dx%d instead of %dx%d."), + _url.c_str(), index + 1, + width_before_avcodec_open, height_before_avcodec_open, + video_codec_ctx->width, video_codec_ctx->height); + video_frame_template.raw_width = width_before_avcodec_open; + video_frame_template.raw_height = height_before_avcodec_open; + } int ar_num = 1; int ar_den = 1; int ar_snum = video_stream->sample_aspect_ratio.num; @@ -779,6 +790,13 @@ void media_object::open(const std::string &url, const device_request &dev_reques _ffmpeg->format_ctx->streams[i]->discard = AVDISCARD_ALL; // ignore by default; user must activate streams AVCodecContext *codec_ctx = _ffmpeg->format_ctx->streams[i]->codec; AVCodec *codec = NULL; + // XXX: Sometimes the reported width and height for a video stream change after avcodec_open(), + // but the original values seem to be correct. This seems to happen mostly with 1920x1080 video + // that later is reported as 1920x1088, which results in a gray bar displayed at the bottom of + // the frame. FFplay is also affected. As a workaround, we keep the original values here and use + // them later in set_video_frame_template(). + int width_before_avcodec_open = codec_ctx->width; + int height_before_avcodec_open = codec_ctx->height; if (_ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { // Activate multithreaded decoding. This must be done before opening the codec; see @@ -811,7 +829,7 @@ void media_object::open(const std::string &url, const device_request &dev_reques _ffmpeg->video_codecs.push_back(codec); // Determine frame template. _ffmpeg->video_frame_templates.push_back(video_frame()); - set_video_frame_template(j); + set_video_frame_template(j, width_before_avcodec_open, height_before_avcodec_open); // Allocate things required for decoding _ffmpeg->video_packets.push_back(AVPacket()); av_init_packet(&(_ffmpeg->video_packets[j])); diff --git a/src/media_object.h b/src/media_object.h index 9055381..9e52da2 100644 --- a/src/media_object.h +++ b/src/media_object.h @@ -40,7 +40,7 @@ private: // Set video frame and audio blob templates by extracting the information // from the given streams - void set_video_frame_template(int video_stream); + void set_video_frame_template(int video_stream, int width_before_avcodec_open, int height_before_avcodec_open); void set_audio_blob_template(int audio_stream); void set_subtitle_box_template(int subtitle_stream);