summaryrefslogtreecommitdiff
path: root/libavcodec/videotoolboxenc.c
diff options
context:
space:
mode:
authorRick Kern <kernrj@gmail.com>2016-03-25 01:56:04 +0800
committerwm4 <nfxjfg@googlemail.com>2016-04-02 19:16:20 +0200
commitc9ad357aeb6a78ff657e5c59dcb7db45332ecda7 (patch)
tree0b7a5d25889c45a11fa28b31c66aa021d9a9b5e0 /libavcodec/videotoolboxenc.c
parent78016694706776fbfe4be9533704be3180b31623 (diff)
lavc/videotoolboxenc: Workaround encoder error
CMVideoFormatDescriptionGetH264ParameterSetAtIndex() fails on some hardware/OS versions when retrieving the parameter set count alone. Signed-off-by: Rick Kern <kernrj@gmail.com> Signed-off-by: wm4 <nfxjfg@googlemail.com>
Diffstat (limited to 'libavcodec/videotoolboxenc.c')
-rw-r--r--libavcodec/videotoolboxenc.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index 07911469f0..3177074463 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -194,6 +194,7 @@ static int get_params_size(
{
size_t total_size = 0;
size_t ps_count;
+ int is_count_bad = 0;
size_t i;
int status;
status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
@@ -203,11 +204,12 @@ static int get_params_size(
&ps_count,
NULL);
if (status) {
- av_log(avctx, AV_LOG_ERROR, "Error getting parameter set count: %d\n", status);
- return AVERROR_EXTERNAL;
+ is_count_bad = 1;
+ ps_count = 0;
+ status = 0;
}
- for(i = 0; i < ps_count; i++){
+ for (i = 0; i < ps_count || is_count_bad; i++) {
const uint8_t *ps;
size_t ps_size;
status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
@@ -216,14 +218,24 @@ static int get_params_size(
&ps_size,
NULL,
NULL);
- if(status){
- av_log(avctx, AV_LOG_ERROR, "Error getting parameter set size for index %zd: %d\n", i, status);
- return AVERROR_EXTERNAL;
+ if (status) {
+ /*
+ * When ps_count is invalid, status != 0 ends the loop normally
+ * unless we didn't get any parameter sets.
+ */
+ if (i > 0 && is_count_bad) status = 0;
+
+ break;
}
total_size += ps_size + sizeof(start_code);
}
+ if (status) {
+ av_log(avctx, AV_LOG_ERROR, "Error getting parameter set sizes: %d\n", status);
+ return AVERROR_EXTERNAL;
+ }
+
*size = total_size;
return 0;
}
@@ -235,6 +247,7 @@ static int copy_param_sets(
size_t dst_size)
{
size_t ps_count;
+ int is_count_bad = 0;
int status;
size_t offset = 0;
size_t i;
@@ -246,11 +259,13 @@ static int copy_param_sets(
&ps_count,
NULL);
if (status) {
- av_log(avctx, AV_LOG_ERROR, "Error getting parameter set count for copying: %d\n", status);
- return AVERROR_EXTERNAL;
+ is_count_bad = 1;
+ ps_count = 0;
+ status = 0;
}
- for (i = 0; i < ps_count; i++) {
+
+ for (i = 0; i < ps_count || is_count_bad; i++) {
const uint8_t *ps;
size_t ps_size;
size_t next_offset;
@@ -262,8 +277,9 @@ static int copy_param_sets(
NULL,
NULL);
if (status) {
- av_log(avctx, AV_LOG_ERROR, "Error getting parameter set data for index %zd: %d\n", i, status);
- return AVERROR_EXTERNAL;
+ if (i > 0 && is_count_bad) status = 0;
+
+ break;
}
next_offset = offset + sizeof(start_code) + ps_size;
@@ -279,6 +295,11 @@ static int copy_param_sets(
offset = next_offset;
}
+ if (status) {
+ av_log(avctx, AV_LOG_ERROR, "Error getting parameter set data: %d\n", status);
+ return AVERROR_EXTERNAL;
+ }
+
return 0;
}