FFmpeg  4.4.5
imx.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/common.h"
22 #include "avcodec.h"
23 #include "bytestream.h"
24 #include "internal.h"
25 
26 typedef struct SimbiosisIMXContext {
28  uint32_t pal[256];
29  uint8_t history[32768];
30  int pos;
32 
34 {
35  SimbiosisIMXContext *imx = avctx->priv_data;
36 
37  avctx->pix_fmt = AV_PIX_FMT_PAL8;
38  avctx->width = 320;
39  avctx->height = 160;
40 
41  imx->frame = av_frame_alloc();
42  if (!imx->frame)
43  return AVERROR(ENOMEM);
44 
45  return 0;
46 }
47 
48 static int imx_decode_frame(AVCodecContext *avctx, void *data,
49  int *got_frame, AVPacket *avpkt)
50 {
51  SimbiosisIMXContext *imx = avctx->priv_data;
52  int ret, x, y;
53  buffer_size_t pal_size;
54  const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &pal_size);
55  AVFrame *frame = imx->frame;
56  GetByteContext gb;
57 
58  if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0)
59  return ret;
60 
61  if (pal && pal_size == AVPALETTE_SIZE) {
62  memcpy(imx->pal, pal, pal_size);
64  frame->key_frame = 1;
65  } else {
66  frame->key_frame = 0;
68  }
69 
70  bytestream2_init(&gb, avpkt->data, avpkt->size);
71 
72  memcpy(frame->data[1], imx->pal, AVPALETTE_SIZE);
73 
74  x = 0, y = 0;
75  while (bytestream2_get_bytes_left(&gb) > 0 &&
76  x < 320 && y < 160) {
77  int b = bytestream2_get_byte(&gb);
78  int len = b & 0x3f;
79  int op = b >> 6;
80  int fill;
81 
82  switch (op) {
83  case 3:
84  len = len * 64 + bytestream2_get_byte(&gb);
85  case 0:
86  while (len > 0) {
87  x++;
88  len--;
89  if (x >= 320) {
90  x = 0;
91  y++;
92  }
93  if (y >= 160)
94  break;
95  }
96 
97  frame->key_frame = 0;
98  break;
99  case 1:
100  if (len == 0) {
101  int offset = bytestream2_get_le16(&gb);
102 
103  if (offset < 0 || offset >= 32768)
104  return AVERROR_INVALIDDATA;
105 
106  len = bytestream2_get_byte(&gb);
107  while (len > 0 && offset < 32768) {
108  frame->data[0][x + y * frame->linesize[0]] = imx->history[offset++];
109  x++;
110  len--;
111  if (x >= 320) {
112  x = 0;
113  y++;
114  }
115  if (y >= 160)
116  break;
117  }
118 
119  frame->key_frame = 0;
120  } else {
121  while (len > 0) {
122  fill = bytestream2_get_byte(&gb);
123  frame->data[0][x + y * frame->linesize[0]] = fill;
124  if (imx->pos < 32768)
125  imx->history[imx->pos++] = fill;
126  x++;
127  len--;
128  if (x >= 320) {
129  x = 0;
130  y++;
131  }
132  if (y >= 160)
133  break;
134  }
135  }
136  break;
137  case 2:
138  fill = bytestream2_get_byte(&gb);
139 
140  while (len > 0) {
141  frame->data[0][x + y * frame->linesize[0]] = fill;
142  x++;
143  len--;
144  if (x >= 320) {
145  x = 0;
146  y++;
147  }
148  if (y >= 160)
149  break;
150  }
151  break;
152  }
153  }
154 
156 
157  if ((ret = av_frame_ref(data, frame)) < 0)
158  return ret;
159 
160  *got_frame = 1;
161 
162  return avpkt->size;
163 }
164 
165 static void imx_decode_flush(AVCodecContext *avctx)
166 {
167  SimbiosisIMXContext *imx = avctx->priv_data;
168 
169  av_frame_unref(imx->frame);
170  imx->pos = 0;
171  memset(imx->pal, 0, sizeof(imx->pal));
172  memset(imx->history, 0, sizeof(imx->history));
173 }
174 
176 {
177  SimbiosisIMXContext *imx = avctx->priv_data;
178 
179  av_frame_free(&imx->frame);
180 
181  return 0;
182 }
183 
185  .name = "simbiosis_imx",
186  .long_name = NULL_IF_CONFIG_SMALL("Simbiosis Interactive IMX Video"),
187  .type = AVMEDIA_TYPE_VIDEO,
189  .priv_data_size = sizeof(SimbiosisIMXContext),
192  .close = imx_decode_close,
194  .capabilities = AV_CODEC_CAP_DR1,
195  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
197 };
static void flush(AVCodecContext *avctx)
#define av_cold
Definition: attributes.h:88
uint8_t
Libavcodec external API header.
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, buffer_size_t *size)
Definition: avpacket.c:368
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
common internal and external API header
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition: decode.c:2007
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static AVFrame * frame
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
@ AV_CODEC_ID_SIMBIOSIS_IMX
Definition: codec_id.h:308
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition: packet.h:46
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:443
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:75
static void imx_decode_flush(AVCodecContext *avctx)
Definition: imx.c:165
static av_cold int imx_decode_init(AVCodecContext *avctx)
Definition: imx.c:33
static int imx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: imx.c:48
static int imx_decode_close(AVCodecContext *avctx)
Definition: imx.c:175
AVCodec ff_simbiosis_imx_decoder
Definition: imx.c:184
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:41
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:49
common internal API header
int buffer_size_t
Definition: internal.h:306
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
const char data[16]
Definition: mxf.c:142
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
main external API structure.
Definition: avcodec.h:536
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
int width
picture width / height.
Definition: avcodec.h:709
void * priv_data
Definition: avcodec.h:563
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:396
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:475
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:401
This structure stores compressed data.
Definition: packet.h:346
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
AVFrame * frame
Definition: imx.c:27
uint32_t pal[256]
Definition: imx.c:28
uint8_t history[32768]
Definition: imx.c:29
const char * b
Definition: vf_curves.c:118
static const uint8_t offset[127][2]
Definition: vf_spp.c:107
int len