#include "a64tables.h"
#include "elbg.h"
#include "internal.h"
+#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
//static const int mc_colors[5]={0x0,0x8,0xa,0xf,0x7};
//static const int mc_colors[5]={0x0,0x9,0x8,0xa,0x3};
-static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest)
+static void to_meta_with_crop(AVCodecContext *avctx, const AVFrame *p, int *dest)
{
int blockx, blocky, x, y;
int luma = 0;
for (y = blocky; y < blocky + 8 && y < C64YRES; y++) {
for (x = blockx; x < blockx + 8 && x < C64XRES; x += 2) {
if(x < width && y < height) {
- /* build average over 2 pixels */
- luma = (src[(x + 0 + y * p->linesize[0])] +
- src[(x + 1 + y * p->linesize[0])]) / 2;
+ if (x + 1 < width) {
+ /* build average over 2 pixels */
+ luma = (src[(x + 0 + y * p->linesize[0])] +
+ src[(x + 1 + y * p->linesize[0])]) / 2;
+ } else {
+ luma = src[(x + y * p->linesize[0])];
+ }
/* write blocks as linear data now so they are suitable for elbg */
dest[0] = luma;
}
static av_cold int a64multi_close_encoder(AVCodecContext *avctx)
{
A64Context *c = avctx->priv_data;
- av_frame_free(&avctx->coded_frame);
av_freep(&c->mc_meta_charset);
av_freep(&c->mc_best_cb);
av_freep(&c->mc_charset);
a64_palette[mc_colors[a]][2] * 0.11;
}
- if (!(c->mc_meta_charset = av_malloc_array(c->mc_lifetime, 32000 * sizeof(int))) ||
+ if (!(c->mc_meta_charset = av_mallocz_array(c->mc_lifetime, 32000 * sizeof(int))) ||
!(c->mc_best_cb = av_malloc(CHARSET_CHARS * 32 * sizeof(int))) ||
!(c->mc_charmap = av_mallocz_array(c->mc_lifetime, 1000 * sizeof(int))) ||
!(c->mc_colram = av_mallocz(CHARSET_CHARS * sizeof(uint8_t))) ||
AV_WB32(avctx->extradata, c->mc_lifetime);
AV_WB32(avctx->extradata + 16, INTERLACED);
- avctx->coded_frame = av_frame_alloc();
- if (!avctx->coded_frame) {
- a64multi_close_encoder(avctx);
- return AVERROR(ENOMEM);
- }
-
- avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
- avctx->coded_frame->key_frame = 1;
if (!avctx->codec_tag)
avctx->codec_tag = AV_RL32("a64m");
}
static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
- const AVFrame *pict, int *got_packet)
+ const AVFrame *p, int *got_packet)
{
A64Context *c = avctx->priv_data;
- AVFrame *const p = avctx->coded_frame;
int frame;
int x, y;
}
/* no data, means end encoding asap */
- if (!pict) {
+ if (!p) {
/* all done, end encoding */
if (!c->mc_lifetime) return 0;
/* no more frames in queue, prepare to flush remaining frames */
} else {
/* fill up mc_meta_charset with data until lifetime exceeds */
if (c->mc_frame_counter < c->mc_lifetime) {
- *p = *pict;
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
to_meta_with_crop(avctx, p, meta + 32000 * c->mc_frame_counter);
c->mc_frame_counter++;
if (c->next_pts == AV_NOPTS_VALUE)
- c->next_pts = pict->pts;
+ c->next_pts = p->pts;
/* lifetime is not reached so wait for next frame first */
return 0;
}
req_size = 0;
/* any frames to encode? */
if (c->mc_lifetime) {
- req_size = charset_size + c->mc_lifetime*(screen_size + colram_size);
- if ((ret = ff_alloc_packet2(avctx, pkt, req_size)) < 0)
+ int alloc_size = charset_size + c->mc_lifetime*(screen_size + colram_size);
+ if ((ret = ff_alloc_packet2(avctx, pkt, alloc_size)) < 0)
return ret;
buf = pkt->data;
/* advance pointers */
buf += charset_size;
+ req_size += charset_size;
}
/* write x frames to buf */
pkt->pts = pkt->dts = c->next_pts;
c->next_pts = AV_NOPTS_VALUE;
+ av_assert0(pkt->size >= req_size);
pkt->size = req_size;
pkt->flags |= AV_PKT_FLAG_KEY;
*got_packet = !!req_size;