• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/mjpeg2jpeg_bsf.c

Go to the documentation of this file.
00001 /*
00002  * MJPEG/AVI1 to JPEG/JFIF bitstream format filter
00003  * Copyright (c) 2010 Adrian Daerr and Nicolas George
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 /*
00023  * Adapted from mjpeg2jpeg.c, with original copyright:
00024  * Paris 2010 Adrian Daerr, public domain
00025  */
00026 
00027 #include <string.h>
00028 #include "avcodec.h"
00029 #include "mjpeg.h"
00030 
00031 static const uint8_t jpeg_header[] = {
00032     0xff, 0xd8,                     // SOI
00033     0xff, 0xe0,                     // APP0
00034     0x00, 0x10,                     // APP0 header size (including
00035                                     // this field, but excluding preceding)
00036     0x4a, 0x46, 0x49, 0x46, 0x00,   // ID string 'JFIF\0'
00037     0x01, 0x01,                     // version
00038     0x00,                           // bits per type
00039     0x00, 0x00,                     // X density
00040     0x00, 0x00,                     // Y density
00041     0x00,                           // X thumbnail size
00042     0x00,                           // Y thumbnail size
00043 };
00044 
00045 static const int dht_segment_size = 420;
00046 static const uint8_t dht_segment_head[] = { 0xFF, 0xC4, 0x01, 0xA2, 0x00 };
00047 static const uint8_t dht_segment_frag[] = {
00048     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
00049     0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
00050     0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
00051 };
00052 
00053 static uint8_t *append(uint8_t *buf, const uint8_t *src, int size)
00054 {
00055     memcpy(buf, src, size);
00056     return buf + size;
00057 }
00058 
00059 static uint8_t *append_dht_segment(uint8_t *buf)
00060 {
00061     buf = append(buf, dht_segment_head, sizeof(dht_segment_head));
00062     buf = append(buf, ff_mjpeg_bits_dc_luminance + 1, 16);
00063     buf = append(buf, dht_segment_frag, sizeof(dht_segment_frag));
00064     buf = append(buf, ff_mjpeg_val_dc, 12);
00065     *(buf++) = 0x10;
00066     buf = append(buf, ff_mjpeg_bits_ac_luminance + 1, 16);
00067     buf = append(buf, ff_mjpeg_val_ac_luminance, 162);
00068     *(buf++) = 0x11;
00069     buf = append(buf, ff_mjpeg_bits_ac_chrominance + 1, 16);
00070     buf = append(buf, ff_mjpeg_val_ac_chrominance, 162);
00071     return buf;
00072 }
00073 
00074 static int mjpeg2jpeg_filter(AVBitStreamFilterContext *bsfc,
00075                              AVCodecContext *avctx, const char *args,
00076                              uint8_t **poutbuf, int *poutbuf_size,
00077                              const uint8_t *buf, int buf_size,
00078                              int keyframe)
00079 {
00080     int input_skip, output_size;
00081     uint8_t *output, *out;
00082 
00083     if (buf_size < 12) {
00084         av_log(avctx, AV_LOG_ERROR, "input is truncated\n");
00085         return AVERROR_INVALIDDATA;
00086     }
00087     if (memcmp("AVI1", buf + 6, 4)) {
00088         av_log(avctx, AV_LOG_ERROR, "input is not MJPEG/AVI1\n");
00089         return AVERROR_INVALIDDATA;
00090     }
00091     input_skip = (buf[4] << 8) + buf[5] + 4;
00092     if (buf_size < input_skip) {
00093         av_log(avctx, AV_LOG_ERROR, "input is truncated\n");
00094         return AVERROR_INVALIDDATA;
00095     }
00096     output_size = buf_size - input_skip +
00097                   sizeof(jpeg_header) + dht_segment_size;
00098     output = out = av_malloc(output_size);
00099     if (!output)
00100         return AVERROR(ENOMEM);
00101     out = append(out, jpeg_header, sizeof(jpeg_header));
00102     out = append_dht_segment(out);
00103     out = append(out, buf + input_skip, buf_size - input_skip);
00104     *poutbuf = output;
00105     *poutbuf_size = output_size;
00106     return 1;
00107 }
00108 
00109 AVBitStreamFilter ff_mjpeg2jpeg_bsf = {
00110     .name           = "mjpeg2jpeg",
00111     .filter         = mjpeg2jpeg_filter,
00112 };
Generated on Fri Feb 1 2013 14:34:38 for FFmpeg by doxygen 1.7.1