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