FFmpeg
 All Data Structures Namespaces 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 "libavutil/attributes.h"
27 #include "libavutil/mem.h"
28 #include "libschroedinger.h"
29 
31  { 640, 480, 24000, 1001},
32  { 176, 120, 15000, 1001},
33  { 176, 144, 25, 2 },
34  { 352, 240, 15000, 1001},
35  { 352, 288, 25, 2 },
36  { 704, 480, 15000, 1001},
37  { 704, 576, 25, 2 },
38  { 720, 480, 30000, 1001},
39  { 720, 576, 25, 1 },
40  { 1280, 720, 60000, 1001},
41  { 1280, 720, 50, 1 },
42  { 1920, 1080, 30000, 1001},
43  { 1920, 1080, 25, 1 },
44  { 1920, 1080, 60000, 1001},
45  { 1920, 1080, 50, 1 },
46  { 2048, 1080, 24, 1 },
47  { 4096, 2160, 24, 1 },
48 };
49 
50 static unsigned int get_video_format_idx(AVCodecContext *avctx)
51 {
52  unsigned int ret_idx = 0;
53  unsigned int idx;
54  unsigned int num_formats = sizeof(ff_schro_video_format_info) /
55  sizeof(ff_schro_video_format_info[0]);
56 
57  for (idx = 1; idx < num_formats; ++idx) {
58  const SchroVideoFormatInfo *vf = &ff_schro_video_format_info[idx];
59  if (avctx->width == vf->width &&
60  avctx->height == vf->height) {
61  ret_idx = idx;
62  if (avctx->time_base.den == vf->frame_rate_num &&
63  avctx->time_base.num == vf->frame_rate_denom)
64  return idx;
65  }
66  }
67  return ret_idx;
68 }
69 
71 {
72  queue->p_head = queue->p_tail = NULL;
73  queue->size = 0;
74 }
75 
76 void ff_schro_queue_free(FFSchroQueue *queue, void (*free_func)(void *))
77 {
78  while (queue->p_head)
79  free_func(ff_schro_queue_pop(queue));
80 }
81 
82 int ff_schro_queue_push_back(FFSchroQueue *queue, void *p_data)
83 {
85 
86  if (!p_new)
87  return -1;
88 
89  p_new->data = p_data;
90 
91  if (!queue->p_head)
92  queue->p_head = p_new;
93  else
94  queue->p_tail->next = p_new;
95  queue->p_tail = p_new;
96 
97  ++queue->size;
98  return 0;
99 }
100 
102 {
103  FFSchroQueueElement *top = queue->p_head;
104 
105  if (top) {
106  void *data = top->data;
107  queue->p_head = queue->p_head->next;
108  --queue->size;
109  av_freep(&top);
110  return data;
111  }
112 
113  return NULL;
114 }
115 
116 /**
117 * Schroedinger video preset table. Ensure that this tables matches up correctly
118 * with the ff_schro_video_format_info table.
119 */
120 static const SchroVideoFormatEnum ff_schro_video_formats[]={
121  SCHRO_VIDEO_FORMAT_CUSTOM ,
122  SCHRO_VIDEO_FORMAT_QSIF ,
123  SCHRO_VIDEO_FORMAT_QCIF ,
124  SCHRO_VIDEO_FORMAT_SIF ,
125  SCHRO_VIDEO_FORMAT_CIF ,
126  SCHRO_VIDEO_FORMAT_4SIF ,
127  SCHRO_VIDEO_FORMAT_4CIF ,
128  SCHRO_VIDEO_FORMAT_SD480I_60 ,
129  SCHRO_VIDEO_FORMAT_SD576I_50 ,
130  SCHRO_VIDEO_FORMAT_HD720P_60 ,
131  SCHRO_VIDEO_FORMAT_HD720P_50 ,
132  SCHRO_VIDEO_FORMAT_HD1080I_60 ,
133  SCHRO_VIDEO_FORMAT_HD1080I_50 ,
134  SCHRO_VIDEO_FORMAT_HD1080P_60 ,
135  SCHRO_VIDEO_FORMAT_HD1080P_50 ,
136  SCHRO_VIDEO_FORMAT_DC2K_24 ,
137  SCHRO_VIDEO_FORMAT_DC4K_24 ,
138 };
139 
141 {
142  unsigned int num_formats = sizeof(ff_schro_video_formats) /
143  sizeof(ff_schro_video_formats[0]);
144 
145  unsigned int idx = get_video_format_idx(avctx);
146 
147  return (idx < num_formats) ? ff_schro_video_formats[idx] :
148  SCHRO_VIDEO_FORMAT_CUSTOM;
149 }
150 
152  SchroFrameFormat *schro_frame_fmt)
153 {
154  unsigned int num_formats = sizeof(schro_pixel_format_map) /
155  sizeof(schro_pixel_format_map[0]);
156 
157  int idx;
158 
159  for (idx = 0; idx < num_formats; ++idx) {
160  if (schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) {
161  *schro_frame_fmt = schro_pixel_format_map[idx].schro_frame_fmt;
162  return 0;
163  }
164  }
165  return -1;
166 }
167 
168 static void free_schro_frame(SchroFrame *frame, void *priv)
169 {
170  AVPicture *p_pic = priv;
171 
172  if (!p_pic)
173  return;
174 
175  avpicture_free(p_pic);
176  av_freep(&p_pic);
177 }
178 
180  SchroFrameFormat schro_frame_fmt)
181 {
182  AVPicture *p_pic;
183  SchroFrame *p_frame;
184  int y_width, uv_width;
185  int y_height, uv_height;
186  int i;
187 
188  y_width = avctx->width;
189  y_height = avctx->height;
190  uv_width = y_width >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt));
191  uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt));
192 
193  p_pic = av_mallocz(sizeof(AVPicture));
194  if (!p_pic || avpicture_alloc(p_pic, avctx->pix_fmt, y_width, y_height) < 0) {
195  av_free(p_pic);
196  return NULL;
197  }
198 
199  p_frame = schro_frame_new();
200  p_frame->format = schro_frame_fmt;
201  p_frame->width = y_width;
202  p_frame->height = y_height;
203  schro_frame_set_free_callback(p_frame, free_schro_frame, (void *)p_pic);
204 
205  for (i = 0; i < 3; ++i) {
206  p_frame->components[i].width = i ? uv_width : y_width;
207  p_frame->components[i].stride = p_pic->linesize[i];
208  p_frame->components[i].height = i ? uv_height : y_height;
209  p_frame->components[i].length =
210  p_frame->components[i].stride * p_frame->components[i].height;
211  p_frame->components[i].data = p_pic->data[i];
212 
213  if (i) {
214  p_frame->components[i].v_shift =
215  SCHRO_FRAME_FORMAT_V_SHIFT(p_frame->format);
216  p_frame->components[i].h_shift =
217  SCHRO_FRAME_FORMAT_H_SHIFT(p_frame->format);
218  }
219  }
220 
221  return p_frame;
222 }