ijkplayer 0.6.0 enable resolution change 代码研究

本文深入研究ijkplayer 0.6.0版本中实现分辨率更改的代码,涉及关键函数如avcodec_parameters_to_context、avcodec_open2等,分析了解码器配置及更新过程,揭示了分辨率变更背后的逻辑。同时,文章指出在某些条件下,决议更改的条件未被正确设置的问题,并给出了解决方案。
摘要由CSDN通过智能技术生成

代码地址
https://github.com/Bilibili/ijkplayer/blob/e28708feb0ec96b7a701f965b8b43a8a15b1eec9/ijkmedia/ijkplayer/android/pipeline/ffpipenode_android_mediacodec_vdec.c#L371
文中提到的行号以该github页面行号为基准

更新日志

  • 160802
    创建文档
    可以搜索数字来找到对应的改动点
  • 160803
    修正:
    avcodec_open2 中的 ff_set_dimensions() 不会执行,所以不会给coded_width/hight 赋值,即也不会与lowres值有关
  • 160803.2
    修正:
    发现了avctx->width/height的修改位置,通顺了代码的执行
  • 160804
    以后研究可能需要用到的git log
    https://github.com/Bilibili/ijkplayer/commit/eda66e626699c28b17ee3d419b812cacd9d56d6a
    有关surface重绘

目前讨论这一新特性的人太少了,如果有兴趣探讨欢迎邮件联系
可从github页面获取邮箱地址
https://github.com/CzachQ

要点1-Line434

if (opaque->ffp->mediacodec_handle_resolution_change &&
                opaque->codecpar->codec_id == AV_CODEC_ID_H264) 

判断本地播放器设置和编码流的编解码器ID

编解码器ID
https://www.ffmpeg.org/doxygen/2.7/group__lavc__core.html#gaadca229ad2c20e060a14fec08a5cc7ce

其中opaque变量定义为:

IJKFF_Pipenode_Opaque *opaque = node->opaque;

IJKFF_Pipenode_Opaque类的定义为:

typedef struct IJKFF_Pipenode_Opaque {
FFPlayer *ffp;
https://github.com/Bilibili/ijkplayer/blob/e28708feb0ec96b7a701f965b8b43a8a15b1eec9/ijkmedia/ijkplayer/ff_ffplay_def.h#L498
IJKFF_Pipeline *pipeline;
Decoder *decoder;
SDL_Vout *weak_vout;
ijkmp_mediacodecinfo_context mcc;
jobject jsurface;
SDL_AMediaFormat *input_aformat;
SDL_AMediaCodec *acodec;
SDL_AMediaFormat *output_aformat;
char acodec_name[128];
int frame_width;
int frame_height;
int frame_rotate_degrees;
AVCodecContext *avctx; // not own
AVCodecParameters *codecpar;
AVBitStreamFilterContext *bsfc; // own
#if AMC_USE_AVBITSTREAM_FILTER
uint8_t *orig_extradata;
int orig_extradata_size; #else
size_t nal_size; #endif
SDL_Thread _enqueue_thread;
SDL_Thread *enqueue_thread;
SDL_mutex *acodec_mutex;
SDL_cond *acodec_cond;
volatile bool acodec_flush_request;
volatile bool acodec_reconfigure_request;
SDL_mutex *acodec_first_dequeue_output_mutex;
SDL_cond *acodec_first_dequeue_output_cond;
volatile bool acodec_first_dequeue_output_request;
bool aformat_need_recreate;
SDL_mutex *any_input_mutex;
SDL_cond *any_input_cond;
int input_packet_count;
int input_error_count;
int output_error_count;
bool quirk_reconfigure_with_new_codec;
int n_buf_out;
AMC_Buf_Out *amc_buf_out;
int off_buf_out;
double last_queued_pts;
SDL_SpeedSampler sampler; } IJKFF_Pipenode_Opaque;

opaque->codecpar:

This struct describes the properties of an encoded stream.
这一数结构描述了一个编码流的属性
http://ffmpeg.org/doxygen/3.1/structAVCodecParameters.html


要点2-Line440

if (size_data && size_data_size > AV_INPUT_BUFFER_PADDING_SIZE) 

其中size_data和size_data_size的定义为:

uint8_t *size_data = NULL;
int size_data_size = 0;
size_data = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &size_data_size);

/**
* The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format
* that the extradata buffer was changed and the receiving side should
* act upon it appropriately. The new extradata is embedded in the side
* data buffer and should be immediately used for processing the current
* frame or packet.
*/

根据理解,size_data中如果得到了数据,表示packet中的extradata更新了,接收端需要更新自己的extradata,所以之后会有代码memcpy(new_avctx->extradata, size_data, size_data_size);完成这一操作
extradata中存储的是特定编解码器包含的特殊信息,类型为uint8_t*

补充说明:

av_packet_get_side_data:
Get side information from packet. (a FFmpeg function)

AVPacket *avpkt = &d->pkt_temp;

+(160803)
https://github.com/Bilib

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值