00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "libschroedinger.h"
00027 #include "libavutil/mem.h"
00028
00029 static const SchroVideoFormatInfo ff_schro_video_format_info[] = {
00030 { 640, 480, 24000, 1001},
00031 { 176, 120, 15000, 1001},
00032 { 176, 144, 25, 2 },
00033 { 352, 240, 15000, 1001},
00034 { 352, 288, 25, 2 },
00035 { 704, 480, 15000, 1001},
00036 { 704, 576, 25, 2 },
00037 { 720, 480, 30000, 1001},
00038 { 720, 576, 25, 1 },
00039 { 1280, 720, 60000, 1001},
00040 { 1280, 720, 50, 1 },
00041 { 1920, 1080, 30000, 1001},
00042 { 1920, 1080, 25, 1 },
00043 { 1920, 1080, 60000, 1001},
00044 { 1920, 1080, 50, 1 },
00045 { 2048, 1080, 24, 1 },
00046 { 4096, 2160, 24, 1 },
00047 };
00048
00049 static unsigned int get_video_format_idx(AVCodecContext *avccontext)
00050 {
00051 unsigned int ret_idx = 0;
00052 unsigned int idx;
00053 unsigned int num_formats = sizeof(ff_schro_video_format_info) /
00054 sizeof(ff_schro_video_format_info[0]);
00055
00056 for (idx = 1; idx < num_formats; ++idx) {
00057 const SchroVideoFormatInfo *vf = &ff_schro_video_format_info[idx];
00058 if (avccontext->width == vf->width &&
00059 avccontext->height == vf->height) {
00060 ret_idx = idx;
00061 if (avccontext->time_base.den == vf->frame_rate_num &&
00062 avccontext->time_base.num == vf->frame_rate_denom)
00063 return idx;
00064 }
00065 }
00066 return ret_idx;
00067 }
00068
00069 void ff_schro_queue_init(FFSchroQueue *queue)
00070 {
00071 queue->p_head = queue->p_tail = NULL;
00072 queue->size = 0;
00073 }
00074
00075 void ff_schro_queue_free(FFSchroQueue *queue, void (*free_func)(void *))
00076 {
00077 while (queue->p_head)
00078 free_func(ff_schro_queue_pop(queue));
00079 }
00080
00081 int ff_schro_queue_push_back(FFSchroQueue *queue, void *p_data)
00082 {
00083 FFSchroQueueElement *p_new = av_mallocz(sizeof(FFSchroQueueElement));
00084
00085 if (!p_new)
00086 return -1;
00087
00088 p_new->data = p_data;
00089
00090 if (!queue->p_head)
00091 queue->p_head = p_new;
00092 else
00093 queue->p_tail->next = p_new;
00094 queue->p_tail = p_new;
00095
00096 ++queue->size;
00097 return 0;
00098 }
00099
00100 void *ff_schro_queue_pop(FFSchroQueue *queue)
00101 {
00102 FFSchroQueueElement *top = queue->p_head;
00103
00104 if (top) {
00105 void *data = top->data;
00106 queue->p_head = queue->p_head->next;
00107 --queue->size;
00108 av_freep(&top);
00109 return data;
00110 }
00111
00112 return NULL;
00113 }
00114
00119 static const SchroVideoFormatEnum ff_schro_video_formats[]={
00120 SCHRO_VIDEO_FORMAT_CUSTOM ,
00121 SCHRO_VIDEO_FORMAT_QSIF ,
00122 SCHRO_VIDEO_FORMAT_QCIF ,
00123 SCHRO_VIDEO_FORMAT_SIF ,
00124 SCHRO_VIDEO_FORMAT_CIF ,
00125 SCHRO_VIDEO_FORMAT_4SIF ,
00126 SCHRO_VIDEO_FORMAT_4CIF ,
00127 SCHRO_VIDEO_FORMAT_SD480I_60 ,
00128 SCHRO_VIDEO_FORMAT_SD576I_50 ,
00129 SCHRO_VIDEO_FORMAT_HD720P_60 ,
00130 SCHRO_VIDEO_FORMAT_HD720P_50 ,
00131 SCHRO_VIDEO_FORMAT_HD1080I_60 ,
00132 SCHRO_VIDEO_FORMAT_HD1080I_50 ,
00133 SCHRO_VIDEO_FORMAT_HD1080P_60 ,
00134 SCHRO_VIDEO_FORMAT_HD1080P_50 ,
00135 SCHRO_VIDEO_FORMAT_DC2K_24 ,
00136 SCHRO_VIDEO_FORMAT_DC4K_24 ,
00137 };
00138
00139 SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext)
00140 {
00141 unsigned int num_formats = sizeof(ff_schro_video_formats) /
00142 sizeof(ff_schro_video_formats[0]);
00143
00144 unsigned int idx = get_video_format_idx(avccontext);
00145
00146 return (idx < num_formats) ? ff_schro_video_formats[idx] :
00147 SCHRO_VIDEO_FORMAT_CUSTOM;
00148 }
00149
00150 int ff_get_schro_frame_format (SchroChromaFormat schro_pix_fmt,
00151 SchroFrameFormat *schro_frame_fmt)
00152 {
00153 unsigned int num_formats = sizeof(schro_pixel_format_map) /
00154 sizeof(schro_pixel_format_map[0]);
00155
00156 int idx;
00157
00158 for (idx = 0; idx < num_formats; ++idx) {
00159 if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) {
00160 *schro_frame_fmt = schro_pixel_format_map[idx].schro_frame_fmt;
00161 return 0;
00162 }
00163 }
00164 return -1;
00165 }
00166
00167 static void free_schro_frame(SchroFrame *frame, void *priv)
00168 {
00169 AVPicture *p_pic = priv;
00170
00171 if (!p_pic)
00172 return;
00173
00174 avpicture_free(p_pic);
00175 av_freep(&p_pic);
00176 }
00177
00178 SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
00179 SchroFrameFormat schro_frame_fmt)
00180 {
00181 AVPicture *p_pic;
00182 SchroFrame *p_frame;
00183 int y_width, uv_width;
00184 int y_height, uv_height;
00185 int i;
00186
00187 y_width = avccontext->width;
00188 y_height = avccontext->height;
00189 uv_width = y_width >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt));
00190 uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt));
00191
00192 p_pic = av_mallocz(sizeof(AVPicture));
00193 if (!p_pic || avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height) < 0) {
00194 av_free(p_pic);
00195 return NULL;
00196 }
00197
00198 p_frame = schro_frame_new();
00199 p_frame->format = schro_frame_fmt;
00200 p_frame->width = y_width;
00201 p_frame->height = y_height;
00202 schro_frame_set_free_callback(p_frame, free_schro_frame, (void *)p_pic);
00203
00204 for (i = 0; i < 3; ++i) {
00205 p_frame->components[i].width = i ? uv_width : y_width;
00206 p_frame->components[i].stride = p_pic->linesize[i];
00207 p_frame->components[i].height = i ? uv_height : y_height;
00208 p_frame->components[i].length =
00209 p_frame->components[i].stride * p_frame->components[i].height;
00210 p_frame->components[i].data = p_pic->data[i];
00211
00212 if (i) {
00213 p_frame->components[i].v_shift =
00214 SCHRO_FRAME_FORMAT_V_SHIFT(p_frame->format);
00215 p_frame->components[i].h_shift =
00216 SCHRO_FRAME_FORMAT_H_SHIFT(p_frame->format);
00217 }
00218 }
00219
00220 return p_frame;
00221 }