annotate libschroedingerdec.c @ 9899:06ab8ac1a593 libavcodec

Fix libx264.c to not drop SEI userdata from x264 encoder. Most muxers in ffmpeg ignore the SEI if it is placed in extradata, so instead it has to be catted to the front of the first video frame.
author darkshikari
date Tue, 30 Jun 2009 23:45:01 +0000
parents 54bc8a2727b0
children fdb318d12314
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
9007
043574c5c153 Add missing av_cold in static init/close functions.
stefano
parents: 8718
diff changeset
138 static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext)
6738
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,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9007
diff changeset
210 AVPacket *avpkt)
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
211 {
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9007
diff changeset
212 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9007
diff changeset
213 int buf_size = avpkt->size;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
214
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
215 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
216 SchroDecoder *decoder = p_schro_params->decoder;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
217 SchroVideoFormat *format;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
218 AVPicture *picture = data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
219 SchroBuffer *enc_buf;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
220 SchroFrame* frame;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
221 int state;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
222 int go = 1;
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
223 int outer = 1;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
224 FfmpegSchroParseUnitContext parse_ctx;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
225
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
226 *data_size = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
227
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
228 FfmpegSchroParseContextInit (&parse_ctx, buf, buf_size);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
229 if (buf_size == 0) {
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
230 if (!p_schro_params->eos_signalled) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
231 state = schro_decoder_push_end_of_stream(decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
232 p_schro_params->eos_signalled = 1;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
233 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
234 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
235
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
236 /* 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
237 do {
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
238 if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) {
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
239 /* Push buffer into decoder. */
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 7234
diff changeset
240 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
241 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
242 avccontext->has_b_frames = 1;
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
243 state = schro_decoder_push (decoder, enc_buf);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
244 if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
245 libschroedinger_handle_first_access_unit(avccontext);
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
246 go = 1;
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
247 }
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
248 else
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
249 outer = 0;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
250 format = p_schro_params->format;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
251
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
252 while (go) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
253 /* Parse data and process result. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
254 state = schro_decoder_wait (decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
255 switch (state)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
256 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
257 case SCHRO_DECODER_FIRST_ACCESS_UNIT:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
258 libschroedinger_handle_first_access_unit (avccontext);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
259 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
260
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
261 case SCHRO_DECODER_NEED_BITS:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
262 /* Need more input data - stop iterating over what we have. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
263 go = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
264 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
265
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
266 case SCHRO_DECODER_NEED_FRAME:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
267 /* Decoder needs a frame - create one and push it in. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
268
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
269 frame = schro_frame_new_and_alloc(NULL,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
270 p_schro_params->frame_format,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
271 format->width,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
272 format->height);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
273 schro_decoder_add_output_picture (decoder, frame);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
274 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
275
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
276 case SCHRO_DECODER_OK:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
277 /* Pull a frame out of the decoder. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
278 frame = schro_decoder_pull (decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
279
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
280 if (frame) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
281 ff_dirac_schro_queue_push_back(
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
282 &p_schro_params->dec_frame_queue,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
283 frame);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
284 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
285 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
286 case SCHRO_DECODER_EOS:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
287 go = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
288 p_schro_params->eos_pulled = 1;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
289 schro_decoder_reset (decoder);
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
290 outer = 0;
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
291 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
292
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
293 case SCHRO_DECODER_ERROR:
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
294 return -1;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
295 break;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
296 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
297 }
7234
dea986389c57 Parse frames to feed the decoder with individual parse units.
benoit
parents: 7040
diff changeset
298 } while(outer);
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
299
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
300 /* Grab next frame to be returned from the top of the queue. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
301 frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
302
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
303 if (frame != NULL) {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
304 memcpy (p_schro_params->dec_pic.data[0],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
305 frame->components[0].data,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
306 frame->components[0].length);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
307
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
308 memcpy (p_schro_params->dec_pic.data[1],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
309 frame->components[1].data,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
310 frame->components[1].length);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
311
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
312 memcpy (p_schro_params->dec_pic.data[2],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
313 frame->components[2].data,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
314 frame->components[2].length);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
315
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
316 /* Fill picture with current buffer data from Schroedinger. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
317 avpicture_fill(picture, p_schro_params->dec_pic.data[0],
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
318 avccontext->pix_fmt,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
319 avccontext->width, avccontext->height);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
320
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
321 *data_size = sizeof(AVPicture);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
322
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
323 /* Now free the frame resources. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
324 libschroedinger_decode_frame_free (frame);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
325 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
326 return buf_size;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
327 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
328
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
329
9007
043574c5c153 Add missing av_cold in static init/close functions.
stefano
parents: 8718
diff changeset
330 static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
331 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
332 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
333 /* Free the decoder. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
334 schro_decoder_free (p_schro_params->decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
335 av_freep(&p_schro_params->format);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
336
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
337 avpicture_free (&p_schro_params->dec_pic);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
338
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
339 /* Free data in the output frame queue. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
340 ff_dirac_schro_queue_free (&p_schro_params->dec_frame_queue,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
341 libschroedinger_decode_frame_free);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
342
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
343 return 0 ;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
344 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
345
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
346 static void libschroedinger_flush (AVCodecContext *avccontext)
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
347 {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
348 /* Got a seek request. Free the decoded frames queue and then reset
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
349 * the decoder */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
350 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
351
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
352 /* Free data in the output frame queue. */
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
353 ff_dirac_schro_queue_free (&p_schro_params->dec_frame_queue,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
354 libschroedinger_decode_frame_free);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
355
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
356 ff_dirac_schro_queue_init (&p_schro_params->dec_frame_queue);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
357 schro_decoder_reset(p_schro_params->decoder);
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
358 p_schro_params->eos_pulled = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
359 p_schro_params->eos_signalled = 0;
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
360 }
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
361
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
362 AVCodec libschroedinger_decoder = {
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
363 "libschroedinger",
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
364 CODEC_TYPE_VIDEO,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
365 CODEC_ID_DIRAC,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
366 sizeof(FfmpegSchroDecoderParams),
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
367 libschroedinger_decode_init,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
368 NULL,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
369 libschroedinger_decode_close,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
370 libschroedinger_decode_frame,
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
371 CODEC_CAP_DELAY,
6819
43bede126ef6 missing codec long names by Stefano Sabatini, stefano.sabatini-lala poste it
diego
parents: 6757
diff changeset
372 .flush = libschroedinger_flush,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6819
diff changeset
373 .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
6738
bdacae101076 Add Dirac support through libschroedinger.
diego
parents:
diff changeset
374 };