FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
libschroedinger.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22 * @file
23 * function definitions common to libschroedinger decoder and encoder
24 */
25 
26 #include "libschroedinger.h"
27 #include "libavutil/mem.h"
28 
30  { 640, 480, 24000, 1001},
31  { 176, 120, 15000, 1001},
32  { 176, 144, 25, 2 },
33  { 352, 240, 15000, 1001},
34  { 352, 288, 25, 2 },
35  { 704, 480, 15000, 1001},
36  { 704, 576, 25, 2 },
37  { 720, 480, 30000, 1001},
38  { 720, 576, 25, 1 },
39  { 1280, 720, 60000, 1001},
40  { 1280, 720, 50, 1 },
41  { 1920, 1080, 30000, 1001},
42  { 1920, 1080, 25, 1 },
43  { 1920, 1080, 60000, 1001},
44  { 1920, 1080, 50, 1 },
45  { 2048, 1080, 24, 1 },
46  { 4096, 2160, 24, 1 },
47 };
48 
49 static unsigned int get_video_format_idx(AVCodecContext *avccontext)
50 {
51  unsigned int ret_idx = 0;
52  unsigned int idx;
53  unsigned int num_formats = sizeof(ff_schro_video_format_info) /
54  sizeof(ff_schro_video_format_info[0]);
55 
56  for (idx = 1; idx < num_formats; ++idx) {
57  const SchroVideoFormatInfo *vf = &ff_schro_video_format_info[idx];
58  if (avccontext->width == vf->width &&
59  avccontext->height == vf->height) {
60  ret_idx = idx;
61  if (avccontext->time_base.den == vf->frame_rate_num &&
62  avccontext->time_base.num == vf->frame_rate_denom)
63  return idx;
64  }
65  }
66  return ret_idx;
67 }
68 
70 {
71  queue->p_head = queue->p_tail = NULL;
72  queue->size = 0;
73 }
74 
75 void ff_schro_queue_free(FFSchroQueue *queue, void (*free_func)(void *))
76 {
77  while (queue->p_head)
78  free_func(ff_schro_queue_pop(queue));
79 }
80 
81 int ff_schro_queue_push_back(FFSchroQueue *queue, void *p_data)
82 {
84 
85  if (!p_new)
86  return -1;
87 
88  p_new->data = p_data;
89 
90  if (!queue->p_head)
91  queue->p_head = p_new;
92  else
93  queue->p_tail->next = p_new;
94  queue->p_tail = p_new;
95 
96  ++queue->size;
97  return 0;
98 }
99 
101 {
102  FFSchroQueueElement *top = queue->p_head;
103 
104  if (top) {
105  void *data = top->data;
106  queue->p_head = queue->p_head->next;
107  --queue->size;
108  av_freep(&top);
109  return data;
110  }
111 
112  return NULL;
113 }
114 
115 /**
116 * Schroedinger video preset table. Ensure that this tables matches up correctly
117 * with the ff_schro_video_format_info table.
118 */
119 static const SchroVideoFormatEnum ff_schro_video_formats[]={
120  SCHRO_VIDEO_FORMAT_CUSTOM ,
121  SCHRO_VIDEO_FORMAT_QSIF ,
122  SCHRO_VIDEO_FORMAT_QCIF ,
123  SCHRO_VIDEO_FORMAT_SIF ,
124  SCHRO_VIDEO_FORMAT_CIF ,
125  SCHRO_VIDEO_FORMAT_4SIF ,
126  SCHRO_VIDEO_FORMAT_4CIF ,
127  SCHRO_VIDEO_FORMAT_SD480I_60 ,
128  SCHRO_VIDEO_FORMAT_SD576I_50 ,
129  SCHRO_VIDEO_FORMAT_HD720P_60 ,
130  SCHRO_VIDEO_FORMAT_HD720P_50 ,
131  SCHRO_VIDEO_FORMAT_HD1080I_60 ,
132  SCHRO_VIDEO_FORMAT_HD1080I_50 ,
133  SCHRO_VIDEO_FORMAT_HD1080P_60 ,
134  SCHRO_VIDEO_FORMAT_HD1080P_50 ,
135  SCHRO_VIDEO_FORMAT_DC2K_24 ,
136  SCHRO_VIDEO_FORMAT_DC4K_24 ,
137 };
138 
139 SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext)
140 {
141  unsigned int num_formats = sizeof(ff_schro_video_formats) /
142  sizeof(ff_schro_video_formats[0]);
143 
144  unsigned int idx = get_video_format_idx(avccontext);
145 
146  return (idx < num_formats) ? ff_schro_video_formats[idx] :
147  SCHRO_VIDEO_FORMAT_CUSTOM;
148 }
149 
151  SchroFrameFormat *schro_frame_fmt)
152 {
153  unsigned int num_formats = sizeof(schro_pixel_format_map) /
154  sizeof(schro_pixel_format_map[0]);
155 
156  int idx;
157 
158  for (idx = 0; idx < num_formats; ++idx) {
159  if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) {
160  *schro_frame_fmt = schro_pixel_format_map[idx].schro_frame_fmt;
161  return 0;
162  }
163  }
164  return -1;
165 }
166 
167 static void free_schro_frame(SchroFrame *frame, void *priv)
168 {
169  AVPicture *p_pic = priv;
170 
171  if (!p_pic)
172  return;
173 
174  avpicture_free(p_pic);
175  av_freep(&p_pic);
176 }
177 
178 SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
179  SchroFrameFormat schro_frame_fmt)
180 {
181  AVPicture *p_pic;
182  SchroFrame *p_frame;
183  int y_width, uv_width;
184  int y_height, uv_height;
185  int i;
186 
187  y_width = avccontext->width;
188  y_height = avccontext->height;
189  uv_width = y_width >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt));
190  uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt));
191 
192  p_pic = av_mallocz(sizeof(AVPicture));
193  if (!p_pic || avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height) < 0) {
194  av_free(p_pic);
195  return NULL;
196  }
197 
198  p_frame = schro_frame_new();
199  p_frame->format = schro_frame_fmt;
200  p_frame->width = y_width;
201  p_frame->height = y_height;
202  schro_frame_set_free_callback(p_frame, free_schro_frame, (void *)p_pic);
203 
204  for (i = 0; i < 3; ++i) {
205  p_frame->components[i].width = i ? uv_width : y_width;
206  p_frame->components[i].stride = p_pic->linesize[i];
207  p_frame->components[i].height = i ? uv_height : y_height;
208  p_frame->components[i].length =
209  p_frame->components[i].stride * p_frame->components[i].height;
210  p_frame->components[i].data = p_pic->data[i];
211 
212  if (i) {
213  p_frame->components[i].v_shift =
214  SCHRO_FRAME_FORMAT_V_SHIFT(p_frame->format);
215  p_frame->components[i].h_shift =
216  SCHRO_FRAME_FORMAT_H_SHIFT(p_frame->format);
217  }
218  }
219 
220  return p_frame;
221 }