Outline
1. Video Decode
2. Video Encode
3. Audio Decode
4. Audio Encode
5. libyuv (YUV scaling & Convert ) 比ffmpeg 快
p.s. GoldWave 撥pcm , g711
-------------------------------------------------
- 1. Video Decode
AVCodec *vCodec265 = NULL;
AVCodec *vCodec264 = NULL;
vCodec265 = avcodec_find_decoder(AV_CODEC_ID_HEVC); //265
vCodec264 = avcodec_find_decoder(AV_CODEC_ID_H264); //264
AVCodecContext *vCodecCtxarr[32];// 16 for h264 ; 16 for h265
- h265
vCodecCtxarr[nal_ch+16] = avcodec_alloc_context3(vCodec265);
vCodecCtxarr[nal_ch+16]->flags |= AV_CODEC_CAP_DELAY;
vCodecCtxarr[nal_ch+16]->skip_frame = AVDISCARD_BIDIR;
vCodecCtxarr[nal_ch+16]->skip_idct = AVDISCARD_NONREF;
vCodecCtxarr[nal_ch+16]->skip_loop_filter = AVDISCARD_NONREF;
vCodecCtxarr[nal_ch+16]->thread_count = 1;
open codec:
avcodec_open2(vCodecCtxarr[nal_ch+16], vCodec265, NULL)
- h264
vCodecCtxarr[nal_ch] = avcodec_alloc_context3(vCodec264);vCodecCtxarr[nal_ch]->flags |= AV_CODEC_CAP_DELAY;
vCodecCtxarr[nal_ch]->skip_frame = AVDISCARD_BIDIR;
vCodecCtxarr[nal_ch]->skip_idct = AVDISCARD_NONREF;
vCodecCtxarr[nal_ch]->skip_loop_filter = AVDISCARD_NONREF;
vCodecCtxarr[nal_ch]->thread_count = 1;
open deoce:
avcodec_open2(vCodecCtxarr[nal_ch], vCodec264, NULL)
--------------------decode stream 切換 vCodecCtxarr[ch] or vCodecCtxarr[ch+16]----------------
*input data:
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = (unsigned char*) nalData;
pkt.size = nal_length;
*deocode:
AVFrame * pFrame = av_frame_alloc();
int consumed_bytes = avcodec_decode_video2(vCodecCtxarr[nal_ch], pFrame, &got_picture, &pkt);轉換format (非必要) , yuv -> RBG565
img_convert_ctx = sws_getContext(
vCodecCtxarr[nal_ch]->width, vCodecCtxarr[nal_ch]->height,
vCodecCtxarr[nal_ch]->pix_fmt, vCodecCtxarr[nal_ch]->width,
vCodecCtxarr[nal_ch]->height,
AV_PIX_FMT_RGB565, SWS_FAST_BILINEAR, NULL, NULL, NULL);
*close codec
- 2. Video Encode
avcodec_flush_buffers(vCodecCtxarr[nal_ch+16]);
avcodec_free_context(&vCodecCtxarr[nal_ch+16]);
vCodecCtxarr[nal_ch+16] = NULL;
av_free(vCodecCtxarr[nal_ch]);- 其他如 AVFrame 存為yuv 420:
FILE *pfout = NULL;
void yuv420p_save(AVFrame *pFrame, int mWidth,int mLeight)
{
int i = 0;
int width = mWidth, height = mLeight;
int height_half = height / 2, width_half = width / 2;
int y_wrap = pFrame->linesize[0];
int u_wrap = pFrame->linesize[1];
int v_wrap = pFrame->linesize[2];
unsigned char *y_buf = pFrame->data[0];
unsigned char *u_buf = pFrame->data[1];
unsigned char *v_buf = pFrame->data[2];
LOGE("qtParserTest....................... real width=%d,height= %d",width,height);
LOGE("qtParserTest....................... y_wrap= %d,u_wrap= %d,v_wrap= %d",y_wrap,u_wrap,v_wrap);
//if height=360,width=640,*3/2=> total 345600;y_wrap=640
//save y
for (i = 0; i < height; i++)
fwrite(y_buf + i * y_wrap, 1, width, pfout);//230400 height*width
//--------------for N12 uv uv;u_wrap=320
// for (i = 0; i < height_half; i++)
// fwrite(u_buf + i * u_wrap, 1, width, pfout);//115200 height_half*width
//-----------------below to for I420
//save u
for (i = 0; i < height_half; i++)//57600 height_half*width_half
fwrite(u_buf + i * u_wrap, 1, width_half, pfout);
//save v
for (i = 0; i < height_half; i++)//57600
fwrite(v_buf + i * v_wrap, 1, width_half, pfout);
//460800
fflush(pfout);
}
- 3. Audio Decode (g726 , aac) g711 用轉表方式
AVCodec *m_pcodec;
AVCodecContext *m_pavCtx;
SwrContext *m_pswrCtx;
- aac:
m_pcodec = avcodec_find_decoder(AV_CODEC_ID_AAC);
m_pavCtx = avcodec_alloc_context3(m_pcodec);
m_pavCtx->channels = 1;
m_pavCtx->sample_rate = i_sample_hz;
m_pavCtx->channel_layout = 1;
avcodec_open2(m_pavCtx, m_pcodec, NULL)
resample:
m_pswrCtx = swr_alloc_set_opts( NULL,
m_pavCtx->channel_layout,
AV_SAMPLE_FMT_S16,
m_pavCtx->sample_rate,
m_pavCtx->channels,
AV_SAMPLE_FMT_FLTP,
m_pavCtx->sample_rate,
0,
NULL);
output&decode:
AVPacket packet;
av_init_packet(&packet);
packet.size = buffer_size;
packet.data = data;
uint8_t *audio_buf = new uint8_t[10240];
AVFrame *frame = av_frame_alloc();
int len = avcodec_decode_audio4(m_pavCtx, frame, &got_frame, &packet);int ret = swr_convert(m_pswrCtx, &audio_buf, frame->nb_samples,
(const uint8_t **) frame->extended_data, frame->nb_samples);
m_fun_notify(m_penv, (unsigned char *) audio_buf, frame->linesize[0] / 4);
- g726:
m_pcodec = avcodec_find_decoder(AV_CODEC_ID_ADPCM_G726);
m_pavCtx->channels = 1;
m_pavCtx->sample_rate = 8000;
m_pavCtx->bit_rate = (ms32CodeType * 8);
m_pavCtx->bits_per_coded_sample = ms32CodeType ;
avcodec_open2(m_pavCtx, m_pcodec, NULL)
output &decode :
AVPacket packet;
av_init_packet(&packet);
packet.size = buffer_size;
packet.data = data;
uint8_t *audio_buf = new uint8_t[10240];
AVFrame *frame = av_frame_alloc();
int len = avcodec_decode_audio4(m_pavCtx, frame, &got_frame, &packet);out:
dst_len=av_samples_get_buffer_size(NULL, m_pavCtx->channels,frame->nb_samples, AV_SAMPLE_FMT_S16, 1);
frame->data[0], dst_len
close:
avcodec_close(m_pavCtx);
av_free(m_pavCtx);
swr_free(&m_pswrCtx);
-----------------------------------
沒有留言:
張貼留言