1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 BayLibre, SAS
4 * Author: Maxime Jourdan <mjourdan@baylibre.com>
5 */
6
7#include <media/v4l2-mem2mem.h>
8#include <media/videobuf2-dma-contig.h>
9
10#include "vdec_helpers.h"
11#include "dos_regs.h"
12#include "codec_h264.h"
13
14#define SIZE_EXT_FW	(20 * SZ_1K)
15#define SIZE_WORKSPACE	0x1ee000
16#define SIZE_SEI	(8 * SZ_1K)
17
18/*
19 * Offset added by the firmware which must be substracted
20 * from the workspace phyaddr
21 */
22#define WORKSPACE_BUF_OFFSET	0x1000000
23
24/* ISR status */
25#define CMD_MASK		GENMASK(7, 0)
26#define CMD_SRC_CHANGE		1
27#define CMD_FRAMES_READY	2
28#define CMD_FATAL_ERROR		6
29#define CMD_BAD_WIDTH		7
30#define CMD_BAD_HEIGHT		8
31
32#define SEI_DATA_READY	BIT(15)
33
34/* Picture type */
35#define PIC_TOP_BOT	5
36#define PIC_BOT_TOP	6
37
38/* Size of Motion Vector per macroblock */
39#define MB_MV_SIZE	96
40
41/* Frame status data */
42#define PIC_STRUCT_BIT	5
43#define PIC_STRUCT_MASK	GENMASK(2, 0)
44#define BUF_IDX_MASK	GENMASK(4, 0)
45#define ERROR_FLAG	BIT(9)
46#define OFFSET_BIT	16
47#define OFFSET_MASK	GENMASK(15, 0)
48
49/* Bitstream parsed data */
50#define MB_TOTAL_BIT	8
51#define MB_TOTAL_MASK	GENMASK(15, 0)
52#define MB_WIDTH_MASK	GENMASK(7, 0)
53#define MAX_REF_BIT	24
54#define MAX_REF_MASK	GENMASK(6, 0)
55#define AR_IDC_BIT	16
56#define AR_IDC_MASK	GENMASK(7, 0)
57#define AR_PRESENT_FLAG	BIT(0)
58#define AR_EXTEND	0xff
59
60/*
61 * Buffer to send to the ESPARSER to signal End Of Stream for H.264.
62 * This is a 16x16 encoded picture that will trigger drain firmware-side.
63 * There is no known alternative.
64 */
65static const u8 eos_sequence[SZ_4K] = {
66	0x00, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xe4, 0xdc, 0x45, 0xe9, 0xbd,
67	0xe6, 0xd9, 0x48, 0xb7,	0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef,
68	0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63,	0x6f, 0x72, 0x65, 0x20,
69	0x36, 0x37, 0x20, 0x72, 0x31, 0x31, 0x33, 0x30, 0x20, 0x38, 0x34, 0x37,
70	0x35, 0x39, 0x37, 0x37, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34,
71	0x2f, 0x4d, 0x50, 0x45,	0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20,
72	0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20,	0x43, 0x6f, 0x70, 0x79,
73	0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30,
74	0x30, 0x39, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
75	0x77, 0x77, 0x77, 0x2e,	0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e,
76	0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36,	0x34, 0x2e, 0x68, 0x74,
77	0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
78	0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d, 0x31, 0x20, 0x72, 0x65,
79	0x66, 0x3d, 0x31, 0x20,	0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3d,
80	0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e,	0x61, 0x6c, 0x79, 0x73,
81	0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20,
82	0x6d, 0x65, 0x3d, 0x68, 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65,
83	0x3d, 0x36, 0x20, 0x70,	0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e,
84	0x30, 0x3a, 0x30, 0x2e, 0x30, 0x20, 0x6d, 0x69,	0x78, 0x65, 0x64, 0x5f,
85	0x72, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e,
86	0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61,
87	0x5f, 0x6d, 0x65, 0x3d,	0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
88	0x73, 0x3d, 0x30, 0x20, 0x38, 0x78, 0x38, 0x64,	0x63, 0x74, 0x3d, 0x30,
89	0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a,
90	0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x63, 0x68,
91	0x72, 0x6f, 0x6d, 0x61,	0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73,
92	0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68,	0x72, 0x65, 0x61, 0x64,
93	0x73, 0x3d, 0x31, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63,
94	0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x6d, 0x62, 0x61, 0x66,
95	0x66, 0x3d, 0x30, 0x20,	0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d,
96	0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74,	0x3d, 0x32, 0x35, 0x30,
97	0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d,
98	0x32, 0x35, 0x20, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x63, 0x75, 0x74, 0x3d,
99	0x34, 0x30, 0x20, 0x72,	0x63, 0x3d, 0x61, 0x62, 0x72, 0x20, 0x62, 0x69,
100	0x74, 0x72, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x30,	0x20, 0x72, 0x61, 0x74,
101	0x65, 0x74, 0x6f, 0x6c, 0x3d, 0x31, 0x2e, 0x30, 0x20, 0x71, 0x63, 0x6f,
102	0x6d, 0x70, 0x3d, 0x30, 0x2e, 0x36, 0x30, 0x20, 0x71, 0x70, 0x6d, 0x69,
103	0x6e, 0x3d, 0x31, 0x30,	0x20, 0x71, 0x70, 0x6d, 0x61, 0x78, 0x3d, 0x35,
104	0x31, 0x20, 0x71, 0x70, 0x73, 0x74, 0x65, 0x70,	0x3d, 0x34, 0x20, 0x69,
105	0x70, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x3d, 0x31, 0x2e, 0x34, 0x30,
106	0x20, 0x61, 0x71, 0x3d, 0x31, 0x3a, 0x31, 0x2e, 0x30, 0x30, 0x00, 0x80,
107	0x00, 0x00, 0x00, 0x01,	0x67, 0x4d, 0x40, 0x0a, 0x9a, 0x74, 0xf4, 0x20,
108	0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x06,	0x51, 0xe2, 0x44, 0xd4,
109	0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x32, 0xc8, 0x00, 0x00, 0x00, 0x01,
110	0x65, 0x88, 0x80, 0x20, 0x00, 0x08, 0x7f, 0xea, 0x6a, 0xe2, 0x99, 0xb6,
111	0x57, 0xae, 0x49, 0x30,	0xf5, 0xfe, 0x5e, 0x46, 0x0b, 0x72, 0x44, 0xc4,
112	0xe1, 0xfc, 0x62, 0xda, 0xf1, 0xfb, 0xa2, 0xdb,	0xd6, 0xbe, 0x5c, 0xd7,
113	0x24, 0xa3, 0xf5, 0xb9, 0x2f, 0x57, 0x16, 0x49, 0x75, 0x47, 0x77, 0x09,
114	0x5c, 0xa1, 0xb4, 0xc3, 0x4f, 0x60, 0x2b, 0xb0, 0x0c, 0xc8, 0xd6, 0x66,
115	0xba, 0x9b, 0x82, 0x29,	0x33, 0x92, 0x26, 0x99, 0x31, 0x1c, 0x7f, 0x9b,
116	0x00, 0x00, 0x01, 0x0ff,
117};
118
119static const u8 *codec_h264_eos_sequence(u32 *len)
120{
121	*len = ARRAY_SIZE(eos_sequence);
122	return eos_sequence;
123}
124
125struct codec_h264 {
126	/* H.264 decoder requires an extended firmware */
127	void      *ext_fw_vaddr;
128	dma_addr_t ext_fw_paddr;
129
130	/* Buffer for the H.264 Workspace */
131	void      *workspace_vaddr;
132	dma_addr_t workspace_paddr;
133
134	/* Buffer for the H.264 references MV */
135	void      *ref_vaddr;
136	dma_addr_t ref_paddr;
137	u32	   ref_size;
138
139	/* Buffer for parsed SEI data */
140	void      *sei_vaddr;
141	dma_addr_t sei_paddr;
142
143	u32 mb_width;
144	u32 mb_height;
145	u32 max_refs;
146};
147
148static int codec_h264_can_recycle(struct amvdec_core *core)
149{
150	return !amvdec_read_dos(core, AV_SCRATCH_7) ||
151	       !amvdec_read_dos(core, AV_SCRATCH_8);
152}
153
154static void codec_h264_recycle(struct amvdec_core *core, u32 buf_idx)
155{
156	/*
157	 * Tell the firmware it can recycle this buffer.
158	 * AV_SCRATCH_8 serves the same purpose.
159	 */
160	if (!amvdec_read_dos(core, AV_SCRATCH_7))
161		amvdec_write_dos(core, AV_SCRATCH_7, buf_idx + 1);
162	else
163		amvdec_write_dos(core, AV_SCRATCH_8, buf_idx + 1);
164}
165
166static int codec_h264_start(struct amvdec_session *sess)
167{
168	u32 workspace_offset;
169	struct amvdec_core *core = sess->core;
170	struct codec_h264 *h264 = sess->priv;
171
172	/* Allocate some memory for the H.264 decoder's state */
173	h264->workspace_vaddr =
174		dma_alloc_coherent(core->dev, SIZE_WORKSPACE,
175				   &h264->workspace_paddr, GFP_KERNEL);
176	if (!h264->workspace_vaddr)
177		return -ENOMEM;
178
179	/* Allocate some memory for the H.264 SEI dump */
180	h264->sei_vaddr = dma_alloc_coherent(core->dev, SIZE_SEI,
181					     &h264->sei_paddr, GFP_KERNEL);
182	if (!h264->sei_vaddr)
183		return -ENOMEM;
184
185	amvdec_write_dos_bits(core, POWER_CTL_VLD, BIT(9) | BIT(6));
186
187	workspace_offset = h264->workspace_paddr - WORKSPACE_BUF_OFFSET;
188	amvdec_write_dos(core, AV_SCRATCH_1, workspace_offset);
189	amvdec_write_dos(core, AV_SCRATCH_G, h264->ext_fw_paddr);
190	amvdec_write_dos(core, AV_SCRATCH_I, h264->sei_paddr -
191					     workspace_offset);
192
193	/* Enable "error correction" */
194	amvdec_write_dos(core, AV_SCRATCH_F,
195			 (amvdec_read_dos(core, AV_SCRATCH_F) & 0xffffffc3) |
196			 BIT(4) | BIT(7));
197
198	amvdec_write_dos(core, MDEC_PIC_DC_THRESH, 0x404038aa);
199
200	return 0;
201}
202
203static int codec_h264_stop(struct amvdec_session *sess)
204{
205	struct codec_h264 *h264 = sess->priv;
206	struct amvdec_core *core = sess->core;
207
208	if (h264->ext_fw_vaddr)
209		dma_free_coherent(core->dev, SIZE_EXT_FW,
210				  h264->ext_fw_vaddr, h264->ext_fw_paddr);
211
212	if (h264->workspace_vaddr)
213		dma_free_coherent(core->dev, SIZE_WORKSPACE,
214				  h264->workspace_vaddr, h264->workspace_paddr);
215
216	if (h264->ref_vaddr)
217		dma_free_coherent(core->dev, h264->ref_size,
218				  h264->ref_vaddr, h264->ref_paddr);
219
220	if (h264->sei_vaddr)
221		dma_free_coherent(core->dev, SIZE_SEI,
222				  h264->sei_vaddr, h264->sei_paddr);
223
224	return 0;
225}
226
227static int codec_h264_load_extended_firmware(struct amvdec_session *sess,
228					     const u8 *data, u32 len)
229{
230	struct codec_h264 *h264;
231	struct amvdec_core *core = sess->core;
232
233	if (len < SIZE_EXT_FW)
234		return -EINVAL;
235
236	h264 = kzalloc(sizeof(*h264), GFP_KERNEL);
237	if (!h264)
238		return -ENOMEM;
239
240	h264->ext_fw_vaddr = dma_alloc_coherent(core->dev, SIZE_EXT_FW,
241						&h264->ext_fw_paddr,
242						GFP_KERNEL);
243	if (!h264->ext_fw_vaddr) {
244		kfree(h264);
245		return -ENOMEM;
246	}
247
248	memcpy(h264->ext_fw_vaddr, data, SIZE_EXT_FW);
249	sess->priv = h264;
250
251	return 0;
252}
253
254static const struct v4l2_fract par_table[] = {
255	{ 1, 1 },   { 1, 1 },    { 12, 11 }, { 10, 11 },
256	{ 16, 11 }, { 40, 33 },  { 24, 11 }, { 20, 11 },
257	{ 32, 11 }, { 80, 33 },  { 18, 11 }, { 15, 11 },
258	{ 64, 33 }, { 160, 99 }, { 4, 3 },   { 3, 2 },
259	{ 2, 1 }
260};
261
262static void codec_h264_set_par(struct amvdec_session *sess)
263{
264	struct amvdec_core *core = sess->core;
265	u32 seq_info = amvdec_read_dos(core, AV_SCRATCH_2);
266	u32 ar_idc = (seq_info >> AR_IDC_BIT) & AR_IDC_MASK;
267
268	if (!(seq_info & AR_PRESENT_FLAG))
269		return;
270
271	if (ar_idc == AR_EXTEND) {
272		u32 ar_info = amvdec_read_dos(core, AV_SCRATCH_3);
273
274		sess->pixelaspect.numerator = ar_info & 0xffff;
275		sess->pixelaspect.denominator = (ar_info >> 16) & 0xffff;
276		return;
277	}
278
279	if (ar_idc >= ARRAY_SIZE(par_table))
280		return;
281
282	sess->pixelaspect = par_table[ar_idc];
283}
284
285static void codec_h264_resume(struct amvdec_session *sess)
286{
287	struct amvdec_core *core = sess->core;
288	struct codec_h264 *h264 = sess->priv;
289	u32 mb_width, mb_height, mb_total;
290
291	amvdec_set_canvases(sess,
292			    (u32[]){ ANC0_CANVAS_ADDR, 0 },
293			    (u32[]){ 24, 0 });
294
295	dev_dbg(core->dev, "max_refs = %u; actual_dpb_size = %u\n",
296		h264->max_refs, sess->num_dst_bufs);
297
298	/* Align to a multiple of 4 macroblocks */
299	mb_width = ALIGN(h264->mb_width, 4);
300	mb_height = ALIGN(h264->mb_height, 4);
301	mb_total = mb_width * mb_height;
302
303	h264->ref_size = mb_total * MB_MV_SIZE * h264->max_refs;
304	h264->ref_vaddr = dma_alloc_coherent(core->dev, h264->ref_size,
305					     &h264->ref_paddr, GFP_KERNEL);
306	if (!h264->ref_vaddr) {
307		amvdec_abort(sess);
308		return;
309	}
310
311	/* Address to store the references' MVs */
312	amvdec_write_dos(core, AV_SCRATCH_1, h264->ref_paddr);
313	/* End of ref MV */
314	amvdec_write_dos(core, AV_SCRATCH_4, h264->ref_paddr + h264->ref_size);
315
316	amvdec_write_dos(core, AV_SCRATCH_0, (h264->max_refs << 24) |
317					     (sess->num_dst_bufs << 16) |
318					     ((h264->max_refs - 1) << 8));
319}
320
321/*
322 * Configure the H.264 decoder when the parser detected a parameter set change
323 */
324static void codec_h264_src_change(struct amvdec_session *sess)
325{
326	struct amvdec_core *core = sess->core;
327	struct codec_h264 *h264 = sess->priv;
328	u32 parsed_info, mb_total;
329	u32 crop_infor, crop_bottom, crop_right;
330	u32 frame_width, frame_height;
331
332	sess->keyframe_found = 1;
333
334	parsed_info = amvdec_read_dos(core, AV_SCRATCH_1);
335
336	/* Total number of 16x16 macroblocks */
337	mb_total = (parsed_info >> MB_TOTAL_BIT) & MB_TOTAL_MASK;
338	/* Number of macroblocks per line */
339	h264->mb_width = parsed_info & MB_WIDTH_MASK;
340	/* Number of macroblock lines */
341	h264->mb_height = mb_total / h264->mb_width;
342
343	h264->max_refs = ((parsed_info >> MAX_REF_BIT) & MAX_REF_MASK) + 1;
344
345	crop_infor = amvdec_read_dos(core, AV_SCRATCH_6);
346	crop_bottom = (crop_infor & 0xff);
347	crop_right = (crop_infor >> 16) & 0xff;
348
349	frame_width = h264->mb_width * 16 - crop_right;
350	frame_height = h264->mb_height * 16 - crop_bottom;
351
352	dev_dbg(core->dev, "frame: %ux%u; crop: %u %u\n",
353		frame_width, frame_height, crop_right, crop_bottom);
354
355	codec_h264_set_par(sess);
356	amvdec_src_change(sess, frame_width, frame_height, h264->max_refs + 5);
357}
358
359/*
360 * The bitstream offset is split in half in 2 different registers.
361 * Fetch its MSB here, which location depends on the frame number.
362 */
363static u32 get_offset_msb(struct amvdec_core *core, int frame_num)
364{
365	int take_msb = frame_num % 2;
366	int reg_offset = (frame_num / 2) * 4;
367	u32 offset_msb = amvdec_read_dos(core, AV_SCRATCH_A + reg_offset);
368
369	if (take_msb)
370		return offset_msb & 0xffff0000;
371
372	return (offset_msb & 0x0000ffff) << 16;
373}
374
375static void codec_h264_frames_ready(struct amvdec_session *sess, u32 status)
376{
377	struct amvdec_core *core = sess->core;
378	int error_count;
379	int num_frames;
380	int i;
381
382	error_count = amvdec_read_dos(core, AV_SCRATCH_D);
383	num_frames = (status >> 8) & 0xff;
384	if (error_count) {
385		dev_warn(core->dev,
386			 "decoder error(s) happened, count %d\n", error_count);
387		amvdec_write_dos(core, AV_SCRATCH_D, 0);
388	}
389
390	for (i = 0; i < num_frames; i++) {
391		u32 frame_status = amvdec_read_dos(core, AV_SCRATCH_1 + i * 4);
392		u32 buffer_index = frame_status & BUF_IDX_MASK;
393		u32 pic_struct = (frame_status >> PIC_STRUCT_BIT) &
394				 PIC_STRUCT_MASK;
395		u32 offset = (frame_status >> OFFSET_BIT) & OFFSET_MASK;
396		u32 field = V4L2_FIELD_NONE;
397
398		/*
399		 * A buffer decode error means it was decoded,
400		 * but part of the picture will have artifacts.
401		 * Typical reason is a temporarily corrupted bitstream
402		 */
403		if (frame_status & ERROR_FLAG)
404			dev_dbg(core->dev, "Buffer %d decode error\n",
405				buffer_index);
406
407		if (pic_struct == PIC_TOP_BOT)
408			field = V4L2_FIELD_INTERLACED_TB;
409		else if (pic_struct == PIC_BOT_TOP)
410			field = V4L2_FIELD_INTERLACED_BT;
411
412		offset |= get_offset_msb(core, i);
413		amvdec_dst_buf_done_idx(sess, buffer_index, offset, field);
414	}
415}
416
417static irqreturn_t codec_h264_threaded_isr(struct amvdec_session *sess)
418{
419	struct amvdec_core *core = sess->core;
420	u32 status;
421	u32 size;
422	u8 cmd;
423
424	status = amvdec_read_dos(core, AV_SCRATCH_0);
425	cmd = status & CMD_MASK;
426
427	switch (cmd) {
428	case CMD_SRC_CHANGE:
429		codec_h264_src_change(sess);
430		break;
431	case CMD_FRAMES_READY:
432		codec_h264_frames_ready(sess, status);
433		break;
434	case CMD_FATAL_ERROR:
435		dev_err(core->dev, "H.264 decoder fatal error\n");
436		goto abort;
437	case CMD_BAD_WIDTH:
438		size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16;
439		dev_err(core->dev, "Unsupported video width: %u\n", size);
440		goto abort;
441	case CMD_BAD_HEIGHT:
442		size = (amvdec_read_dos(core, AV_SCRATCH_1) + 1) * 16;
443		dev_err(core->dev, "Unsupported video height: %u\n", size);
444		goto abort;
445	case 0: /* Unused but not worth printing for */
446	case 9:
447		break;
448	default:
449		dev_info(core->dev, "Unexpected H264 ISR: %08X\n", cmd);
450		break;
451	}
452
453	if (cmd && cmd != CMD_SRC_CHANGE)
454		amvdec_write_dos(core, AV_SCRATCH_0, 0);
455
456	/* Decoder has some SEI data for us ; ignore */
457	if (amvdec_read_dos(core, AV_SCRATCH_J) & SEI_DATA_READY)
458		amvdec_write_dos(core, AV_SCRATCH_J, 0);
459
460	return IRQ_HANDLED;
461abort:
462	amvdec_abort(sess);
463	return IRQ_HANDLED;
464}
465
466static irqreturn_t codec_h264_isr(struct amvdec_session *sess)
467{
468	struct amvdec_core *core = sess->core;
469
470	amvdec_write_dos(core, ASSIST_MBOX1_CLR_REG, 1);
471
472	return IRQ_WAKE_THREAD;
473}
474
475struct amvdec_codec_ops codec_h264_ops = {
476	.start = codec_h264_start,
477	.stop = codec_h264_stop,
478	.load_extended_firmware = codec_h264_load_extended_firmware,
479	.isr = codec_h264_isr,
480	.threaded_isr = codec_h264_threaded_isr,
481	.can_recycle = codec_h264_can_recycle,
482	.recycle = codec_h264_recycle,
483	.eos_sequence = codec_h264_eos_sequence,
484	.resume = codec_h264_resume,
485};
486