annotate libschroedingerdec.c @ 8790:1045a26cb90d libavcodec

Fix crash when encoding using libschroedinger. Currently only pixel and half-pixel motion vector precisions are supported in libschroedinger. Setting the mv_precision field to 2 (i.e. quarter pixel) causes a crash in the libschroedinger encoder calls. By not setting this parameter, we fall back to the default value used in libschroedinger. patch by Anuradha Suraparaju, anuradha rd.bbc.co uk
author diego
date Tue, 10 Feb 2009 14:27:16 +0000
parents e9d9d946f213
children 043574c5c153
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
1 /*
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
2 * Dirac decoder support via Schroedinger libraries
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
3 * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
4 *
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
5 * This file is part of FFmpeg.
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
6 *
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
11 *
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
15 * Lesser General Public License for more details.
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
16 *
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
20 */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
21
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
22 /**
8718
e9d9d946f213 Use full internal pathname in doxygen @file directives.
diego
parents: 8422
diff changeset
23 * @file libavcodec/libschroedingerdec.c
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
24 * Dirac decoder support via libschroedinger-1.0 libraries. More details about
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
25 * the Schroedinger project can be found at http://www.diracvideo.org/.
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
26 * The library implements Dirac Specification Version 2.2.
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
27 * (http://dirac.sourceforge.net/specification.html).
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
28 */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
29
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
30 #include "avcodec.h"
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
31 #include "libdirac_libschro.h"
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
32 #include "libschroedinger.h"
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
33
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
34 #undef NDEBUG
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
35 #include <assert.h>
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
36
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
37
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
38 #include <schroedinger/schro.h>
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
39 #include <schroedinger/schrodebug.h>
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
40 #include <schroedinger/schrovideoformat.h>
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
41
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
42 /** libschroedinger decoder private data */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
43 typedef struct FfmpegSchroDecoderParams
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
44 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
45 /** Schroedinger video format */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
46 SchroVideoFormat *format;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
47
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
48 /** Schroedinger frame format */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
49 SchroFrameFormat frame_format;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
50
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
51 /** decoder handle */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
52 SchroDecoder* decoder;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
53
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
54 /** queue storing decoded frames */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
55 FfmpegDiracSchroQueue dec_frame_queue;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
56
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
57 /** end of sequence signalled */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
58 int eos_signalled;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
59
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
60 /** end of sequence pulled */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
61 int eos_pulled;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
62
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
63 /** decoded picture */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
64 AVPicture dec_pic;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
65 } FfmpegSchroDecoderParams;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
66
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
67 typedef struct FfmpegSchroParseUnitContext
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
68 {
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
69 const uint8_t *buf;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
70 int buf_size;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
71 } FfmpegSchroParseUnitContext;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
72
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
73
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
74 static void libschroedinger_decode_buffer_free (SchroBuffer *schro_buf,
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
75 void *priv);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
76
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
77 static void FfmpegSchroParseContextInit (FfmpegSchroParseUnitContext *parse_ctx,
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
78 const uint8_t *buf, int buf_size)
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
79 {
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
80 parse_ctx->buf = buf;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
81 parse_ctx->buf_size = buf_size;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
82 }
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
83
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
84 static SchroBuffer* FfmpegFindNextSchroParseUnit (FfmpegSchroParseUnitContext *parse_ctx)
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
85 {
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
86 SchroBuffer *enc_buf = NULL;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
87 int next_pu_offset = 0;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
88 unsigned char *in_buf;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
89
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
90 if (parse_ctx->buf_size < 13 ||
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
91 parse_ctx->buf[0] != 'B' ||
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
92 parse_ctx->buf[1] != 'B' ||
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
93 parse_ctx->buf[2] != 'C' ||
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
94 parse_ctx->buf[3] != 'D')
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
95 return NULL;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
96
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
97 next_pu_offset = (parse_ctx->buf[5] << 24) +
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
98 (parse_ctx->buf[6] << 16) +
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
99 (parse_ctx->buf[7] << 8) +
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
100 parse_ctx->buf[8];
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
101
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
102 if (next_pu_offset == 0 &&
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
103 SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4]))
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
104 next_pu_offset = 13;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
105
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
106 if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset)
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
107 return NULL;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
108
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
109 in_buf = av_malloc(next_pu_offset);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
110 memcpy (in_buf, parse_ctx->buf, next_pu_offset);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
111 enc_buf = schro_buffer_new_with_data (in_buf, next_pu_offset);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
112 enc_buf->free = libschroedinger_decode_buffer_free;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
113 enc_buf->priv = in_buf;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
114
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
115 parse_ctx->buf += next_pu_offset;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
116 parse_ctx->buf_size -= next_pu_offset;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
117
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
118 return enc_buf;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
119 }
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
120
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
121 /**
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
122 * Returns FFmpeg chroma format.
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
123 */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
124 static enum PixelFormat GetFfmpegChromaFormat(SchroChromaFormat schro_pix_fmt)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
125 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
126 int num_formats = sizeof(ffmpeg_schro_pixel_format_map) /
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
127 sizeof(ffmpeg_schro_pixel_format_map[0]);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
128 int idx;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
129
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
130 for (idx = 0; idx < num_formats; ++idx) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
131 if (ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
132 return ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
133 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
134 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
135 return PIX_FMT_NONE;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
136 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
137
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
138 static int libschroedinger_decode_init(AVCodecContext *avccontext)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
139 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
140
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
141 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data ;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
142 /* First of all, initialize our supporting libraries. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
143 schro_init();
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
144
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
145 schro_debug_set_level(avccontext->debug);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
146 p_schro_params->decoder = schro_decoder_new();
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
147 schro_decoder_set_skip_ratio(p_schro_params->decoder, 1);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
148
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
149 if (!p_schro_params->decoder)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
150 return -1;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
151
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
152 /* Initialize the decoded frame queue. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
153 ff_dirac_schro_queue_init (&p_schro_params->dec_frame_queue);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
154 return 0 ;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
155 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
156
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
157 static void libschroedinger_decode_buffer_free (SchroBuffer *schro_buf,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
158 void *priv)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
159 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
160 av_freep(&priv);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
161 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
162
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
163 static void libschroedinger_decode_frame_free (void *frame)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
164 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
165 schro_frame_unref(frame);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
166 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
167
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
168 static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
169 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
170 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
171 SchroDecoder *decoder = p_schro_params->decoder;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
172
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
173 p_schro_params->format = schro_decoder_get_video_format (decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
174
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
175 /* Tell FFmpeg about sequence details. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
176 if(avcodec_check_dimensions(avccontext, p_schro_params->format->width,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
177 p_schro_params->format->height) < 0) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
178 av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
179 p_schro_params->format->width, p_schro_params->format->height);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
180 avccontext->height = avccontext->width = 0;
6754
7094ae690809 Do not return -1 from void functions.
cehoyos
parents: 6738
diff changeset
181 return;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
182 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
183 avccontext->height = p_schro_params->format->height;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
184 avccontext->width = p_schro_params->format->width;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
185 avccontext->pix_fmt =
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
186 GetFfmpegChromaFormat(p_schro_params->format->chroma_format);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
187
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
188 if (ff_get_schro_frame_format( p_schro_params->format->chroma_format,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
189 &p_schro_params->frame_format) == -1) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
190 av_log (avccontext, AV_LOG_ERROR,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
191 "This codec currently only supports planar YUV 4:2:0, 4:2:2 "
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
192 "and 4:4:4 formats.\n");
6754
7094ae690809 Do not return -1 from void functions.
cehoyos
parents: 6738
diff changeset
193 return;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
194 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
195
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
196 avccontext->time_base.den = p_schro_params->format->frame_rate_numerator;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
197 avccontext->time_base.num = p_schro_params->format->frame_rate_denominator;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
198
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
199 if (p_schro_params->dec_pic.data[0] == NULL)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
200 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
201 avpicture_alloc(&p_schro_params->dec_pic,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
202 avccontext->pix_fmt,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
203 avccontext->width,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
204 avccontext->height);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
205 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
206 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
207
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
208 static int libschroedinger_decode_frame(AVCodecContext *avccontext,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
209 void *data, int *data_size,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
210 const uint8_t *buf, int buf_size)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
211 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
212
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
213 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
214 SchroDecoder *decoder = p_schro_params->decoder;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
215 SchroVideoFormat *format;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
216 AVPicture *picture = data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
217 SchroBuffer *enc_buf;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
218 SchroFrame* frame;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
219 int state;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
220 int go = 1;
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
221 int outer = 1;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
222 FfmpegSchroParseUnitContext parse_ctx;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
223
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
224 *data_size = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
225
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
226 FfmpegSchroParseContextInit (&parse_ctx, buf, buf_size);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
227 if (buf_size == 0) {
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
228 if (!p_schro_params->eos_signalled) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
229 state = schro_decoder_push_end_of_stream(decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
230 p_schro_params->eos_signalled = 1;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
231 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
232 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
233
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
234 /* Loop through all the individual parse units in the input buffer */
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
235 do {
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
236 if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) {
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
237 /* Push buffer into decoder. */
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 7234
diff changeset
238 if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 7234
diff changeset
239 SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 7234
diff changeset
240 avccontext->has_b_frames = 1;
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
241 state = schro_decoder_push (decoder, enc_buf);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
242 if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
243 libschroedinger_handle_first_access_unit(avccontext);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
244 go = 1;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
245 }
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
246 else
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
247 outer = 0;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
248 format = p_schro_params->format;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
249
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
250 while (go) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
251 /* Parse data and process result. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
252 state = schro_decoder_wait (decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
253 switch (state)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
254 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
255 case SCHRO_DECODER_FIRST_ACCESS_UNIT:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
256 libschroedinger_handle_first_access_unit (avccontext);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
257 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
258
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
259 case SCHRO_DECODER_NEED_BITS:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
260 /* Need more input data - stop iterating over what we have. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
261 go = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
262 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
263
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
264 case SCHRO_DECODER_NEED_FRAME:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
265 /* Decoder needs a frame - create one and push it in. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
266
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
267 frame = schro_frame_new_and_alloc(NULL,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
268 p_schro_params->frame_format,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
269 format->width,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
270 format->height);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
271 schro_decoder_add_output_picture (decoder, frame);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
272 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
273
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
274 case SCHRO_DECODER_OK:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
275 /* Pull a frame out of the decoder. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
276 frame = schro_decoder_pull (decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
277
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
278 if (frame) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
279 ff_dirac_schro_queue_push_back(
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
280 &p_schro_params->dec_frame_queue,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
281 frame);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
282 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
283 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
284 case SCHRO_DECODER_EOS:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
285 go = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
286 p_schro_params->eos_pulled = 1;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
287 schro_decoder_reset (decoder);
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
288 outer = 0;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
289 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
290
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
291 case SCHRO_DECODER_ERROR:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
292 return -1;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
293 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
294 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
295 }
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
296 } while(outer);
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
297
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
298 /* Grab next frame to be returned from the top of the queue. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
299 frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
300
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
301 if (frame != NULL) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
302 memcpy (p_schro_params->dec_pic.data[0],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
303 frame->components[0].data,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
304 frame->components[0].length);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
305
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
306 memcpy (p_schro_params->dec_pic.data[1],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
307 frame->components[1].data,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
308 frame->components[1].length);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
309
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
310 memcpy (p_schro_params->dec_pic.data[2],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
311 frame->components[2].data,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
312 frame->components[2].length);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
313
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
314 /* Fill picture with current buffer data from Schroedinger. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
315 avpicture_fill(picture, p_schro_params->dec_pic.data[0],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
316 avccontext->pix_fmt,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
317 avccontext->width, avccontext->height);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
318
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
319 *data_size = sizeof(AVPicture);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
320
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
321 /* Now free the frame resources. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
322 libschroedinger_decode_frame_free (frame);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
323 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
324 return buf_size;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
325 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
326
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
327
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
328 static int libschroedinger_decode_close(AVCodecContext *avccontext)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
329 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
330 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
331 /* Free the decoder. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
332 schro_decoder_free (p_schro_params->decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
333 av_freep(&p_schro_params->format);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
334
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
335 avpicture_free (&p_schro_params->dec_pic);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
336
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
337 /* Free data in the output frame queue. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
338 ff_dirac_schro_queue_free (&p_schro_params->dec_frame_queue,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
339 libschroedinger_decode_frame_free);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
340
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
341 return 0 ;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
342 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
343
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
344 static void libschroedinger_flush (AVCodecContext *avccontext)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
345 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
346 /* Got a seek request. Free the decoded frames queue and then reset
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
347 * the decoder */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
348 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
349
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
350 /* Free data in the output frame queue. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
351 ff_dirac_schro_queue_free (&p_schro_params->dec_frame_queue,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
352 libschroedinger_decode_frame_free);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
353
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
354 ff_dirac_schro_queue_init (&p_schro_params->dec_frame_queue);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
355 schro_decoder_reset(p_schro_params->decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
356 p_schro_params->eos_pulled = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
357 p_schro_params->eos_signalled = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
358 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
359
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
360 AVCodec libschroedinger_decoder = {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
361 "libschroedinger",
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
362 CODEC_TYPE_VIDEO,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
363 CODEC_ID_DIRAC,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
364 sizeof(FfmpegSchroDecoderParams),
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
365 libschroedinger_decode_init,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
366 NULL,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
367 libschroedinger_decode_close,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
368 libschroedinger_decode_frame,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
369 CODEC_CAP_DELAY,
6819
43bede126ef6 missing codec long names by Stefano Sabatini, stefano.sabatini-lala poste it
diego
parents: 6757
diff changeset
370 .flush = libschroedinger_flush,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6819
diff changeset
371 .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
372 };