FFmpeg 像素格式转换和尺寸转换

Demo

FFmpeg 可以实现像素格式转换和尺寸转换,但是性能开销非常大,对视频帧率影响比较大,实际开发中最好用 Shader来实现,FFmpeg的优势转换接口比较简单。

像素格式转换上下文 SwsContext

(1)sws_getContext
(2)sws_getCachedContext(
struct SwsContext *context,
int srcW, int srcH, 原宽高
enum AVPixelFormat srcFormat,原像素格式
int dstW, int dstH, 目标宽高
enum AVPixelFormat dstFormat,目标格式
int flags, 算法标签(性能差异 效果差异 针对尺寸变化)
SwsFilter *srcFilter,过滤器
SwsFilter *dstFilter,过滤器
const double *param 算法中默认值的设定 可以默认);
两个函数的差别是第一个参数:SwsContext
sws_getContext 会创建一个上下文空间,sws_getCachedContext会去缓冲中找,前后两次参数没变时返回同一个

//每一帧数据的处理
int sws_scale(struct SwsContext *c,
const uint8_t *const srcSlice[],具体数据的数组
const int srcStride[],一行数据的大小
int srcSliceY, 传0
int srcSliceH, 图形高度
uint8_t *const dst[], 目标的地址(指针数组)
const int dstStride[]) 输出的一行数据的大小;

void sws_freeContext(struct SwsContext *swsContext);//是否

     for (; ; ) {//保证能搜到全部的解码数据
            re = avcodec_receive_frame(cc, frame);
            if (re != 0) {
                break;
            }
            if (cc == vc) {
                frameCount++;
                vctx = sws_getCachedContext(vctx, frame->width, frame->height, (AVPixelFormat)frame->format, outWidth, outHeight, AV_PIX_FMT_RGBA, SWS_FAST_BILINEAR, 0, 0, 0);
                if (!vctx) {
                    NSLog(@"sws_getCachedContext failed!");

                }else{
                    uint8_t *data[AV_NUM_DATA_POINTERS] = {0};
                    data[0] = (uint8_t *)rgb;
                    int lines[AV_NUM_DATA_POINTERS] = {0};
                    lines[0] = outWidth * 4;
                    int h = sws_scale(vctx, frame->data, frame->linesize, 0, frame->height
                                      , data, lines);
                    NSLog(@"sws_scale h :%d ",h);
                }
            }

        }
        //最后一针的时候 avcodec_send_packet(cc, NULL)
        av_packet_unref(pkt);
2018-08-03 19:16:54.397601+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.409398+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.417052+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.425106+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.440420+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.448448+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.457397+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.465670+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.473706+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.481495+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.489395+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.497006+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.504962+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.512761+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.520280+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.528375+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.543610+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.551972+0800 FFmpeg402[611:176423] sws_scale h :720
2018-08-03 19:16:54.559866+0800 FFmpeg402[611:176423] sws_scale h :720

音频冲采样 SwrContext

一般音频解码出来直播不能直接播放,需要经过冲采样

SwrContext *swr_alloc(void); 上下文

SwrContext *swr_alloc_set_opts(设置参数
struct SwrContext *s,
int64_t out_ch_layout,输出layout
AVSampleFormat out_sample_fmt,输出的样本格式
int out_sample_rate,输出样本率
int64_t in_ch_layout,输入layout
AVSampleFormat in_sample_fmt,输入的样本格式
int in_sample_rate, 输入样本率
int log_offset, 0
void *log_ctx);日志 0

int swr_init(struct SwrContext *s); 初始化

void swr_free(struct SwrContext **s);释放

转换函数swr_convert 对每一帧音频做重采样

• int swr_convert(struct SwrContext *s,
uint8_t **out,输出的数组
int out_count,样本的数量 单通道
• const uint8_t **in , 输入参数指针数组
int in_count);

   //音频重采样上下文初始化
    SwrContext *actx = swr_alloc();
    //设置参数
    actx = swr_alloc_set_opts(actx,
                              av_get_default_channel_layout(2),//2
                              AV_SAMPLE_FMT_S16,
                              ac->sample_rate,
                              av_get_default_channel_layout(ac->channels),
                              ac->sample_fmt,
                              ac->sample_rate,
                              0,
                              0);
    re = swr_init(actx);
    if (re != 0) {
        NSLog(@"swr_init failed!");
    }else{
        NSLog(@"swr_init success!");
    }
         uint8_t *outData[2] = {0};
                outData[0]  = (uint8_t *)pcm;
                //重采样
                int len = swr_convert(actx,//上下文
                                      outData,
                                      frame->nb_samples,
                                      (const uint8_t **)frame->data,
                                      frame->nb_samples);
        
               NSLog(@"swr_convert len :%d ",len);
                
2018-08-03 19:45:47.054517+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.054560+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066537+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066658+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066744+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066872+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066932+0800 FFmpeg402[630:182386] swr_convert len :1024
2018-08-03 19:45:47.066977+0800 FFmpeg402[630:182386] swr_convert len :1024

打完收工

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容