diff options
author | Stefan Kost <ensonic@users.sf.net> | 2009-09-28 16:29:45 +0300 |
---|---|---|
committer | Stefan Kost <ensonic@users.sf.net> | 2009-09-28 17:25:35 +0300 |
commit | 69c24fb991d5556e83e68d7a236e6526ea3dade5 (patch) | |
tree | d30df455ab9e7934a6ae5eb45c62feefbc3cb664 | |
parent | 0fac7b5347d1cd1f727b697d5be4782de1f56152 (diff) |
jpeg: handle more libjpeg return values, add some more branch hints
Also remove unused size variable in _chain().
-rw-r--r-- | ext/jpeg/gstjpegdec.c | 84 |
1 files changed, 50 insertions, 34 deletions
diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c index f9cc68e74..0f12be765 100644 --- a/ext/jpeg/gstjpegdec.c +++ b/ext/jpeg/gstjpegdec.c | |||
@@ -518,6 +518,8 @@ add_huff_table (j_decompress_ptr dinfo, | |||
518 | if (*htblptr == NULL) | 518 | if (*htblptr == NULL) |
519 | *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo); | 519 | *htblptr = jpeg_alloc_huff_table ((j_common_ptr) dinfo); |
520 | 520 | ||
521 | g_assert (*htblptr); | ||
522 | |||
521 | /* Copy the number-of-symbols-of-each-code-length counts */ | 523 | /* Copy the number-of-symbols-of-each-code-length counts */ |
522 | memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits)); | 524 | memcpy ((*htblptr)->bits, bits, sizeof ((*htblptr)->bits)); |
523 | 525 | ||
@@ -687,37 +689,42 @@ gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3], | |||
687 | }; | 689 | }; |
688 | guchar **scanarray[3] = { y_rows, u_rows, v_rows }; | 690 | guchar **scanarray[3] = { y_rows, u_rows, v_rows }; |
689 | gint i, j, k; | 691 | gint i, j, k; |
692 | gint lines; | ||
690 | 693 | ||
691 | GST_DEBUG_OBJECT (dec, | 694 | GST_DEBUG_OBJECT (dec, |
692 | "unadvantageous width or r_h, taking slow route involving memcpy"); | 695 | "unadvantageous width or r_h, taking slow route involving memcpy"); |
693 | 696 | ||
694 | for (i = 0; i < height; i += r_v * DCTSIZE) { | 697 | for (i = 0; i < height; i += r_v * DCTSIZE) { |
695 | jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE); | 698 | lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE); |
696 | for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) { | 699 | if (G_LIKELY (lines)) { |
697 | memcpy (base[0], y_rows[j], I420_Y_ROWSTRIDE (width)); | 700 | for (j = 0, k = 0; j < (r_v * DCTSIZE); j += r_v, k++) { |
698 | if (base[0] < last[0]) | 701 | memcpy (base[0], y_rows[j], I420_Y_ROWSTRIDE (width)); |
699 | base[0] += I420_Y_ROWSTRIDE (width); | ||
700 | if (r_v == 2) { | ||
701 | memcpy (base[0], y_rows[j + 1], I420_Y_ROWSTRIDE (width)); | ||
702 | if (base[0] < last[0]) | 702 | if (base[0] < last[0]) |
703 | base[0] += I420_Y_ROWSTRIDE (width); | 703 | base[0] += I420_Y_ROWSTRIDE (width); |
704 | } | 704 | if (G_LIKELY (r_h == 2)) { |
705 | if (G_LIKELY (r_h == 2)) { | 705 | memcpy (base[0], y_rows[j + 1], I420_Y_ROWSTRIDE (width)); |
706 | memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width)); | 706 | if (base[0] < last[0]) |
707 | memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width)); | 707 | base[0] += I420_Y_ROWSTRIDE (width); |
708 | } else if (G_UNLIKELY (r_h == 1)) { | 708 | } |
709 | hresamplecpy1 (base[1], u_rows[k], I420_U_ROWSTRIDE (width)); | 709 | if (G_LIKELY (r_h == 2)) { |
710 | hresamplecpy1 (base[2], v_rows[k], I420_V_ROWSTRIDE (width)); | 710 | memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width)); |
711 | } else { | 711 | memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width)); |
712 | /* FIXME: implement (at least we avoid crashing by doing nothing) */ | 712 | } else if (G_UNLIKELY (r_h == 1)) { |
713 | } | 713 | hresamplecpy1 (base[1], u_rows[k], I420_U_ROWSTRIDE (width)); |
714 | hresamplecpy1 (base[2], v_rows[k], I420_V_ROWSTRIDE (width)); | ||
715 | } else { | ||
716 | /* FIXME: implement (at least we avoid crashing by doing nothing) */ | ||
717 | } | ||
714 | 718 | ||
715 | if (r_v == 2 || (k & 1) != 0) { | 719 | if (r_v == 2 || (k & 1) != 0) { |
716 | if (base[1] < last[1] && base[2] < last[2]) { | 720 | if (base[1] < last[1] && base[2] < last[2]) { |
717 | base[1] += I420_U_ROWSTRIDE (width); | 721 | base[1] += I420_U_ROWSTRIDE (width); |
718 | base[2] += I420_V_ROWSTRIDE (width); | 722 | base[2] += I420_V_ROWSTRIDE (width); |
723 | } | ||
719 | } | 724 | } |
720 | } | 725 | } |
726 | } else { | ||
727 | GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0"); | ||
721 | } | 728 | } |
722 | } | 729 | } |
723 | } | 730 | } |
@@ -731,6 +738,7 @@ gst_jpeg_dec_decode_direct (GstJpegDec * dec, guchar * base[3], | |||
731 | guchar *u[4 * DCTSIZE]; | 738 | guchar *u[4 * DCTSIZE]; |
732 | guchar *v[4 * DCTSIZE]; | 739 | guchar *v[4 * DCTSIZE]; |
733 | gint i, j, k; | 740 | gint i, j, k; |
741 | gint lines; | ||
734 | 742 | ||
735 | line[0] = y; | 743 | line[0] = y; |
736 | line[1] = u; | 744 | line[1] = u; |
@@ -757,7 +765,10 @@ gst_jpeg_dec_decode_direct (GstJpegDec * dec, guchar * base[3], | |||
757 | } | 765 | } |
758 | } | 766 | } |
759 | } | 767 | } |
760 | jpeg_read_raw_data (&dec->cinfo, line, r_v * DCTSIZE); | 768 | lines = jpeg_read_raw_data (&dec->cinfo, line, r_v * DCTSIZE); |
769 | if (G_UNLIKELY (!lines)) { | ||
770 | GST_INFO_OBJECT (dec, "jpeg_read_raw_data() returned 0"); | ||
771 | } | ||
761 | } | 772 | } |
762 | } | 773 | } |
763 | 774 | ||
@@ -840,14 +851,13 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) | |||
840 | GstFlowReturn ret = GST_FLOW_OK; | 851 | GstFlowReturn ret = GST_FLOW_OK; |
841 | GstJpegDec *dec; | 852 | GstJpegDec *dec; |
842 | GstBuffer *outbuf; | 853 | GstBuffer *outbuf; |
843 | gulong size; | ||
844 | guchar *data, *outdata; | 854 | guchar *data, *outdata; |
845 | guchar *base[3], *last[3]; | 855 | guchar *base[3], *last[3]; |
846 | guint img_len, outsize; | 856 | guint img_len, outsize; |
847 | gint width, height; | 857 | gint width, height; |
848 | gint r_h, r_v; | 858 | gint r_h, r_v; |
849 | gint i; | 859 | gint i; |
850 | guint code; | 860 | guint code, hdr_ok; |
851 | GstClockTime timestamp, duration; | 861 | GstClockTime timestamp, duration; |
852 | 862 | ||
853 | dec = GST_JPEG_DEC (GST_PAD_PARENT (pad)); | 863 | dec = GST_JPEG_DEC (GST_PAD_PARENT (pad)); |
@@ -909,11 +919,10 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) | |||
909 | goto skip_decoding; | 919 | goto skip_decoding; |
910 | 920 | ||
911 | data = (guchar *) GST_BUFFER_DATA (dec->tempbuf); | 921 | data = (guchar *) GST_BUFFER_DATA (dec->tempbuf); |
912 | size = img_len; | ||
913 | GST_LOG_OBJECT (dec, "image size = %u", img_len); | 922 | GST_LOG_OBJECT (dec, "image size = %u", img_len); |
914 | 923 | ||
915 | dec->jsrc.pub.next_input_byte = data; | 924 | dec->jsrc.pub.next_input_byte = data; |
916 | dec->jsrc.pub.bytes_in_buffer = size; | 925 | dec->jsrc.pub.bytes_in_buffer = img_len; |
917 | 926 | ||
918 | if (setjmp (dec->jerr.setjmp_buffer)) { | 927 | if (setjmp (dec->jerr.setjmp_buffer)) { |
919 | code = dec->jerr.pub.msg_code; | 928 | code = dec->jerr.pub.msg_code; |
@@ -929,7 +938,10 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) | |||
929 | data[2], data[3]); | 938 | data[2], data[3]); |
930 | 939 | ||
931 | /* read header */ | 940 | /* read header */ |
932 | jpeg_read_header (&dec->cinfo, TRUE); | 941 | hdr_ok = jpeg_read_header (&dec->cinfo, TRUE); |
942 | if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) { | ||
943 | GST_WARNING_OBJECT (dec, "reading the header failed, %d", hdr_ok); | ||
944 | } | ||
933 | 945 | ||
934 | r_h = dec->cinfo.cur_comp_info[0]->h_samp_factor; | 946 | r_h = dec->cinfo.cur_comp_info[0]->h_samp_factor; |
935 | r_v = dec->cinfo.cur_comp_info[0]->v_samp_factor; | 947 | r_v = dec->cinfo.cur_comp_info[0]->v_samp_factor; |
@@ -938,11 +950,13 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) | |||
938 | GST_LOG_OBJECT (dec, "num_components=%d, comps_in_scan=%d", | 950 | GST_LOG_OBJECT (dec, "num_components=%d, comps_in_scan=%d", |
939 | dec->cinfo.num_components, dec->cinfo.comps_in_scan); | 951 | dec->cinfo.num_components, dec->cinfo.comps_in_scan); |
940 | 952 | ||
953 | #ifndef GST_DISABLE_GST_DEBUG | ||
941 | for (i = 0; i < dec->cinfo.comps_in_scan; ++i) { | 954 | for (i = 0; i < dec->cinfo.comps_in_scan; ++i) { |
942 | GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d", i, | 955 | GST_LOG_OBJECT (dec, "[%d] h_samp_factor=%d, v_samp_factor=%d", i, |
943 | dec->cinfo.cur_comp_info[i]->h_samp_factor, | 956 | dec->cinfo.cur_comp_info[i]->h_samp_factor, |
944 | dec->cinfo.cur_comp_info[i]->v_samp_factor); | 957 | dec->cinfo.cur_comp_info[i]->v_samp_factor); |
945 | } | 958 | } |
959 | #endif | ||
946 | 960 | ||
947 | /* prepare for raw output */ | 961 | /* prepare for raw output */ |
948 | dec->cinfo.do_fancy_upsampling = FALSE; | 962 | dec->cinfo.do_fancy_upsampling = FALSE; |
@@ -953,18 +967,20 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) | |||
953 | 967 | ||
954 | GST_LOG_OBJECT (dec, "starting decompress"); | 968 | GST_LOG_OBJECT (dec, "starting decompress"); |
955 | guarantee_huff_tables (&dec->cinfo); | 969 | guarantee_huff_tables (&dec->cinfo); |
956 | jpeg_start_decompress (&dec->cinfo); | 970 | if (!jpeg_start_decompress (&dec->cinfo)) { |
971 | GST_WARNING_OBJECT (dec, "failed to start decompression cycle"); | ||
972 | } | ||
957 | 973 | ||
958 | width = dec->cinfo.output_width; | 974 | width = dec->cinfo.output_width; |
959 | height = dec->cinfo.output_height; | 975 | height = dec->cinfo.output_height; |
960 | 976 | ||
961 | if (width < MIN_WIDTH || width > MAX_WIDTH || | 977 | if (G_UNLIKELY (width < MIN_WIDTH || width > MAX_WIDTH || |
962 | height < MIN_HEIGHT || height > MAX_HEIGHT) | 978 | height < MIN_HEIGHT || height > MAX_HEIGHT)) |
963 | goto wrong_size; | 979 | goto wrong_size; |
964 | 980 | ||
965 | if (width != dec->caps_width || height != dec->caps_height || | 981 | if (G_UNLIKELY (width != dec->caps_width || height != dec->caps_height || |
966 | dec->framerate_numerator != dec->caps_framerate_numerator || | 982 | dec->framerate_numerator != dec->caps_framerate_numerator || |
967 | dec->framerate_denominator != dec->caps_framerate_denominator) { | 983 | dec->framerate_denominator != dec->caps_framerate_denominator)) { |
968 | GstCaps *caps; | 984 | GstCaps *caps; |
969 | 985 | ||
970 | /* framerate == 0/1 is a still frame */ | 986 | /* framerate == 0/1 is a still frame */ |
@@ -1007,7 +1023,7 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) | |||
1007 | 1023 | ||
1008 | ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, | 1024 | ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, |
1009 | dec->outsize, GST_PAD_CAPS (dec->srcpad), &outbuf); | 1025 | dec->outsize, GST_PAD_CAPS (dec->srcpad), &outbuf); |
1010 | if (ret != GST_FLOW_OK) | 1026 | if (G_UNLIKELY (ret != GST_FLOW_OK)) |
1011 | goto alloc_failed; | 1027 | goto alloc_failed; |
1012 | 1028 | ||
1013 | outdata = GST_BUFFER_DATA (outbuf); | 1029 | outdata = GST_BUFFER_DATA (outbuf); |