Fix issue 1) not recognizes some usb device, 2) reconnect when ffmpeg encoder error
[rtmpclient.git] / app / src / main / jni / libuvc / src / frame-mjpeg_original.c
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 *  Copyright (C) 2014 Robert Xiao
5 *  All rights reserved.
6 *
7 *  Redistribution and use in source and binary forms, with or without
8 *  modification, are permitted provided that the following conditions
9 *  are met:
10 *
11 *   * Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 *   * Redistributions in binary form must reproduce the above
14 *     copyright notice, this list of conditions and the following
15 *     disclaimer in the documentation and/or other materials provided
16 *     with the distribution.
17 *   * Neither the name of the author nor other contributors may be
18 *     used to endorse or promote products derived from this software
19 *     without specific prior written permission.
20 *
21 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 *  POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35 /**
36  * @defgroup frame Frame processing
37  */
38 #include "libuvc/libuvc.h"
39 #include "libuvc/libuvc_internal.h"
40 #include <jpeglib.h>
41 #include <setjmp.h>
42
43 extern uvc_error_t uvc_ensure_frame_size(uvc_frame_t *frame, size_t need_bytes);
44
45 struct error_mgr {
46   struct jpeg_error_mgr super;
47   jmp_buf jmp;
48 };
49
50 static void _error_exit(j_common_ptr dinfo) {
51   struct error_mgr *myerr = (struct error_mgr *)dinfo->err;
52   (*dinfo->err->output_message)(dinfo);
53   longjmp(myerr->jmp, 1);
54 }
55
56 /* ISO/IEC 10918-1:1993(E) K.3.3. Default Huffman tables used by MJPEG UVC devices
57    which don't specify a Huffman table in the JPEG stream. */
58 static const unsigned char dc_lumi_len[] = 
59   {0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0};
60 static const unsigned char dc_lumi_val[] = 
61   {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
62
63 static const unsigned char dc_chromi_len[] = 
64   {0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
65 static const unsigned char dc_chromi_val[] = 
66   {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
67
68 static const unsigned char ac_lumi_len[] = 
69   {0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d};
70 static const unsigned char ac_lumi_val[] = 
71   {0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
72    0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71,
73    0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1,
74    0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
75    0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
76    0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
77    0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
78    0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
79    0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
80    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
81    0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
82    0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
83    0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
84    0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
85    0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
86    0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
87    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
88    0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
89 static const unsigned char ac_chromi_len[] = 
90   {0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77};
91 static const unsigned char ac_chromi_val[] = 
92   {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31,
93    0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
94    0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1,
95    0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
96    0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
97    0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
98    0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
99    0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
100    0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
101    0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
102    0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,
103    0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
104    0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
105    0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
106    0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
107    0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
108    0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
109    0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa};
110
111 #define COPY_HUFF_TABLE(dinfo,tbl,name) do { \
112   if(dinfo->tbl == NULL) dinfo->tbl = jpeg_alloc_huff_table((j_common_ptr)dinfo); \
113   memcpy(dinfo->tbl->bits, name##_len, sizeof(name##_len)); \
114   memset(dinfo->tbl->huffval, 0, sizeof(dinfo->tbl->huffval)); \
115   memcpy(dinfo->tbl->huffval, name##_val, sizeof(name##_val)); \
116 } while(0)
117
118 static void insert_huff_tables(j_decompress_ptr dinfo) {
119   COPY_HUFF_TABLE(dinfo, dc_huff_tbl_ptrs[0], dc_lumi);
120   COPY_HUFF_TABLE(dinfo, dc_huff_tbl_ptrs[1], dc_chromi);
121   COPY_HUFF_TABLE(dinfo, ac_huff_tbl_ptrs[0], ac_lumi);
122   COPY_HUFF_TABLE(dinfo, ac_huff_tbl_ptrs[1], ac_chromi);
123 }
124
125 /** @brief Convert an MJPEG frame to RGB
126  * @ingroup frame
127  *
128  * @param in MJPEG frame
129  * @param out RGB frame
130  */
131 uvc_error_t uvc_mjpeg2rgb(uvc_frame_t *in, uvc_frame_t *out) {
132   struct jpeg_decompress_struct dinfo;
133   struct error_mgr jerr;
134   size_t lines_read;
135
136   if (in->frame_format != UVC_FRAME_FORMAT_MJPEG)
137     return UVC_ERROR_INVALID_PARAM;
138
139   if (uvc_ensure_frame_size(out, in->width * in->height * 3) < 0)
140     return UVC_ERROR_NO_MEM;
141
142   out->width = in->width;
143   out->height = in->height;
144   out->frame_format = UVC_FRAME_FORMAT_RGB;
145   out->step = in->width * 3;
146   out->sequence = in->sequence;
147   out->capture_time = in->capture_time;
148   out->source = in->source;
149
150   dinfo.err = jpeg_std_error(&jerr.super);
151   jerr.super.error_exit = _error_exit;
152
153   if (setjmp(jerr.jmp)) {
154     goto fail;
155   }
156
157   jpeg_create_decompress(&dinfo);
158   jpeg_mem_src(&dinfo, in->data, in->data_bytes);
159   jpeg_read_header(&dinfo, TRUE);
160
161   if (dinfo.dc_huff_tbl_ptrs[0] == NULL) {
162     /* This frame is missing the Huffman tables: fill in the standard ones */
163     insert_huff_tables(&dinfo);
164   }
165
166   dinfo.out_color_space = JCS_RGB;
167   dinfo.dct_method = JDCT_IFAST;
168
169   jpeg_start_decompress(&dinfo);
170
171   lines_read = 0;
172   while (dinfo.output_scanline < dinfo.output_height) {
173     unsigned char *buffer[1] = { out->data + lines_read * out->step };
174     int num_scanlines;
175
176     num_scanlines = jpeg_read_scanlines(&dinfo, buffer, 1);
177     lines_read += num_scanlines;
178   }
179
180   jpeg_finish_decompress(&dinfo);
181   jpeg_destroy_decompress(&dinfo);
182   return 0;
183
184 fail:
185   jpeg_destroy_decompress(&dinfo);
186   return UVC_ERROR_OTHER;
187 }