31 #include <libavformat/avformat.h> 32 #include <libmediaprocsutils/log.h> 33 #include <libmediaprocsutils/stat_codes.h> 34 #include <libmediaprocsutils/check_utils.h> 35 #include <libmediaprocsutils/mem_utils.h> 36 #include <libmediaprocs/proc_if.h> 49 register int i, ffmpeg_fmt, end_code= STAT_ERROR;
50 AVFrame *avframe= NULL;
54 CHECK_DO(proc_frame_ctx!= NULL,
return NULL);
57 ffmpeg_fmt= proc_sample_fmt_2_ffmpegfmt(proc_frame_ctx->
proc_sample_fmt);
63 register int width_Y, height_Y;
64 case AV_PIX_FMT_YUV420P:
67 width_Y= proc_frame_ctx->
width[0];
69 LOGE(
"Frame width= %d out of bounds (range is 1..%d)\n",
70 width_Y, PROC_FRAME_MAX_WIDTH);
73 height_Y= proc_frame_ctx->
height[0];
75 LOGE(
"Frame height= %d out of bounds (range is 1..%d)\n",
76 height_Y, PROC_FRAME_MAX_HEIGHT);
85 for(i= 0; i< PROC_FRAME_NUM_DATA_POINTERS; i++) {
86 register int l, lsize_src, lsize_dst, width, height;
87 const uint8_t *data_src= proc_frame_ctx->
p_data[i];
88 uint8_t *data_dst= avframe->data[i];
94 lsize_src= proc_frame_ctx->
linesize[i];
95 lsize_dst= avframe->linesize[i];
96 width= proc_frame_ctx->
width[i];
97 height= proc_frame_ctx->
height[i];
98 CHECK_DO(width== width_Y>> (i!= 0),
goto end);
99 CHECK_DO(height== height_Y>> (i!= 0),
goto end);
100 CHECK_DO(lsize_src>= width && lsize_dst>= width,
goto end);
101 for(l= 0; l< height; l++)
102 memcpy(&data_dst[l*lsize_dst], &data_src[l*lsize_src], width);
106 avframe->format= ffmpeg_fmt;
107 avframe->pts= proc_frame_ctx->
pts;
109 case AV_SAMPLE_FMT_S16:
110 case AV_SAMPLE_FMT_S16P:
113 if(proc_frame_ctx->
width[0]< 1 || proc_frame_ctx->
height[0]< 1) {
114 LOGE(
"Frame height and width should be set to '1' and 'data-size' " 115 "respectively (this is a 1-dimensional array of data)\n");
120 avframe= av_frame_alloc();
129 avframe->nb_samples= proc_frame_ctx->
width[0]>> (
130 (ffmpeg_fmt== AV_SAMPLE_FMT_S16)
132 avframe->format= AV_SAMPLE_FMT_S16P;
133 avframe->channel_layout= AV_CH_LAYOUT_STEREO;
134 avframe->linesize[0]= avframe->linesize[1]=
135 proc_frame_ctx->
linesize[0]>> (ffmpeg_fmt== AV_SAMPLE_FMT_S16);
136 avframe->pts= proc_frame_ctx->
pts;
142 CHECK_DO(av_frame_get_buffer(avframe, 32)>= 0,
goto end);
145 if(ffmpeg_fmt== AV_SAMPLE_FMT_S16) {
147 const int16_t *data_src= (int16_t*)(proc_frame_ctx->
p_data[0]);
148 int16_t *data_dst_lef= (int16_t*)(avframe->data[0]);
149 int16_t *data_dst_rig= (int16_t*)(avframe->data[1]);
151 for(i= 0; i< avframe->nb_samples<< 1; i+= 2) {
152 int16_t sample_lef= *data_src++;
153 int16_t sample_rig= *data_src++;
154 *data_dst_lef++= sample_lef;
155 *data_dst_rig++= sample_rig;
158 for(i= 0; i< 2 ; i++) {
159 register int plane_size;
160 const uint8_t *data_src= proc_frame_ctx->
p_data[i];
161 uint8_t *data_dst= avframe->data[i];
164 CHECK_DO(data_dst!= NULL,
goto end);
165 if((plane_size= proc_frame_ctx->
linesize[i])<= 0)
167 memcpy(data_dst, data_src, plane_size);
172 LOGE(
"Unsupported frame samples format at encoder input\n");
176 end_code= STAT_SUCCESS;
178 if(end_code!= STAT_SUCCESS && avframe!= NULL) {
179 av_frame_free(&avframe);
182 return (
void*)avframe;
187 int ret_code, end_code= STAT_ERROR;
188 AVFrame *avframe= NULL;
194 LOGE(
"Could not allocate video raw picture buffer: video resolution " 199 avframe= av_frame_alloc();
208 avframe->format= pix_fmt;
209 avframe->width= width;
210 avframe->height= height;
211 ret_code= av_frame_get_buffer(avframe, 32);
215 ret_code= av_frame_make_writable(avframe);
219 end_code= STAT_SUCCESS;
221 if(end_code!= STAT_SUCCESS && avframe!= NULL) {
222 av_frame_free(&avframe);
230 if(ref_avfame== NULL)
232 av_frame_free((AVFrame**)ref_avfame);
238 AVPacket *avpacket= (AVPacket*)avpacket_arg;
244 CHECK_DO(avpacket!= NULL,
return NULL);
247 CHECK_DO(proc_frame_ctx!= NULL,
return NULL);
253 data= (uint8_t*)malloc(avpacket->size);
255 proc_frame_ctx->
p_data[0]= proc_frame_ctx->
data= data;
256 memcpy((
void*)data, avpacket->data, avpacket->size);
258 proc_frame_ctx->
linesize[0]= avpacket->size;
259 proc_frame_ctx->
width[0]= avpacket->size;
260 proc_frame_ctx->
height[0]= 1;
261 proc_frame_ctx->
pts= avpacket->pts;
262 proc_frame_ctx->
dts= avpacket->dts;
263 proc_frame_ctx->
es_id= avpacket->stream_index;
269 av_packet_unref(avpacket);
270 return proc_frame_ctx;
275 register int data_size, ret_code, end_code= STAT_ERROR;
276 AVPacket *avpacket= NULL;
280 CHECK_DO(proc_frame_ctx!= NULL,
return NULL);
283 if(proc_frame_ctx->
width[0]< 1 || proc_frame_ctx->
height[0]< 1) {
284 LOGE(
"Frame height and width should be set to '1' and 'data-size' " 285 "respectively (this is a 1-dimensional array of data)\n");
290 avpacket= av_packet_alloc();
291 CHECK_DO(avpacket!= NULL,
goto end);
298 data_size= proc_frame_ctx->
width[0];
299 ret_code= av_new_packet(avpacket, data_size);
300 CHECK_DO(ret_code== 0 && avpacket->data!= NULL &&
301 avpacket->size== data_size,
goto end);
302 memcpy(avpacket->data, proc_frame_ctx->
p_data[0], data_size);
305 avpacket->pts= proc_frame_ctx->
pts;
306 avpacket->dts= proc_frame_ctx->
dts;
307 avpacket->stream_index= proc_frame_ctx->
es_id;
309 end_code= STAT_SUCCESS;
311 if(end_code!= STAT_SUCCESS && avpacket!= NULL)
313 return (
void*)avpacket;
318 if(ref_avpacket== NULL)
320 av_packet_free((AVPacket**)
328 register int end_code= STAT_ERROR;
329 AVFrame *avframe= (AVFrame*)avframe_arg;
339 CHECK_DO(proc_frame_ctx!= NULL,
goto end);
342 proc_sample_fmt= ffmpegfmt_2_proc_sample_fmt(avframe->format);
347 switch(proc_sample_fmt) {
348 register int i, lsize_dst_Y, lsize_dst_C, size_dst_Y, size_dst_C,
349 width_Y= 0, height_Y= 0, lsize_ch, lsize_ch_aligned;
353 width_Y= avframe->width;
354 height_Y= avframe->height;
356 LOGE(
"Frame width= %d out of bounds (range is 1..%d)\n",
357 width_Y, PROC_FRAME_MAX_WIDTH);
361 LOGE(
"Frame height= %d out of bounds (range is 1..%d)\n",
362 height_Y, PROC_FRAME_MAX_HEIGHT);
369 size_dst_Y= lsize_dst_Y* height_Y;
370 size_dst_C= lsize_dst_C* (height_Y>> 1);
374 proc_frame_ctx->
data= data;
377 proc_frame_ctx->
p_data[0]= data;
378 proc_frame_ctx->
p_data[1]= data+ size_dst_Y;
379 proc_frame_ctx->
p_data[2]= data+ size_dst_Y+ size_dst_C;
381 proc_frame_ctx->
linesize[0]= lsize_dst_Y;
382 proc_frame_ctx->
linesize[1]= lsize_dst_C;
383 proc_frame_ctx->
linesize[2]= lsize_dst_C;
384 proc_frame_ctx->
width[0]= width_Y;
385 proc_frame_ctx->
width[1]= width_Y>> 1;
386 proc_frame_ctx->
width[2]= width_Y>> 1;
387 proc_frame_ctx->
height[0]= height_Y;
388 proc_frame_ctx->
height[1]= height_Y>> 1;
389 proc_frame_ctx->
height[2]= height_Y>> 1;
392 for(i= 0; i< 3; i++) {
394 register int h= proc_frame_ctx->
height[i];
395 register int w= proc_frame_ctx->
width[i];
396 for(l= 0; l< h; l++) {
397 uint8_t *data_src= avframe->data[i];
398 uint8_t *data_dst= (uint8_t*)proc_frame_ctx->
p_data[i];
399 register int lsize_src= avframe->linesize[i];
400 register int lsize_dst= proc_frame_ctx->
linesize[i];
402 CHECK_DO(data_src!= NULL && data_dst!= NULL,
goto end);
403 CHECK_DO(lsize_src>= w && lsize_dst>= w,
goto end);
404 memcpy(&data_dst[l*lsize_dst], &data_src[l*lsize_src], w);
423 if(avframe->channel_layout!= AV_CH_LAYOUT_STEREO) {
424 LOGE(
"Audio channel layout not supported\n");
427 lsize_ch= avframe->linesize[0];
432 proc_frame_ctx->
data= data;
437 int16_t *data_src_lef;
438 int16_t *data_src_rig;
442 proc_frame_ctx->
p_data[0]= proc_frame_ctx->
data;
443 proc_frame_ctx->
linesize[0]= lsize_ch_aligned<< 1;
444 proc_frame_ctx->
width[0]= lsize_ch<< 1;
445 proc_frame_ctx->
height[0]= 1;
448 data_src_lef= (int16_t*)(avframe->data[0]);
449 data_src_rig= (int16_t*)(avframe->data[1]);
450 data_dst= (int16_t*)(proc_frame_ctx->
p_data[0]);
451 for(i= 0; i< avframe->nb_samples<< 1; i+= 2) {
452 int16_t sample_lef= *data_src_lef++;
453 int16_t sample_rig= *data_src_rig++;
454 *data_dst++= sample_lef;
455 *data_dst++= sample_rig;
459 proc_frame_ctx->
p_data[0]= proc_frame_ctx->
data;
460 proc_frame_ctx->
p_data[1]= proc_frame_ctx->
data+ lsize_ch_aligned;
461 proc_frame_ctx->
linesize[0]= lsize_ch_aligned;
462 proc_frame_ctx->
width[0]= lsize_ch;
463 proc_frame_ctx->
height[0]= 1;
464 proc_frame_ctx->
linesize[1]= lsize_ch_aligned;
465 proc_frame_ctx->
width[1]= lsize_ch;
466 proc_frame_ctx->
height[1]= 1;
469 for(i= 0; i< 2; i++) {
470 uint8_t *data_src= avframe->data[i];
471 uint8_t *data_dst= (uint8_t*)proc_frame_ctx->
p_data[i];
472 CHECK_DO(data_src!= NULL && data_dst!= NULL,
goto end);
473 memcpy(data_dst, data_src, lsize_ch);
479 LOGE(
"Unsupported frame samples format at decoder output\n");
486 proc_frame_ctx->
pts= avframe->pts;
487 proc_frame_ctx->
dts= -1;
489 end_code= STAT_SUCCESS;
493 if(end_code!= STAT_SUCCESS)
495 return proc_frame_ctx;
502 switch(proc_sample_fmt) {
504 ffmpegfmt= AV_PIX_FMT_YUV420P;
510 ffmpegfmt= AV_SAMPLE_FMT_S16;
513 ffmpegfmt= AV_SAMPLE_FMT_S16P;
527 case AV_PIX_FMT_YUV420P:
533 case AV_SAMPLE_FMT_S16:
536 case AV_SAMPLE_FMT_S16P:
543 return proc_sample_fmt;
void avframe_release(void **ref_avfame)
Facilities to convert processor's input/output frame to FFmpeg's formats and vice versa...
proc_frame_ctx_t * avframe_2_proc_frame_ctx(const void *avframe_arg)
size_t width[PROC_FRAME_NUM_DATA_POINTERS]
void proc_frame_ctx_release(proc_frame_ctx_t **ref_proc_frame_ctx)
#define EXTEND_SIZE_TO_MULTIPLE(SIZE, MULTIPLE)
int linesize[PROC_FRAME_NUM_DATA_POINTERS]
AVFrame * allocate_frame_video(int pix_fmt, int width, int height)
void avpacket_release(void **ref_avpacket)
#define CHECK_DO(COND, ACTION)
enum proc_sample_fmt_enum proc_sample_fmt_t
Planar YUV 4:2:0 with 12bpp (video)
proc_frame_ctx_t * proc_frame_ctx_allocate()
#define PROC_FRAME_MAX_HEIGHT
#define PROC_FRAME_MAX_WIDTH
proc_frame_ctx_t * avpacket_2_proc_frame_ctx(const void *avpacket_arg)
Planar signed 16 bits (typically audio)
void * proc_frame_ctx_2_avpacket(const proc_frame_ctx_t *proc_frame_ctx)
size_t height[PROC_FRAME_NUM_DATA_POINTERS]
Interleaved signed 16 bits (typically audio)
void * proc_frame_ctx_2_avframe(const proc_frame_ctx_t *proc_frame_ctx)
const uint8_t * p_data[PROC_FRAME_NUM_DATA_POINTERS]